66 lines
1.8 KiB
Haskell
66 lines
1.8 KiB
Haskell
{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}
|
|
|
|
module Gui (runReader) where
|
|
|
|
import qualified GI.Gtk as Gtk
|
|
import qualified GI.Gio as Gio
|
|
import qualified GI.Gdk as Gdk
|
|
import qualified GI.WebKit as WebKit
|
|
|
|
import Data.IORef (newIORef, readIORef, writeIORef)
|
|
import Control.Monad.Reader (runReaderT)
|
|
import Text.HTML.TagSoup (renderTags)
|
|
|
|
import EpubParser (EpubEnv, resolveSpine, getChapter)
|
|
|
|
runReader :: EpubEnv -> IO ()
|
|
runReader env = do
|
|
app <- Gtk.applicationNew (Just "com.svitak.reader") []
|
|
|
|
_ <- Gtk.on app #activate $ do
|
|
window <- Gtk.applicationWindowNew app
|
|
Gtk.windowSetTitle window (Just "Svitak")
|
|
Gtk.windowSetDefaultSize window 800 600
|
|
|
|
-- Web View
|
|
webView <- WebKit.webViewNew
|
|
Gtk.windowSetChild window (Just webView)
|
|
|
|
-- Book Data
|
|
spine <- runReaderT resolveSpine env
|
|
currentChapterIndex <- newIORef 0
|
|
|
|
let loadChapter index = do
|
|
let maxIdx = length spine - 1
|
|
-- index to valid range
|
|
let safeIdx = max 0 (min index maxIdx)
|
|
|
|
-- Update state
|
|
writeIORef currentChapterIndex safeIdx
|
|
|
|
let filename = spine !! safeIdx
|
|
tags <- runReaderT (getChapter filename) env
|
|
|
|
WebKit.webViewLoadHtml webView (renderTags tags) (Just "file:///")
|
|
|
|
loadChapter 0
|
|
|
|
-- Keyboard Input
|
|
keyController <- Gtk.eventControllerKeyNew
|
|
Gtk.widgetAddController window keyController
|
|
|
|
_ <- Gtk.on keyController #keyPressed $ \keyval _ _ -> do
|
|
currentIndex <- readIORef currentChapterIndex
|
|
case keyval of
|
|
Gdk.KEY_Right -> do
|
|
loadChapter (currentIndex + 1)
|
|
return True
|
|
Gdk.KEY_Left -> do
|
|
loadChapter (currentIndex - 1)
|
|
return True
|
|
_ -> return False
|
|
|
|
#present window
|
|
|
|
_ <- Gio.applicationRun app Nothing
|
|
pure ()
|