window icons, tool bar

This commit is contained in:
sheaf 2020-08-07 21:39:24 +02:00
parent 9bc8e096c9
commit cc96802f8e
7 changed files with 390 additions and 54 deletions

View file

@ -10,6 +10,7 @@ data-dir:
assets
data-files:
theme.css
icon.png
description:
MetaBrush is a GUI for brush calligraphy based on Bézier curves.
@ -84,6 +85,7 @@ executable MetaBrush
other-modules:
MetaBrush.Asset.Brush
, MetaBrush.Asset.Colours
, MetaBrush.Asset.Cursor
, MetaBrush.Asset.Logo
, MetaBrush.Asset.Magnifier
, MetaBrush.Asset.Meta

View file

@ -39,10 +39,18 @@ import qualified Data.Text as Text
( pack )
-- MetaBrush
import MetaBrush.Asset.Brush
( drawBrush )
import MetaBrush.Asset.Colours
( ColourRecord(..), colours )
import MetaBrush.Asset.Cursor
( drawCursorIcon )
import MetaBrush.Asset.Logo
( drawLogo )
import MetaBrush.Asset.Meta
( drawMeta )
import MetaBrush.Asset.WindowIcons
( drawMinimise, drawRestoreDown, drawMaximise, drawClose )
import MetaBrush.Event
( handleKeyboardPressEvent, handleKeyboardReleaseEvent )
import MetaBrush.Render.Util
@ -88,6 +96,9 @@ main = do
( Just windowGeometry )
[ GDK.WindowHintsMinSize ]
iconPath <- Directory.canonicalizePath =<< Cabal.getDataFileName "icon.png"
GTK.windowSetIconFromFile window iconPath
Colours { .. } <- colours windowWidgetPath
---------------------------------------------------------
@ -106,9 +117,9 @@ main = do
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
GTK.gridAttach uiGrid mainPane 2 1 2 4
GTK.gridAttach uiGrid titleBar 1 0 2 1
GTK.gridAttach uiGrid toolBar 0 2 2 1
GTK.gridAttach uiGrid mainPane 2 2 1 1
mainView <- GTK.boxNew GTK.OrientationVertical 0
@ -149,6 +160,20 @@ main = do
widgetAddClasses menuBar [ "menuBar", "text", "plain" ]
GTK.boxPackStart titleBar menuBar False False 0
-- 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
windowIcons <- GTK.boxNew GTK.OrientationHorizontal 0
widgetAddClasses windowIcons [ "windowIcon" ]
GTK.boxPackEnd titleBar windowIcons False False 0
@ -157,11 +182,91 @@ main = do
widgetAddClasses title [ "text", "title", "plain" ]
GTK.boxSetCenterWidget titleBar ( Just title )
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
( drawMinimise plain )
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
then Cairo.renderWithContext ( drawRestoreDown plain ) cairoContext
else Cairo.renderWithContext ( drawMaximise plain ) cairoContext
void $ GTK.onWidgetDraw closeArea
$ Cairo.renderWithContext
( drawClose plain )
for_ [ minimiseButton, fullscreenButton, closeButton ] \ button -> do
widgetAddClass button "windowIcon"
widgetAddClass closeButton "closeWindowIcon"
---------------------------------------------------------
-- Tool bar
widgetAddClass toolBar "toolBar"
GTK.widgetSetValign toolBar GTK.AlignStart
GTK.widgetSetVexpand toolBar True
toolBarPhantomRadioButton <- GTK.radioButtonNew ( [] @GTK.RadioButton )
selectionTool <- GTK.radioButtonNewFromWidget ( Just toolBarPhantomRadioButton )
brushTool <- GTK.radioButtonNewFromWidget ( Just toolBarPhantomRadioButton )
metaTool <- GTK.radioButtonNewFromWidget ( Just toolBarPhantomRadioButton )
GTK.boxPackStart toolBar selectionTool True True 0
GTK.boxPackStart toolBar brushTool True True 0
GTK.boxPackStart toolBar metaTool True True 0
for_ [ selectionTool, brushTool, metaTool ] \ tool -> do
GTK.toggleButtonSetMode tool False -- don't display radio indicator
widgetAddClass tool "toolItem"
selectionToolArea <- GTK.drawingAreaNew
brushToolArea <- GTK.drawingAreaNew
metaToolArea <- GTK.drawingAreaNew
{-
for_ [ selectionToolArea, brushToolArea, metaToolArea ] \ toolArea -> do
GTK.widgetSetValign toolArea GTK.AlignCenter
GTK.widgetSetHalign toolArea GTK.AlignCenter
-}
GTK.containerAdd selectionTool selectionToolArea
GTK.containerAdd brushTool brushToolArea
GTK.containerAdd metaTool metaToolArea
void $ GTK.onWidgetDraw selectionToolArea
$ Cairo.renderWithContext
( drawCursorIcon logo_base )
void $ GTK.onWidgetDraw brushToolArea
$ Cairo.renderWithContext
( drawBrush logo_base logo_highlight logo_base )
void $ GTK.onWidgetDraw metaToolArea
$ Cairo.renderWithContext
( drawMeta logo_highlight )
---------------------------------------------------------
-- File bar
@ -171,11 +276,11 @@ main = do
GTK.containerAdd fileBar fileTabs
widgetAddClasses fileTabs [ "fileBar", "plain", "text" ]
phantomRadioButton <- GTK.radioButtonNew ( [] @GTK.RadioButton )
fileBarPhantomRadioButton <- GTK.radioButtonNew ( [] @GTK.RadioButton )
for_ [ 1 .. 12 ] \ i -> do
-- File tab elements.
pgButton <- GTK.radioButtonNewWithLabelFromWidget ( Just phantomRadioButton ) ( "New Document (" <> Text.pack ( show i ) <> ")" )
pgButton <- GTK.radioButtonNewWithLabelFromWidget ( Just fileBarPhantomRadioButton ) ( "New Document (" <> Text.pack ( show i ) <> ")" )
GTK.toggleButtonSetMode pgButton False -- don't display radio indicator
closeFileButton <- GTK.buttonNewWithLabel "x"
@ -189,6 +294,8 @@ main = do
widgetAddClasses pgButton [ "fileBarTabButton" ]
widgetAddClasses closeFileButton [ "fileBarCloseButton" ]
-- Make both file tab elements activate styling on the whole tab
-- (e.g. hovering over the close file button should highlight the whole tab).
void $ GTK.onButtonClicked pgButton do
active <- GTK.toggleButtonGetActive pgButton
flags <- GTK.widgetGetStateFlags tab
@ -297,14 +404,27 @@ main = do
---------------------------------------------------------
-- Actions
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
---------------------------------------------------------
-- GTK main loop
GTK.widgetAddEvents window [GDK.EventMaskKeyPressMask, GDK.EventMaskKeyReleaseMask]
_ <- GTK.onWidgetKeyPressEvent window handleKeyboardPressEvent
_ <- GTK.onWidgetKeyReleaseEvent window handleKeyboardReleaseEvent
_ <- GTK.onWidgetDestroy window GTK.mainQuit
GTK.widgetShowAll window
GTK.main

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -14,8 +14,6 @@
/* Viewport background colour */
.viewport_bg {
background-color: rgb(236, 223, 210);
min-width: 60px;
min-height: 40px;
-GtkWidget-window-dragging: false;
}
@ -47,6 +45,7 @@
/* Logo area */
.logo {
margin-left: 4px;
min-width: 28px;
}
/* Logo base colour */
@ -112,9 +111,11 @@
font-size: 12px;
}
/*
.titleBar > * :hover {
background-color: rgb(72,70,61);
}
*/
.title {
border-top: 2px solid rgb(41, 40, 40);
@ -132,12 +133,17 @@
border-top: 2px solid rgb(41, 40, 40);
}
.menuItem:hover {
/* Menu item hover effect (workaround) */
.menuItem:selected {
border-color: rgb(72,70,61);
}
/* Styling for active menu item */
.menuItem:active, .menuItem:checked, .menuItem:hover {
border-color: rgb(234,223,204);
background-color: rgb(72,70,61);
}
/* Menu drop shadow */
.menuItem > * > * {
box-shadow: 2px 4px 3px -1px rgba(28,25,25,0.5);
border: 1px solid rgb(28,25,25);
@ -153,6 +159,10 @@
border-left: 2px solid rgb(41, 40, 40);
}
.submenuItem:hover{
background-color: rgb(72,70,61);
}
.submenuItem:disabled {
color: rgb(149,149,149);
}
@ -166,14 +176,48 @@
border-color: rgb(234,223,204);
}
/*
.windowIcon {
min-width: 24px;
}
.windowIcon:hover {
background-color: rgb(34,131,186);
}
.windowIcon:active, .windowIcon:checked {
background-color: rgb(23,108,156);
}
.closeWindowIcon:hover {
background-color: rgb(181,43,43);
}
.closeWindowIcon:active, .closeWindowIcon:checked {
background-color: rgb(160,37,37);
}
*/
/* Tool bar */
.toolBar {
min-width: 60px;
min-width: 32px;
margin-top: 28px;
}
.toolItem {
border-left: 2px solid rgb(41, 40, 40);
min-height: 32px;
min-width: 38px;
padding-top: 12px;
padding-bottom: 8px;
padding-left: 6px;
}
.toolItem:hover {
border-color: rgb(72,70,61);
}
.toolItem:active, .toolItem:checked {
border-color: rgb(234,223,204);
background-color: rgb(72,70,61);
}
/* File bar */
@ -184,7 +228,7 @@
}
.fileBarTab {
border-top: 3px solid rgb(41, 40, 40);
border-top: 2px solid rgb(41, 40, 40);
}
.fileBarTab:hover {

View file

@ -5,6 +5,7 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="MetaBrush_ui_mockup.svg"
@ -55,15 +56,19 @@
showgrid="false"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="399.13966"
inkscape:cx="834.67434"
inkscape:zoom="0.70710678"
inkscape:cy="-120.95892"
inkscape:cx="667.79746"
inkscape:zoom="1"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
id="base">
<inkscape:grid
id="grid4274"
type="xygrid" />
</sodipodi:namedview>
<metadata
id="metadata6298">
<rdf:RDF>
@ -447,16 +452,16 @@
d="m 53.697983,130.46852 c -0.398481,-0.58922 -0.794322,-1.7911 -1.048322,-1.73818 -0.137583,-0.0423 -2.879333,4.01184 -3.122749,4.29759 -0.275167,-0.28575 -0.645584,0.0212 -0.677334,0.45508 0,0.22225 0.538837,0.84005 1.005417,0.16933 0.04401,-0.0633 2.128203,-2.97885 2.322592,-3.26489 0.169333,0.34925 0.869778,1.57275 0.912111,1.62567 0.413037,-0.20721 0.507142,-0.33141 0.729392,-0.59599 0.254032,-0.35144 0.287311,-0.3959 0.629738,-0.84526 0.15875,0.32808 0.651865,0.86911 1.100666,1.44991 0.169643,0.21954 0.893474,0.96206 1.105878,0.87896 0.113388,-0.0444 0.516106,-0.40729 0.587459,-0.79224 0.01599,-0.0863 0.05612,-0.41482 -0.01708,-0.48091 -0.05177,-0.0468 -0.483647,0.19656 -0.618249,0.14287 -0.232945,-0.34124 -0.51833,-0.93511 -0.765006,-1.34591 -0.391583,-0.70908 -0.69744,-1.58033 -1.012682,-1.38728 -0.218958,0.13409 -0.343747,0.30086 -0.391584,0.37042 -0.219248,0.31882 -0.322696,0.47584 -0.740261,1.06082 z" />
</g>
<path
inkscape:connector-curvature="0"
id="path1747"
d="m 191.61844,-203.31939 h 4.39072"
style="fill:none;stroke:#d4be98;stroke-width:0.40479055;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
sodipodi:nodetypes="ccccc"
id="path4307"
d="m 194.23426,-203.9466 v 0.99478 h 3.09843 v -0.99478 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d4be98;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.415235;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
<g
style="stroke-width:0.20610821;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(1.9821532,0,0,1.9459556,-90.197116,-240.32697)"
id="g1780">
<path
style="fill:none;stroke:#d4be98;stroke-width:0.20610821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;stroke:#d4be98;stroke-width:0.22902154;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 151.28645,17.610589 1.56634,1.56634"
id="path1753"
inkscape:connector-curvature="0" />
@ -464,25 +469,18 @@
inkscape:connector-curvature="0"
id="path1755"
d="m 151.28645,19.176929 1.56634,-1.56634"
style="fill:none;stroke:#d4be98;stroke-width:0.20610821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
style="fill:none;stroke:#d4be98;stroke-width:0.22902154;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
style="stroke-width:0.20610821;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(1.9821532,0,0,1.9459556,-86.71522,-239.22024)"
style="stroke-width:0.206108;stroke-miterlimit:4;stroke-dasharray:none"
transform="matrix(1.9821532,0,0,1.9459556,-86.400539,-233.92857)"
id="g1776">
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#d4be98;stroke-width:0.20610821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
id="rect1757"
width="1.5227864"
height="1.2336483"
x="145.30342"
y="17.521439" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="rect1757-1"
d="m 145.772,17.529818 v -0.539244 h 1.52279 v 1.233648 h -0.44295"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#d4be98;stroke-width:0.20610821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers" />
sodipodi:nodetypes="ccccccccccccccccccccc"
transform="matrix(0.13348279,0,0,0.13596576,-38.35818,15.738262)"
d="m 1378.666,7.5722656 v 5.0508574 h -3.5117 v 9.876341 h 10.8697 v -4.345243 h 3.5117 V 7.5722656 Z m 1.5352,3.0839624 h 7.7838 v 5.974556 h -1.961 v -4.007661 h -5.8228 z m -3.5117,5.05281 h 7.7837 v 5.280661 h -7.7837 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d4be98;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.52992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
id="path4298" />
</g>
<text
id="text1791"
@ -617,7 +615,7 @@
height="3.1260154"
width="32.521175"
id="rect1943-2"
style="opacity:1;vector-effect:none;fill:#282727;fill-opacity:0.57647059;stroke:none;stroke-width:0.45031363;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
style="opacity:1;vector-effect:none;fill:#332727;fill-opacity:0.57647061;stroke:none;stroke-width:0.45031363;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
<rect
y="-193.70197"
x="-138.94586"
@ -5559,5 +5557,55 @@
x="-36.769897"
id="tspan1846-4-5"
sodipodi:role="line">. . .</tspan></text>
<image
id="image4290"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAAiCAIAAAChsAJ0AAAEGGlUWHRYTUw6Y29tLmFkb2JlLnht
cAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQi
Pz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUg
NS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIy
LXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1s
bnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJo
dHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFk
b2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hh
cC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9z
VHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249Ijg1IgogICBleGlm
OlBpeGVsWURpbWVuc2lvbj0iMzQiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iODUiCiAgIHRpZmY6SW1h
Z2VMZW5ndGg9IjM0IgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0
aW9uPSI3Mi4wIgogICB0aWZmOllSZXNvbHV0aW9uPSI3Mi4wIgogICB4bXA6TW9kaWZ5RGF0ZT0i
MjAyMC0wOC0wNlQyMTo1OTo1MyswMjowMCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wOC0w
NlQyMTo1OTo1MyswMjowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAg
PHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2Fy
ZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjcuMSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMC0wOC0w
NlQyMTo1OTo1MyswMjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAg
PC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5k
PSJyIj8+jrhnkQAAAUtpQ0NQQWRvYmUgUkdCICgxOTk4KQAAKJFjYGAKyUnOLWYSYGDIzSspCnJ3
UoiIjFJgv8DAwcDNIMxgzGCdmFxc4BvsFsIABHn5eakMGODbNQZGEH1ZF2QWpjxewJVcUFQCpP8A
sVFKanEyAwOjAZA9obykACjOeADIFknKBrOvgNhFIUHOQPYLIJsvHcL+AWIngdlMHCB2EdATQLYE
SH06hK0DNgfCdgCxS1IrQPYyOOcXVBZlpmeUKBgZGBgoOKbkJ6UqBFcWl6TmFit45iXnFxXkFyWW
pKYA1ULcBwaCEIWgENMwtLS00IR5SJDBkSGFIZ8hiSGVQYEhiMGdwQlIazAYMlgCoQUDXCEVACiu
IKzPgeA4YBQ7gxBDgOTSojIok5HJmDAfYcYcYBj6L2VgYPmDEDPpZWBYAAxP/qkIMTVDBgYBfQaG
fXMAVfRVYDjhut8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAFrSURBVGiB7ZixqoMwFIbPvXQVMhV8
gIKzUyd9A9e+wHmBPENXwa1Tpk7N1KmPUHAS8ghZC0IhQsGpgyClpbmXxmsunHxTEvA3X2KOEADa
fCVJ4nsOPvn2PQHPBH/aBH/aBH/aBH/a+PHPsqx+wSUQEeu6RsQfB59YuLz1Y7quu91u1+t1HFku
ly6BQogoihDRGCOlBIDNZoOIUkohhOXBuf3TNAWA1WqllNrv9wCgtW7b9ng8OiZXVQUAnPOhyzmX
Ug6DFub23+12Y3u9XgPAdrs9nU6ThD8uwW/kYX7/rusOh8PYzfN82nxjzFPDztz+xpjHAxnHcVEU
aZoyxtzDxzMPAI+1wMJbf0tBHr7bqdBaK6WapnHMQUREFEIM62uM4ZxHUfS/6t8rSin38/8kDwBD
Y/j5WZbg7f3PH+3/+Xy+XC5jlzFWluVU9e8Dwv0XbYI/bYI/bYI/bYI/bYI/baj7L/q+9z0Hn9wB
5xWjTCer4ggAAAAASUVORK5CYII=
"
preserveAspectRatio="none"
height="11.994444"
width="29.986111"
x="127.25611"
y="-229.74541" />
<g
id="g4311"
transform="matrix(1.9821532,0,0,1.9459556,-102.87085,-239.22024)"
style="stroke-width:0.206108;stroke-miterlimit:4;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cccccccccc"
id="path4318"
d="m 201.42249,-206.03505 v 3.4668 h 3.5 v -3.4668 z m 0.40625,0.97374 h 2.6875 v 2.08876 h -2.6875 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d4be98;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40549;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 244 KiB

View file

@ -0,0 +1,47 @@
module MetaBrush.Asset.Cursor
( drawCursor, drawCursorIcon )
where
-- gi-cairo-render
import qualified GI.Cairo.Render as Cairo
-- gi-gdk
import qualified GI.Gdk as GDK
-- MetaBrush
import MetaBrush.Render.Util
( withRGBA )
--------------------------------------------------------------------------------
-- | "Selection" mouse cursor. 18 x 18.
drawCursor :: GDK.RGBA -> GDK.RGBA -> Cairo.Render Bool
drawCursor cursorColour outlineColour = do
Cairo.setLineWidth 1
withRGBA outlineColour Cairo.setSourceRGBA
Cairo.newPath
Cairo.moveTo 12.625 10.582031
Cairo.curveTo 5.699219 11.101563 4.097656 12.3125 0 17.976563
Cairo.lineTo 0.078125 0
Cairo.closePath
Cairo.strokePreserve
withRGBA cursorColour Cairo.setSourceRGBA
Cairo.fillPreserve
pure True
-- | "Selection" tool icon. 30 x 30.
drawCursorIcon :: GDK.RGBA -> Cairo.Render Bool
drawCursorIcon cursorColour = do
withRGBA cursorColour Cairo.setSourceRGBA
Cairo.newPath
Cairo.moveTo 24.023438 16.3125
Cairo.curveTo 15.636719 16.9375 13.699219 18.40625 8.742188 25.261719
Cairo.lineTo 8.835938 3.503906
Cairo.closePath
Cairo.fillPreserve
pure True

View file

@ -9,23 +9,98 @@ import qualified GI.Cairo.Render as Cairo
import qualified GI.Gdk as GDK
-- MetaBrush
--import MetaBrush.Render.Util
-- ( withRGBA )
import MetaBrush.Render.Util
( withRGBA )
--------------------------------------------------------------------------------
-- | Minimise window icon.
drawMinimise :: GDK.RGBA -> Cairo.Render ()
drawMinimise iconColour = pure ()
drawMinimise :: GDK.RGBA -> Cairo.Render Bool
drawMinimise iconColour = do
withRGBA iconColour Cairo.setSourceRGBA
Cairo.newPath
Cairo.moveTo 6.144531 12.914063
Cairo.lineTo 6.144531 16.675781
Cairo.lineTo 17.855469 16.675781
Cairo.lineTo 17.855469 12.914063
Cairo.closePath
Cairo.fillPreserve
pure True
-- | Restore down window icon.
drawRestoreDown :: GDK.RGBA -> Cairo.Render ()
drawRestoreDown iconColour = pure ()
drawRestoreDown :: GDK.RGBA -> Cairo.Render Bool
drawRestoreDown iconColour = do
withRGBA iconColour Cairo.setSourceRGBA
Cairo.newPath
Cairo.moveTo 8.453125 4.179688
Cairo.lineTo 8.453125 9.230469
Cairo.lineTo 4.941406 9.230469
Cairo.lineTo 4.941406 19.105469
Cairo.lineTo 15.8125 19.105469
Cairo.lineTo 15.8125 14.761719
Cairo.lineTo 19.324219 14.761719
Cairo.lineTo 19.324219 4.179688
Cairo.closePath
Cairo.moveTo 9.988281 7.261719
Cairo.lineTo 17.773438 7.261719
Cairo.lineTo 17.773438 13.238281
Cairo.lineTo 15.8125 13.238281
Cairo.lineTo 15.8125 9.230469
Cairo.lineTo 9.988281 9.230469
Cairo.closePath
Cairo.moveTo 6.476563 12.316406
Cairo.lineTo 14.261719 12.316406
Cairo.lineTo 14.261719 17.597656
Cairo.lineTo 6.476563 17.597656
Cairo.closePath
Cairo.fillPreserve
pure True
-- | Maximise window icon.
drawMaximise :: GDK.RGBA -> Cairo.Render ()
drawMaximise iconColour = pure ()
drawMaximise :: GDK.RGBA -> Cairo.Render Bool
drawMaximise iconColour = do
withRGBA iconColour Cairo.setSourceRGBA
Cairo.newPath
Cairo.moveTo 5.386719 5.449219
Cairo.lineTo 5.386719 18.550781
Cairo.lineTo 18.613281 18.550781
Cairo.lineTo 18.613281 5.449219
Cairo.closePath
Cairo.moveTo 6.921875 9.128906
Cairo.lineTo 17.078125 9.128906
Cairo.lineTo 17.078125 17.023438
Cairo.lineTo 6.921875 17.023438
Cairo.closePath
Cairo.fillPreserve
pure True
-- | Close window icon.
drawClose :: GDK.RGBA -> Cairo.Render ()
drawClose iconColour = pure ()
drawClose :: GDK.RGBA -> Cairo.Render Bool
drawClose iconColour = do
Cairo.setLineWidth 2
withRGBA iconColour Cairo.setSourceRGBA
Cairo.setLineCap Cairo.LineCapRound
Cairo.setLineJoin Cairo.LineJoinMiter
Cairo.newPath
Cairo.moveTo 6.132813 6.238281
Cairo.lineTo 17.867188 17.761719
Cairo.strokePreserve
Cairo.newPath
Cairo.moveTo 6.132813 17.761719
Cairo.lineTo 17.867188 6.23828
Cairo.strokePreserve
pure True