svitak/app/Gui.hs

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 ()