metabrush/app/Main.hs

315 lines
10 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-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 )
-- 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
( ColourRecord(..), colours )
import MetaBrush.Asset.Logo
( drawLogo )
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-05 20:23:16 +00:00
Colours { .. } <- colours windowWidgetPath
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-05 21:30:36 +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
2020-08-04 06:15:06 +00:00
panelGrid <- GTK.gridNew
GTK.gridAttach uiGrid logo 0 0 1 2
GTK.gridAttach uiGrid titleBar 1 0 3 1
GTK.gridAttach uiGrid toolBar 0 2 2 2
2020-08-06 00:45:20 +00:00
GTK.gridAttach uiGrid mainPane 2 1 2 4
2020-08-05 21:30:36 +00:00
mainView <- GTK.boxNew GTK.OrientationVertical 0
GTK.panedPack1 mainPane mainView True False
GTK.panedPack2 mainPane panelGrid False False
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"
---------------------------------------------------------
-- 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-05 20:23:16 +00:00
$ Cairo.renderWithContext
( drawLogo logo_base logo_highlight logo_base )
---------------------------------------------------------
-- Title bar
widgetAddClass titleBar "titleBar"
( 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-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
---------------------------------------------------------
-- Tool bar
widgetAddClass toolBar "toolBar"
---------------------------------------------------------
-- 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" ]
phantomRadioButton <- GTK.radioButtonNew ( [] @GTK.RadioButton )
for_ [ 1 .. 12 ] \ i -> do
2020-08-06 03:06:18 +00:00
-- File tab elements.
pgButton <- GTK.radioButtonNewWithLabelFromWidget ( Just phantomRadioButton ) ( "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" ]
void $ GTK.onButtonClicked pgButton do
active <- GTK.toggleButtonGetActive pgButton
flags <- GTK.widgetGetStateFlags tab
if active
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-05 21:30:36 +00:00
widgetAddClass viewportGrid "viewport_bg"
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
viewport <- GTK.drawingAreaNew
GTK.setContainerChild viewportOverlay viewport
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
widgetAddClass panelGrid "panels"
---------------------------------------------------------
-- Info bar
widgetAddClass infoBar "infoBar"
---------------------------------------------------------
2020-08-04 06:15:06 +00:00
-- Actions
2020-08-05 20:23:16 +00:00
---------------------------------------------------------
-- GTK main loop
2020-08-04 06:15:06 +00:00
2020-08-05 20:23:16 +00:00
GTK.widgetAddEvents window [GDK.EventMaskKeyPressMask, GDK.EventMaskKeyReleaseMask]
_ <- GTK.onWidgetKeyPressEvent window handleKeyboardPressEvent
_ <- GTK.onWidgetKeyReleaseEvent window handleKeyboardReleaseEvent
_ <- GTK.onWidgetDestroy window GTK.mainQuit
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