metabrush/app/Main.hs

585 lines
20 KiB
Haskell
Raw Normal View History

2020-08-05 20:23:16 +00:00
{-# LANGUAGE BlockArguments #-}
2020-08-06 03:06:18 +00:00
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
2020-08-08 03:33:35 +00:00
{-# LANGUAGE NegativeLiterals #-}
2020-08-05 20:23:16 +00:00
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
2020-08-04 06:15:06 +00:00
module Main
( main )
where
2020-08-05 20:23:16 +00:00
-- base
2020-08-06 03:06:18 +00:00
import Control.Monad
( void )
2020-08-06 00:45:20 +00:00
import Data.Foldable
( for_ )
2020-08-05 20:23:16 +00:00
import Data.Int
( Int32 )
import System.Exit
( exitSuccess )
-- directory
import qualified System.Directory as Directory
( canonicalizePath )
2020-08-04 06:15:06 +00:00
-- gi-cairo-connector
import qualified GI.Cairo.Render.Connector as Cairo
( renderWithContext )
2020-08-08 03:33:35 +00:00
-- gi-cairo-render
import qualified GI.Cairo.Render as Cairo
2020-08-04 06:15:06 +00:00
-- gi-gdk
import qualified GI.Gdk as GDK
-- gi-gtk
import qualified GI.Gtk as GTK
2020-08-05 20:23:16 +00:00
-- text
import qualified Data.Text as Text
( pack )
2020-08-04 06:15:06 +00:00
-- MetaBrush
2020-08-05 20:23:16 +00:00
import MetaBrush.Asset.Colours
2020-08-08 03:33:35 +00:00
( getColours )
2020-08-07 19:39:24 +00:00
import MetaBrush.Asset.Cursor
( drawCursorIcon )
2020-08-08 03:33:35 +00:00
import MetaBrush.Asset.InfoBar
( drawMagnifier, drawTopLeftCornerRect )
2020-08-05 20:23:16 +00:00
import MetaBrush.Asset.Logo
( drawLogo )
2020-08-07 22:41:08 +00:00
import MetaBrush.Asset.Tools
( drawBrush, drawMeta, drawPath, drawPen )
2020-08-07 19:39:24 +00:00
import MetaBrush.Asset.WindowIcons
( drawMinimise, drawRestoreDown, drawMaximise, drawClose )
2020-08-05 20:23:16 +00:00
import MetaBrush.Event
( handleKeyboardPressEvent, handleKeyboardReleaseEvent )
import MetaBrush.Render.Util
( widgetAddClass, widgetAddClasses )
import MetaBrush.UI.Menu
( newMenuBar )
import qualified Paths_MetaBrush as Cabal
2020-08-04 06:15:06 +00:00
( getDataFileName )
--------------------------------------------------------------------------------
main :: IO ()
main = do
---------------------------------------------------------
-- Initialise GTK
2020-08-06 03:06:18 +00:00
void $ GTK.init Nothing
2020-08-04 06:15:06 +00:00
Just screen <- GDK.screenGetDefault
2020-08-05 20:23:16 +00:00
themePath <- Text.pack <$> ( Directory.canonicalizePath =<< Cabal.getDataFileName "theme.css" )
2020-08-04 06:15:06 +00:00
cssProvider <- GTK.cssProviderNew
GTK.cssProviderLoadFromPath cssProvider themePath
GTK.styleContextAddProviderForScreen screen cssProvider 1000
window <- GTK.windowNew GTK.WindowTypeToplevel
windowWidgetPath <- GTK.widgetGetPath window
widgetAddClass window "window"
GTK.setWindowResizable window True
2020-08-05 20:23:16 +00:00
GTK.setWindowDecorated window True
2020-08-04 06:15:06 +00:00
GTK.setWindowTitle window "MetaBrush"
GTK.windowSetDefaultSize window 800 600
let
baseMinWidth, baseMinHeight :: Int32
2020-08-05 20:23:16 +00:00
baseMinWidth = 480
2020-08-04 06:15:06 +00:00
baseMinHeight = 240
windowGeometry <- GDK.newZeroGeometry
GDK.setGeometryMinWidth windowGeometry baseMinWidth
GDK.setGeometryMinHeight windowGeometry baseMinHeight
GTK.windowSetGeometryHints window ( Nothing @GTK.Widget )
( Just windowGeometry )
[ GDK.WindowHintsMinSize ]
2020-08-07 19:39:24 +00:00
iconPath <- Directory.canonicalizePath =<< Cabal.getDataFileName "icon.png"
GTK.windowSetIconFromFile window iconPath
2020-08-07 22:41:08 +00:00
colours <- getColours windowWidgetPath
2020-08-05 20:23:16 +00:00
2020-08-04 06:15:06 +00:00
---------------------------------------------------------
-- Create base UI elements
baseOverlay <- GTK.overlayNew
2020-08-05 20:23:16 +00:00
GTK.setContainerChild window baseOverlay
2020-08-04 06:15:06 +00:00
uiGrid <- GTK.gridNew
2020-08-05 20:23:16 +00:00
GTK.setContainerChild baseOverlay uiGrid
2020-08-04 06:15:06 +00:00
2020-08-08 13:53:06 +00:00
logo <- GTK.boxNew GTK.OrientationVertical 0
titleBar <- GTK.boxNew GTK.OrientationHorizontal 0
toolBar <- GTK.boxNew GTK.OrientationVertical 0
mainPane <- GTK.panedNew GTK.OrientationHorizontal
panelBox <- GTK.boxNew GTK.OrientationVertical 0
2020-08-04 06:15:06 +00:00
GTK.gridAttach uiGrid logo 0 0 1 2
2020-08-07 19:39:24 +00:00
GTK.gridAttach uiGrid titleBar 1 0 2 1
GTK.gridAttach uiGrid toolBar 0 2 2 1
GTK.gridAttach uiGrid mainPane 2 2 1 1
2020-08-05 21:30:36 +00:00
mainView <- GTK.boxNew GTK.OrientationVertical 0
2020-08-08 13:53:06 +00:00
GTK.panedPack1 mainPane mainView True False
GTK.panedPack2 mainPane panelBox False False
2020-08-05 21:30:36 +00:00
2020-08-06 00:45:20 +00:00
fileBar <- GTK.scrolledWindowNew ( Nothing @GTK.Adjustment ) ( Nothing @GTK.Adjustment )
viewportGrid <- GTK.gridNew
infoBar <- GTK.boxNew GTK.OrientationHorizontal 0
GTK.boxPackStart mainView fileBar False False 0
2020-08-05 21:30:36 +00:00
GTK.boxPackStart mainView viewportGrid True True 0
GTK.boxPackStart mainView infoBar False False 0
2020-08-04 06:15:06 +00:00
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- Background
widgetAddClass uiGrid "bg"
---------------------------------------------------------
2020-08-08 03:33:35 +00:00
-- Title bar
widgetAddClass titleBar "titleBar"
--------
2020-08-05 20:23:16 +00:00
-- Logo
widgetAddClass logo "logo"
logoArea <- GTK.drawingAreaNew
GTK.boxPackStart logo logoArea True True 0
2020-08-06 03:06:18 +00:00
void $ GTK.onWidgetDraw logoArea
2020-08-07 22:41:08 +00:00
$ Cairo.renderWithContext ( drawLogo colours )
2020-08-05 20:23:16 +00:00
2020-08-08 03:33:35 +00:00
------------
-- Menu bar
2020-08-05 20:23:16 +00:00
( menuBar, _menu ) <- newMenuBar
2020-08-06 00:45:20 +00:00
widgetAddClasses menuBar [ "menuBar", "text", "plain" ]
2020-08-05 20:23:16 +00:00
GTK.boxPackStart titleBar menuBar False False 0
2020-08-07 19:39:24 +00:00
-- TODO: this is a bit of a workaround to add hover highlight to top-level menu items.
-- Activating a menu somehow sets the "hover" setting,
-- so instead we use the "selected" setting for actual hover highlighting.
topLevelMenuItems <- GTK.containerGetChildren menuBar
for_ topLevelMenuItems \ topLevelMenuItem -> do
void $ GTK.onWidgetEnterNotifyEvent topLevelMenuItem \ _ -> do
flags <- GTK.widgetGetStateFlags topLevelMenuItem
GTK.widgetSetStateFlags topLevelMenuItem ( GTK.StateFlagsSelected : flags ) True
pure False
void $ GTK.onWidgetLeaveNotifyEvent topLevelMenuItem \ _ -> do
flags <- GTK.widgetGetStateFlags topLevelMenuItem
GTK.widgetSetStateFlags topLevelMenuItem ( filter ( /= GTK.StateFlagsSelected ) flags ) True
pure False
2020-08-05 21:30:36 +00:00
windowIcons <- GTK.boxNew GTK.OrientationHorizontal 0
widgetAddClasses windowIcons [ "windowIcon" ]
GTK.boxPackEnd titleBar windowIcons False False 0
2020-08-06 00:45:20 +00:00
title <- GTK.labelNew ( Just "● New Document (1) MetaBrush" )
2020-08-05 20:23:16 +00:00
widgetAddClasses title [ "text", "title", "plain" ]
2020-08-05 21:30:36 +00:00
GTK.boxSetCenterWidget titleBar ( Just title )
2020-08-05 20:23:16 +00:00
2020-08-07 19:39:24 +00:00
minimiseButton <- GTK.buttonNew
fullscreenButton <- GTK.buttonNew
closeButton <- GTK.buttonNew
GTK.boxPackStart windowIcons minimiseButton True True 0
GTK.boxPackStart windowIcons fullscreenButton True True 0
GTK.boxPackStart windowIcons closeButton True True 0
minimiseArea <- GTK.drawingAreaNew
fullscreenArea <- GTK.drawingAreaNew
closeArea <- GTK.drawingAreaNew
GTK.containerAdd minimiseButton minimiseArea
GTK.containerAdd fullscreenButton fullscreenArea
GTK.containerAdd closeButton closeArea
void $ GTK.onWidgetDraw minimiseArea
$ Cairo.renderWithContext
2020-08-07 22:41:08 +00:00
( drawMinimise colours )
2020-08-07 19:39:24 +00:00
void $ GTK.onWidgetDraw fullscreenArea \ cairoContext -> do
Just gdkWindow <- GTK.widgetGetWindow window
windowState <- GDK.windowGetState gdkWindow
if any ( \case { GDK.WindowStateFullscreen -> True; GDK.WindowStateMaximized -> True; _ -> False } ) windowState
2020-08-07 22:41:08 +00:00
then Cairo.renderWithContext ( drawRestoreDown colours ) cairoContext
else Cairo.renderWithContext ( drawMaximise colours ) cairoContext
2020-08-07 19:39:24 +00:00
void $ GTK.onWidgetDraw closeArea
$ Cairo.renderWithContext
2020-08-07 22:41:08 +00:00
( drawClose colours )
2020-08-07 19:39:24 +00:00
for_ [ minimiseButton, fullscreenButton, closeButton ] \ button -> do
widgetAddClass button "windowIcon"
widgetAddClass closeButton "closeWindowIcon"
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- Tool bar
widgetAddClass toolBar "toolBar"
2020-08-07 19:39:24 +00:00
GTK.widgetSetValign toolBar GTK.AlignStart
GTK.widgetSetVexpand toolBar True
2020-08-07 22:41:08 +00:00
selectionTool <- GTK.radioButtonNew ( [] @GTK.RadioButton )
penTool <- GTK.radioButtonNewFromWidget ( Just selectionTool )
pathTool <- GTK.radioButtonNew ( [] @GTK.RadioButton )
brushTool <- GTK.radioButtonNewFromWidget ( Just pathTool )
metaTool <- GTK.radioButtonNewFromWidget ( Just pathTool )
2020-08-07 19:39:24 +00:00
2020-08-07 22:41:08 +00:00
toolSep1 <- GTK.boxNew GTK.OrientationVertical 0
2020-08-07 19:39:24 +00:00
GTK.boxPackStart toolBar selectionTool True True 0
2020-08-07 22:41:08 +00:00
GTK.boxPackStart toolBar penTool True True 0
GTK.boxPackStart toolBar toolSep1 True True 0
GTK.boxPackStart toolBar pathTool True True 0
2020-08-07 19:39:24 +00:00
GTK.boxPackStart toolBar brushTool True True 0
GTK.boxPackStart toolBar metaTool True True 0
2020-08-07 22:41:08 +00:00
for_ [ selectionTool, penTool, pathTool, brushTool, metaTool ] \ tool -> do
2020-08-07 19:39:24 +00:00
GTK.toggleButtonSetMode tool False -- don't display radio indicator
widgetAddClass tool "toolItem"
2020-08-07 22:41:08 +00:00
widgetAddClass toolSep1 "toolBarSeparator"
GTK.widgetSetTooltipText selectionTool ( Just "Select" )
GTK.widgetSetTooltipText penTool ( Just "Draw" )
GTK.widgetSetTooltipText pathTool ( Just "Brush path" )
GTK.widgetSetTooltipText brushTool ( Just "Brushes" )
GTK.widgetSetTooltipText metaTool ( Just "Meta-parameters" )
2020-08-07 19:39:24 +00:00
selectionToolArea <- GTK.drawingAreaNew
2020-08-07 22:41:08 +00:00
penToolArea <- GTK.drawingAreaNew
pathToolArea <- GTK.drawingAreaNew
2020-08-07 19:39:24 +00:00
brushToolArea <- GTK.drawingAreaNew
metaToolArea <- GTK.drawingAreaNew
GTK.containerAdd selectionTool selectionToolArea
2020-08-07 22:41:08 +00:00
GTK.containerAdd penTool penToolArea
GTK.containerAdd pathTool pathToolArea
2020-08-07 19:39:24 +00:00
GTK.containerAdd brushTool brushToolArea
GTK.containerAdd metaTool metaToolArea
void $ GTK.onWidgetDraw selectionToolArea
$ Cairo.renderWithContext
2020-08-07 22:41:08 +00:00
( drawCursorIcon colours )
void $ GTK.onWidgetDraw penToolArea
$ Cairo.renderWithContext
( drawPen colours )
void $ GTK.onWidgetDraw pathToolArea
$ Cairo.renderWithContext
( drawPath colours )
2020-08-07 19:39:24 +00:00
void $ GTK.onWidgetDraw brushToolArea
$ Cairo.renderWithContext
2020-08-07 22:41:08 +00:00
( drawBrush colours )
2020-08-07 19:39:24 +00:00
void $ GTK.onWidgetDraw metaToolArea
$ Cairo.renderWithContext
2020-08-07 22:41:08 +00:00
( drawMeta colours )
2020-08-07 19:39:24 +00:00
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- File bar
widgetAddClass fileBar "fileBar"
2020-08-06 00:45:20 +00:00
fileTabs <- GTK.boxNew GTK.OrientationHorizontal 0
GTK.containerAdd fileBar fileTabs
widgetAddClasses fileTabs [ "fileBar", "plain", "text" ]
2020-08-07 19:39:24 +00:00
fileBarPhantomRadioButton <- GTK.radioButtonNew ( [] @GTK.RadioButton )
2020-08-06 00:45:20 +00:00
for_ [ 1 .. 12 ] \ i -> do
2020-08-06 03:06:18 +00:00
-- File tab elements.
2020-08-07 19:39:24 +00:00
pgButton <- GTK.radioButtonNewWithLabelFromWidget ( Just fileBarPhantomRadioButton ) ( "New Document (" <> Text.pack ( show i ) <> ")" )
2020-08-06 00:45:20 +00:00
GTK.toggleButtonSetMode pgButton False -- don't display radio indicator
2020-08-06 03:06:18 +00:00
closeFileButton <- GTK.buttonNewWithLabel "x"
-- Create box for file tab elements.
tab <- GTK.boxNew GTK.OrientationHorizontal 0
widgetAddClasses tab [ "fileBarTab" ]
GTK.boxPackStart fileTabs tab False False 0
GTK.boxPackStart tab pgButton True True 0
GTK.boxPackStart tab closeFileButton False False 0
widgetAddClasses pgButton [ "fileBarTabButton" ]
widgetAddClasses closeFileButton [ "fileBarCloseButton" ]
2020-08-07 19:39:24 +00:00
-- Make both file tab elements activate styling on the whole tab
-- (e.g. hovering over the close file button should highlight the whole tab).
2020-08-06 03:06:18 +00:00
void $ GTK.onButtonClicked pgButton do
2020-08-07 22:41:08 +00:00
isActive <- GTK.toggleButtonGetActive pgButton
2020-08-06 03:06:18 +00:00
flags <- GTK.widgetGetStateFlags tab
2020-08-07 22:41:08 +00:00
if isActive
2020-08-06 03:06:18 +00:00
then GTK.widgetSetStateFlags tab ( GTK.StateFlagsActive : flags ) True
else GTK.widgetSetStateFlags tab ( filter ( /= GTK.StateFlagsActive ) flags ) True
{-
void $ GTK.onButtonClicked closeFileButton do
closeFileDialog ...
-}
for_ @_ @_ @_ @() [ Exists @GTK.IsWidget pgButton, Exists @GTK.IsWidget closeFileButton ] \ ( Exists button ) -> do
void $ GTK.onWidgetEnterNotifyEvent button \ _ -> do
flags <- GTK.widgetGetStateFlags tab
GTK.widgetSetStateFlags tab ( GTK.StateFlagsPrelight : flags ) True
pure False
void $ GTK.onWidgetLeaveNotifyEvent button \ _ -> do
flags <- GTK.widgetGetStateFlags tab
GTK.widgetSetStateFlags tab ( filter ( /= GTK.StateFlagsPrelight ) flags ) True
pure False
2020-08-06 00:45:20 +00:00
GTK.scrolledWindowSetPolicy fileBar GTK.PolicyTypeAutomatic GTK.PolicyTypeNever
GTK.scrolledWindowSetOverlayScrolling fileBar True
2020-08-06 03:06:18 +00:00
---------------------------------------------------------
-- Main viewport
2020-08-07 22:41:08 +00:00
widgetAddClass viewportGrid "viewport"
2020-08-05 20:23:16 +00:00
2020-08-06 03:06:18 +00:00
rvRulerCorner <- GTK.revealerNew
rvLeftRuler <- GTK.revealerNew
rvTopRuler <- GTK.revealerNew
viewportOverlay <- GTK.overlayNew
2020-08-05 20:23:16 +00:00
2020-08-06 03:06:18 +00:00
GTK.gridAttach viewportGrid rvRulerCorner 0 0 1 1
GTK.gridAttach viewportGrid rvLeftRuler 0 1 1 1
GTK.gridAttach viewportGrid rvTopRuler 1 0 1 1
GTK.gridAttach viewportGrid viewportOverlay 1 1 1 1
2020-08-05 20:23:16 +00:00
rulerCorner <- GTK.boxNew GTK.OrientationVertical 0
leftRuler <- GTK.boxNew GTK.OrientationVertical 0
topRuler <- GTK.boxNew GTK.OrientationHorizontal 0
GTK.containerAdd rvRulerCorner rulerCorner
GTK.containerAdd rvLeftRuler leftRuler
GTK.containerAdd rvTopRuler topRuler
widgetAddClass rulerCorner "ruler"
widgetAddClass leftRuler "ruler"
widgetAddClass topRuler "ruler"
GTK.revealerSetRevealChild rvRulerCorner True
GTK.revealerSetRevealChild rvLeftRuler True
GTK.revealerSetRevealChild rvTopRuler True
GTK.revealerSetTransitionType rvRulerCorner GTK.RevealerTransitionTypeSlideLeft
GTK.revealerSetTransitionType rvLeftRuler GTK.RevealerTransitionTypeSlideLeft
GTK.revealerSetTransitionType rvTopRuler GTK.RevealerTransitionTypeSlideUp
rulerCornerArea <- GTK.drawingAreaNew
GTK.boxPackStart rulerCorner rulerCornerArea True True 0
leftRulerArea <- GTK.drawingAreaNew
GTK.boxPackStart leftRuler leftRulerArea True True 0
topRulerArea <- GTK.drawingAreaNew
GTK.boxPackStart topRuler topRulerArea True True 0
2020-08-06 03:06:18 +00:00
GTK.widgetSetHexpand rulerCorner False
GTK.widgetSetVexpand rulerCorner False
GTK.widgetSetHexpand leftRuler False
GTK.widgetSetVexpand leftRuler True
GTK.widgetSetHexpand topRuler True
GTK.widgetSetVexpand topRuler False
GTK.widgetSetHexpand viewportOverlay True
GTK.widgetSetVexpand viewportOverlay True
2020-08-07 22:41:08 +00:00
viewportArea <- GTK.drawingAreaNew
GTK.setContainerChild viewportOverlay viewportArea
2020-08-06 03:06:18 +00:00
viewportScrollbarGrid <- GTK.gridNew
GTK.overlayAddOverlay viewportOverlay viewportScrollbarGrid
viewportHScrollbar <- GTK.scrollbarNew GTK.OrientationHorizontal ( Nothing @GTK.Adjustment )
viewportVScrollbar <- GTK.scrollbarNew GTK.OrientationVertical ( Nothing @GTK.Adjustment )
GTK.widgetSetValign viewportHScrollbar GTK.AlignEnd
GTK.widgetSetHalign viewportVScrollbar GTK.AlignEnd
GTK.widgetSetVexpand viewportVScrollbar True
GTK.widgetSetHexpand viewportHScrollbar True
GTK.gridAttach viewportScrollbarGrid viewportHScrollbar 0 1 1 1
GTK.gridAttach viewportScrollbarGrid viewportVScrollbar 1 0 1 1
widgetAddClass viewportHScrollbar "viewportScrollbar"
widgetAddClass viewportVScrollbar "viewportScrollbar"
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- Panels
2020-08-08 13:53:06 +00:00
widgetAddClass panelBox "panels"
pane1 <- GTK.panedNew GTK.OrientationVertical
GTK.boxPackStart panelBox pane1 True True 0
panels1 <- GTK.notebookNew
panels2 <- GTK.notebookNew
GTK.notebookSetGroupName panels1 ( Just "Panel" )
GTK.notebookSetGroupName panels2 ( Just "Panel" )
GTK.panedPack1 pane1 panels1 True True
GTK.panedPack2 pane1 panels2 True True
strokesPanel <- GTK.boxNew GTK.OrientationVertical 0
brushesPanel <- GTK.boxNew GTK.OrientationVertical 0
transformPanel <- GTK.boxNew GTK.OrientationVertical 0
strokesTab <- GTK.labelNew ( Just "Strokes" )
brushesTab <- GTK.labelNew ( Just "Brushes" )
transformTab <- GTK.labelNew ( Just "Transform" )
for_ [ strokesTab, brushesTab, transformTab ] \ tab -> do
widgetAddClasses tab [ "plain", "text", "panelTab" ]
for_ [ strokesPanel, brushesPanel, transformPanel ] \ panel -> do
widgetAddClass panel "panel"
void $ GTK.notebookAppendPage panels1 strokesPanel ( Just strokesTab )
void $ GTK.notebookAppendPage panels1 brushesPanel ( Just brushesTab )
void $ GTK.notebookAppendPage panels2 transformPanel ( Just transformTab )
GTK.notebookSetTabReorderable panels1 strokesPanel True
GTK.notebookSetTabDetachable panels1 strokesPanel True
GTK.notebookSetTabReorderable panels1 brushesPanel True
GTK.notebookSetTabDetachable panels1 brushesPanel True
GTK.notebookSetTabReorderable panels2 transformPanel True
GTK.notebookSetTabDetachable panels2 transformPanel True
strokesContent <- GTK.labelNew ( Just "Strokes tab content..." )
brushesContent <- GTK.labelNew ( Just "Brushes tab content..." )
transformContent <- GTK.labelNew ( Just "Transform tab content..." )
GTK.boxPackStart strokesPanel strokesContent True True 0
GTK.boxPackStart brushesPanel brushesContent True True 0
GTK.boxPackStart transformPanel transformContent True True 0
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- Info bar
2020-08-08 03:33:35 +00:00
widgetAddClasses infoBar [ "infoBar", "monospace", "contrast" ]
zoomBox <- GTK.boxNew GTK.OrientationHorizontal 0
cursorPosBox <- GTK.boxNew GTK.OrientationHorizontal 0
topLeftPosBox <- GTK.boxNew GTK.OrientationHorizontal 0
botRightPosBox <- GTK.boxNew GTK.OrientationHorizontal 0
for_ [ botRightPosBox, topLeftPosBox, cursorPosBox, zoomBox ] \ box -> do
GTK.boxPackEnd infoBar box False False 0
widgetAddClass box "infoBarBox"
-------------
-- Magnifier
magnifierArea <- GTK.drawingAreaNew
zoomText <- GTK.labelNew ( Just "300%" )
GTK.boxPackStart zoomBox magnifierArea True True 0
GTK.boxPackStart zoomBox zoomText True True 0
void $ GTK.onWidgetDraw magnifierArea \ctx ->
( `Cairo.renderWithContext` ctx ) $ do
Cairo.scale 0.9 0.9
Cairo.translate 14 10
drawMagnifier colours
-------------------
-- Cursor position
cursorPosArea <- GTK.drawingAreaNew
cursorPosText <- GTK.labelNew ( Just "x: 212.12 px\ny: 120.23 px" )
GTK.boxPackStart cursorPosBox cursorPosArea False False 0
GTK.boxPackStart cursorPosBox cursorPosText False False 0
void $ GTK.onWidgetDraw cursorPosArea \ctx ->
( `Cairo.renderWithContext` ctx ) $ do
Cairo.scale 0.75 0.75
Cairo.translate 10 7
drawCursorIcon colours
---------------------
-- Top left position
topLeftPosArea <- GTK.drawingAreaNew
topLeftPosText <- GTK.labelNew ( Just "x: 212.12 px\ny: 120.23 px" )
GTK.boxPackStart topLeftPosBox topLeftPosArea False False 0
GTK.boxPackStart topLeftPosBox topLeftPosText False False 0
void $ GTK.onWidgetDraw topLeftPosArea
$ Cairo.renderWithContext
( drawTopLeftCornerRect colours )
-------------------------
-- Bottom right position
botRightPosArea <- GTK.drawingAreaNew
botRightPosText <- GTK.labelNew ( Just "x: 212.12 px\ny: 120.23 px" )
GTK.boxPackStart botRightPosBox botRightPosArea False False 0
GTK.boxPackStart botRightPosBox botRightPosText False False 0
void $ GTK.onWidgetDraw botRightPosArea \ctx ->
( `Cairo.renderWithContext` ctx ) $ do
Cairo.scale -1 -1
Cairo.translate -40 -40
drawTopLeftCornerRect colours
-------------------------
for_ [ magnifierArea, cursorPosArea, topLeftPosArea, botRightPosArea ] \ area -> do
widgetAddClass area "infoBarIcon"
GTK.widgetSetSizeRequest area 40 40 -- not sure why this is needed...?
for_ [ zoomText, cursorPosText, topLeftPosText, botRightPosText ] \ info -> do
widgetAddClass info "infoBarInfo"
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
2020-08-04 06:15:06 +00:00
-- Actions
2020-08-07 19:39:24 +00:00
GTK.widgetAddEvents window [GDK.EventMaskKeyPressMask, GDK.EventMaskKeyReleaseMask]
_ <- GTK.onButtonClicked closeButton GTK.mainQuit
_ <- GTK.onButtonClicked minimiseButton ( GTK.windowIconify window )
_ <- GTK.onButtonClicked fullscreenButton do
Just gdkWindow <- GTK.widgetGetWindow window
windowState <- GDK.windowGetState gdkWindow
if GDK.WindowStateFullscreen `elem` windowState
then GTK.windowUnfullscreen window
else
if GDK.WindowStateMaximized `elem` windowState
then GTK.windowUnmaximize window
else GTK.windowMaximize window
_ <- GTK.onWidgetKeyPressEvent window handleKeyboardPressEvent
_ <- GTK.onWidgetKeyReleaseEvent window handleKeyboardReleaseEvent
_ <- GTK.onWidgetDestroy window GTK.mainQuit
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- GTK main loop
2020-08-04 06:15:06 +00:00
GTK.widgetShowAll window
GTK.main
2020-08-05 20:23:16 +00:00
exitSuccess
2020-08-06 03:06:18 +00:00
data Exists c where
Exists :: c a => a -> Exists c