mirror of
https://gitlab.com/sheaf/metabrush.git
synced 2024-11-05 06:43:37 +00:00
add CSS for stroke popover menu
This commit is contained in:
parent
60b65a38e1
commit
bcd0b9fb13
225
assets/theme.css
225
assets/theme.css
|
@ -5,33 +5,33 @@
|
|||
}
|
||||
*/
|
||||
|
||||
.toggle, .dialogButton, .titlebar, .titleBar, .windowIcon, .fileBarCloseButton,
|
||||
.newFileButton, .header, .paned, .panel, .tabs, .frame {
|
||||
.metabrush .toggle, .metabrush .dialogButton, .metabrush .titlebar,
|
||||
.metabrush .windowIcon, .metabrush .fileBarCloseButton,
|
||||
.metabrush .newFileButton, .metabrush .header,
|
||||
.metabrush .paned, .metabrush .panel, .metabrush .tabs, .metabrush .frame {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
windowcontrols {
|
||||
.metabrush windowcontrols {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.reorderable-page {
|
||||
.metabrush .reorderable-page {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.menu * {
|
||||
.metabrush .headerMenu * {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.frame > * {
|
||||
.metabrush .frame > * {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
|
||||
.notebook {
|
||||
.metabrush .notebook {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
|
||||
@import url("colours.css");
|
||||
|
||||
/* Colours parsed by application */
|
||||
|
@ -100,24 +100,24 @@ windowcontrols {
|
|||
.pointSelected {
|
||||
color: @pointSelected;
|
||||
}
|
||||
.viewport {
|
||||
.metabrush .viewport {
|
||||
background-color: @base;
|
||||
color: @base;
|
||||
min-width: 120px;
|
||||
min-height: 90px;
|
||||
}
|
||||
.viewportScrollbar {
|
||||
.metabrush .viewportScrollbar {
|
||||
background-color: @scrollbar;
|
||||
color: @scrollbar;
|
||||
margin: 4px;
|
||||
min-width: 8px;
|
||||
min-height: 8px;
|
||||
}
|
||||
.tabScrollbar {
|
||||
.metabrush .tabScrollbar {
|
||||
background-color: @scrollbar;
|
||||
color: @scrollbar;
|
||||
}
|
||||
.ruler {
|
||||
.metabrush .ruler {
|
||||
background-color: @ruler;
|
||||
color: @ruler;
|
||||
min-width: 16px;
|
||||
|
@ -159,7 +159,7 @@ tooltip {
|
|||
}
|
||||
|
||||
|
||||
.window, .dialog {
|
||||
.metabrush .window, .metabrush .dialog {
|
||||
border-radius: 0px;
|
||||
border-color: @border;
|
||||
box-shadow:
|
||||
|
@ -172,54 +172,54 @@ tooltip {
|
|||
/* Basic text colour */
|
||||
|
||||
/* Basic text font */
|
||||
.text {
|
||||
.metabrush .text {
|
||||
font-family: "Lato", "Roboto", "Helvetica", sans-serif;
|
||||
}
|
||||
|
||||
/* Monospace font */
|
||||
.monospace {
|
||||
.metabrush .monospace {
|
||||
font-family: "Fira Code", "Inconsolata", "Courier", "Courier New", monospace;
|
||||
}
|
||||
|
||||
/* High-constrast text colour */
|
||||
.contrast {
|
||||
.metabrush .contrast {
|
||||
color: @contrast;
|
||||
}
|
||||
|
||||
/* Active (highlighting) colour */
|
||||
.highlight {
|
||||
.metabrush .highlight {
|
||||
color: @highlight;
|
||||
}
|
||||
|
||||
/* Logo area */
|
||||
.logo {
|
||||
.metabrush .logo {
|
||||
margin-left: 4px;
|
||||
min-width: 28px;
|
||||
}
|
||||
|
||||
/* Logo base colour */
|
||||
.logo_base {
|
||||
.metabrush .logo_base {
|
||||
color: @highlight;
|
||||
}
|
||||
|
||||
/* Logo highlight colour */
|
||||
.logo_highlight {
|
||||
.metabrush .logo_highlight {
|
||||
color: @splash;
|
||||
}
|
||||
|
||||
|
||||
/* Rulers */
|
||||
.leftRuler {
|
||||
.metabrush .leftRuler {
|
||||
border-right: 1px solid @rulerBorder;
|
||||
min-width: 16px;
|
||||
}
|
||||
|
||||
.topRuler {
|
||||
.metabrush .topRuler {
|
||||
border-bottom: 1px solid @rulerBorder;
|
||||
min-height: 16px;
|
||||
}
|
||||
|
||||
.rulerCorner {
|
||||
.metabrush .rulerCorner {
|
||||
min-width: 8px;
|
||||
min-height: 8px;
|
||||
border-bottom: 1px solid @rulerBorder;
|
||||
|
@ -227,44 +227,44 @@ tooltip {
|
|||
}
|
||||
|
||||
/* Cursor colour */
|
||||
.cursor {
|
||||
.metabrush .cursor {
|
||||
color: @cursor;
|
||||
}
|
||||
|
||||
/* Bézier path point colour */
|
||||
.point {
|
||||
.metabrush .point {
|
||||
color: @pathPoint;
|
||||
}
|
||||
|
||||
/* Bézier control point colour */
|
||||
.control {
|
||||
.metabrush .control {
|
||||
color: @controlPoint;
|
||||
}
|
||||
|
||||
/* Title bar */
|
||||
.titleBar {
|
||||
.metabrush .titleBar {
|
||||
min-height: 24px;
|
||||
font-size: 12px;
|
||||
background-color: @bg;
|
||||
}
|
||||
|
||||
/*
|
||||
.titleBar > * :hover {
|
||||
.metabrush .titleBar > * :hover {
|
||||
background-color: rgb(72,70,61);
|
||||
}
|
||||
*/
|
||||
|
||||
.title {
|
||||
.metabrush .title {
|
||||
border-top: 2px solid @bg;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
.metabrush .dialog {
|
||||
border: 1px solid @border;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* dialog button */
|
||||
.dialogButton {
|
||||
.metabrush .dialogButton {
|
||||
background-color: @active;
|
||||
border: 1px solid @border;
|
||||
border-radius: 4px;
|
||||
|
@ -272,11 +272,11 @@ tooltip {
|
|||
padding: 2px 10px 2px 10px;
|
||||
}
|
||||
|
||||
.dialogButton:hover {
|
||||
.metabrush .dialogButton:hover {
|
||||
border-color: @plain;
|
||||
}
|
||||
|
||||
.dialogButton:active, .dialogButton:checked {
|
||||
.metabrush .dialogButton:active, .metabrush .dialogButton:checked {
|
||||
color: @active;
|
||||
border-color: @border;
|
||||
background-color: @highlight;
|
||||
|
@ -284,31 +284,31 @@ tooltip {
|
|||
|
||||
/* Menu bar */
|
||||
|
||||
.menu label {
|
||||
.metabrush .headerMenu label {
|
||||
color:@plain;
|
||||
}
|
||||
|
||||
.menu :disabled {
|
||||
.metabrush .headerMenu :disabled {
|
||||
color: @disabled;
|
||||
}
|
||||
|
||||
.menu :focus-within {
|
||||
.metabrush .headerMenu :focus-within {
|
||||
border-color: @plain;
|
||||
}
|
||||
|
||||
.menu :focus{
|
||||
.metabrush .headerMenu :focus{
|
||||
border-color: @active;
|
||||
background-color: @bg;
|
||||
}
|
||||
|
||||
.menu item {
|
||||
.metabrush .headerMenu item {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
color: @plain;
|
||||
border-top: 2px solid @bg;
|
||||
}
|
||||
|
||||
.menu item > * :hover {
|
||||
.metabrush .headerMenu item > * :hover {
|
||||
border-color: @plain;
|
||||
background-color: @active;
|
||||
}
|
||||
|
@ -318,15 +318,15 @@ tooltip {
|
|||
"The visible part of the popover can have a shadow.
|
||||
To specify it in CSS, set the box-shadow of the contents node."
|
||||
*/
|
||||
.menu item > popover > contents {
|
||||
.metabrush .headerMenu item > popover > contents {
|
||||
box-shadow: 2px 3px 3px rgba(0,0,0,0.5)
|
||||
, -2px 3px 3px rgba(0,0,0,0.5)
|
||||
, 0px 4px 3px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
/* Look at the CSS with the GTK inspector to figure this out... */
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > modelbutton,
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > box > modelbutton
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > modelbutton,
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > box > modelbutton
|
||||
{
|
||||
background-color: @bg;
|
||||
color: @active;
|
||||
|
@ -335,46 +335,95 @@ To specify it in CSS, set the box-shadow of the contents node."
|
|||
padding: 6px 10px 6px 10px;
|
||||
}
|
||||
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > separator,
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > separator :hover {
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > separator,
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > separator :hover {
|
||||
background-color: @active;
|
||||
padding: 1px 0px 0px 1px;
|
||||
}
|
||||
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > modelbutton > accelerator,
|
||||
.menu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > box > modelbutton > accelerator {
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > modelbutton > accelerator,
|
||||
.metabrush .headerMenu item > popover > contents > scrolledwindow > viewport > stack > box > box > box > box > modelbutton > accelerator {
|
||||
font-size: 10px;
|
||||
color: @shortcutKey;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.windowIcon {
|
||||
.metabrush .listViewPane :selected {
|
||||
background-color: unset;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* Stroke popover menu */
|
||||
/* TODO: refactor with menu */
|
||||
.metabrush .strokeMenu > * {
|
||||
background-color: @bg;
|
||||
}
|
||||
|
||||
.metabrush .strokeMenu contents {
|
||||
border: unset;
|
||||
border-radius: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.metabrush .strokeMenu .flat {
|
||||
border-left: 2px solid @bg;
|
||||
border-top: 0px;
|
||||
}
|
||||
|
||||
.metabrush .strokeMenu :selected {
|
||||
color: @plain;
|
||||
background-color: @active;
|
||||
font-weight: normal;
|
||||
border-left: 2px solid @plain;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.metabrush .strokeMenu separator {
|
||||
background-color: @contrast;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.metabrush .strokeMenu .separator {
|
||||
color: black;
|
||||
background-color: @contrast;
|
||||
font-weight: normal;
|
||||
opacity: 1;
|
||||
margin: 4px 10px 4px 10px;
|
||||
padding: 0px 6px 0px 6px;
|
||||
border: 0px solid black;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.metabrush .windowIcon {
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
.windowIcon:hover {
|
||||
.metabrush .windowIcon:hover {
|
||||
background-color: @windowButtonHover;
|
||||
}
|
||||
|
||||
.windowIcon:active, .windowIcon:checked {
|
||||
.metabrush .windowIcon:active, .metabrush .windowIcon:checked {
|
||||
background-color: @windowButtonActive;
|
||||
}
|
||||
|
||||
.closeWindowIcon:hover {
|
||||
.metabrush .closeWindowIcon:hover {
|
||||
background-color: @closeButtonHover;
|
||||
}
|
||||
|
||||
.closeWindowIcon:active, .closeWindowIcon:checked {
|
||||
.metabrush .closeWindowIcon:active, .metabrush .closeWindowIcon:checked {
|
||||
background-color: @closeButtonActive;
|
||||
}
|
||||
|
||||
/* Tool bar */
|
||||
.toolBar {
|
||||
.metabrush .toolBar {
|
||||
min-width: 32px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.toolBarSeparator {
|
||||
.metabrush .toolBarSeparator {
|
||||
min-height: 2px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
|
@ -383,7 +432,7 @@ To specify it in CSS, set the box-shadow of the contents node."
|
|||
background-color: @active;
|
||||
}
|
||||
|
||||
.toolItem {
|
||||
.metabrush .toolItem {
|
||||
border-left: 2px solid @bg;
|
||||
min-height: 40px;
|
||||
min-width: 40px;
|
||||
|
@ -393,42 +442,42 @@ To specify it in CSS, set the box-shadow of the contents node."
|
|||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.toolItem:hover {
|
||||
.metabrush .toolItem:hover {
|
||||
border-color: @active;
|
||||
}
|
||||
|
||||
.toolItem:active, .toolItem:checked {
|
||||
.metabrush .toolItem:active, .metabrush .toolItem:checked {
|
||||
border-color: @base;
|
||||
background-color: @active;
|
||||
}
|
||||
|
||||
/* File bar */
|
||||
.fileBar {
|
||||
.metabrush .fileBar {
|
||||
min-height: 24px;
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.fileBarTab {
|
||||
.metabrush .fileBarTab {
|
||||
border-top: 2px solid @bg;
|
||||
}
|
||||
|
||||
.fileBarTab:hover {
|
||||
.metabrush .fileBarTab:hover {
|
||||
border-color: @active;
|
||||
}
|
||||
|
||||
.fileBarTab:active, .fileBarTab:checked {
|
||||
.metabrush .fileBarTab:active, .metabrush .fileBarTab:checked {
|
||||
border-color: @base;
|
||||
background-color: @active;
|
||||
}
|
||||
|
||||
.fileBarTabButton {
|
||||
.metabrush .fileBarTabButton {
|
||||
padding-left: 8px;
|
||||
padding-right: 2px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.fileBarCloseButton {
|
||||
.metabrush .fileBarCloseButton {
|
||||
min-width: 10px;
|
||||
min-height: 22px;
|
||||
padding-left: 1px;
|
||||
|
@ -437,15 +486,15 @@ To specify it in CSS, set the box-shadow of the contents node."
|
|||
color: @plain;
|
||||
}
|
||||
|
||||
.fileBarCloseButton:hover {
|
||||
.metabrush .fileBarCloseButton:hover {
|
||||
color: @closeButtonHover;
|
||||
}
|
||||
|
||||
.fileBarCloseButton:active, .fileBarCloseButton:checked {
|
||||
.metabrush .fileBarCloseButton:active, .metabrush .fileBarCloseButton:checked {
|
||||
color: @closeButtonActive;
|
||||
}
|
||||
|
||||
.newFileButton {
|
||||
.metabrush .newFileButton {
|
||||
color: @newFileButton;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
|
@ -455,55 +504,55 @@ To specify it in CSS, set the box-shadow of the contents node."
|
|||
border-left: 1px solid @bg;
|
||||
}
|
||||
|
||||
.newFileButton:hover, .newFileButton:active, newFileButton:checked {
|
||||
.metabrush .newFileButton:hover, .metabrush .newFileButton:active, .metabrush newFileButton:checked {
|
||||
color: @newFileButtonActive;
|
||||
}
|
||||
|
||||
.newFileButton:active, .newFileButton:checked {
|
||||
.metabrush .newFileButton:active, .metabrush .newFileButton:checked {
|
||||
border-color: @newFileButtonActive;
|
||||
}
|
||||
|
||||
|
||||
/* Panels */
|
||||
.panels {
|
||||
.metabrush .panels {
|
||||
min-width: 120px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.panels tab {
|
||||
.metabrush .panels tab {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
border-top: 2px solid @bg;
|
||||
}
|
||||
|
||||
.panels tab:hover {
|
||||
.metabrush .panels tab:hover {
|
||||
border-color: @active;
|
||||
}
|
||||
|
||||
.panels tab:active, .panels tab:checked {
|
||||
.metabrush .panels tab:active, .metabrush .panels tab:checked {
|
||||
background-color: @active;
|
||||
border-color: rgb(234,223,204);
|
||||
}
|
||||
|
||||
.panel {
|
||||
.metabrush .panel {
|
||||
background-color: @active;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
/* Info bar */
|
||||
.infoBar {
|
||||
.metabrush .infoBar {
|
||||
min-height: 40px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.infoBarInfo {
|
||||
.metabrush .infoBarInfo {
|
||||
margin-left: -4px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
/* Stroke hierarchy layers */
|
||||
|
||||
row {
|
||||
.metabrush row {
|
||||
border-top: 0px;
|
||||
border-bottom: 0px;
|
||||
margin-top: -2px;
|
||||
|
@ -511,18 +560,12 @@ row {
|
|||
}
|
||||
|
||||
/* Slightly hacky way to align layers and groups */
|
||||
indent {
|
||||
.metabrush indent {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
:selected {
|
||||
background-color: rgba(255,255,255,0);
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.layer-item, .brush-item {
|
||||
.metabrush .layer-item, .metabrush .brush-item {
|
||||
color: @plain;
|
||||
background-color: @active;
|
||||
border: 0px solid @bg;
|
||||
|
@ -536,22 +579,22 @@ indent {
|
|||
padding-left: 3px;
|
||||
}
|
||||
|
||||
:selected .layer-item, :selected .brush-item {
|
||||
.metabrush :selected .layer-item, .metabrush :selected .brush-item {
|
||||
color: black;
|
||||
background-color: @contrast;
|
||||
border: 0px solid @contrast;
|
||||
}
|
||||
|
||||
/* Add "drop here" areas when a drag has been initiated */
|
||||
.dragging-item .layer-item {
|
||||
.metabrush .dragging-item .layer-item {
|
||||
}
|
||||
|
||||
/* Style when dragging over an item */
|
||||
.drag-over.layer-item {
|
||||
.metabrush .drag-over.layer-item {
|
||||
}
|
||||
|
||||
/* Style when dragging layer item over the top part of an item */
|
||||
.dragging-item .drag-top.layer-item {
|
||||
.metabrush .dragging-item .drag-top.layer-item {
|
||||
border-top: 2px solid @highlight;
|
||||
margin-top: -2px;
|
||||
box-shadow:
|
||||
|
@ -559,7 +602,7 @@ indent {
|
|||
}
|
||||
|
||||
/* Style when dragging layer item over the bottom part of an item */
|
||||
.dragging-item .drag-bot.layer-item {
|
||||
.metabrush .dragging-item .drag-bot.layer-item {
|
||||
border-bottom: 2px solid @highlight;
|
||||
margin-bottom: -2px;
|
||||
box-shadow:
|
||||
|
@ -567,7 +610,7 @@ indent {
|
|||
}
|
||||
|
||||
/* Style when dragging brush over an item */
|
||||
.dragging-brush .drag-top.layer-item, .dragging-brush .drag-bot.layer-item {
|
||||
.metabrush .dragging-brush .drag-top.layer-item, .dragging-brush .drag-bot.layer-item {
|
||||
border-top: 2px solid @brushStroke;
|
||||
border-bottom: 2px solid @brushStroke;
|
||||
border-left: 0px;
|
||||
|
@ -578,7 +621,7 @@ indent {
|
|||
}
|
||||
|
||||
/* Style for item being dragged */
|
||||
.dragged.layer-item {
|
||||
.metabrush .dragged.layer-item {
|
||||
background-color: @bg;
|
||||
transition:
|
||||
background-color 0.4s ease-in-out;
|
||||
|
|
|
@ -686,6 +686,34 @@ instance HandleAction Delete where
|
|||
-- TODO: handle deletion of layers by checking the current focus.
|
||||
_ -> pure ()
|
||||
|
||||
------------------
|
||||
-- Delete layer --
|
||||
------------------
|
||||
|
||||
data DeleteLayer = DeleteLayer !MetaBrush.Layer.Layer
|
||||
deriving stock Show
|
||||
|
||||
instance HandleAction MetaBrush.Application.Action.DeleteLayer where
|
||||
handleAction
|
||||
uiElts
|
||||
vars@( Variables { toolTVar, modeTVar } )
|
||||
_ =
|
||||
return ()
|
||||
|
||||
---------------
|
||||
-- New group --
|
||||
---------------
|
||||
|
||||
data GroupPosition = GroupAbove | GroupBelow | GroupContaining
|
||||
deriving stock Show
|
||||
|
||||
data NewGroup = NewGroup !GroupPosition !MetaBrush.Layer.Layer
|
||||
deriving stock Show
|
||||
|
||||
instance HandleAction NewGroup where
|
||||
handleAction ( UIElements { viewport = Viewport {..} } ) ( Variables { redrawStrokesTVar, showGuidesTVar } ) ( NewGroup pos lay ) = do
|
||||
return ()
|
||||
|
||||
-------------------
|
||||
-- Toggle guides --
|
||||
-------------------
|
||||
|
|
|
@ -7,6 +7,10 @@ import Data.Word
|
|||
-- gi-gtk
|
||||
import qualified GI.Gtk as GTK
|
||||
|
||||
-- text
|
||||
import Data.Text
|
||||
( Text )
|
||||
|
||||
-- MetaBrush
|
||||
import Math.Linear
|
||||
( ℝ(..), T(..) )
|
||||
|
@ -15,9 +19,12 @@ import MetaBrush.UI.Viewport
|
|||
( Ruler(..) )
|
||||
import MetaBrush.Unique
|
||||
( Unique )
|
||||
import MetaBrush.Layer (Layer)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
actionPrefix :: ActionName -> Text
|
||||
|
||||
class HandleAction action where
|
||||
handleAction :: UIElements -> Variables -> action -> IO ()
|
||||
|
||||
|
@ -38,6 +45,9 @@ instance HandleAction Save
|
|||
data SaveAs = SaveAs
|
||||
instance HandleAction SaveAs
|
||||
|
||||
data Export = Export
|
||||
instance HandleAction Export
|
||||
|
||||
data Close
|
||||
= CloseActive
|
||||
| CloseThis
|
||||
|
@ -76,6 +86,13 @@ instance HandleAction Duplicate
|
|||
data Delete = Delete
|
||||
instance HandleAction Delete
|
||||
|
||||
data DeleteLayer = DeleteLayer !Layer
|
||||
instance HandleAction DeleteLayer
|
||||
|
||||
data GroupPosition = GroupAbove | GroupBelow | GroupContaining
|
||||
data NewGroup = NewGroup !GroupPosition !Layer
|
||||
instance HandleAction NewGroup
|
||||
|
||||
data ToggleGuides = ToggleGuides
|
||||
instance HandleAction ToggleGuides
|
||||
|
||||
|
@ -85,6 +102,9 @@ instance HandleAction Confirm
|
|||
data About = About
|
||||
instance HandleAction About
|
||||
|
||||
data OpenPrefs = OpenPrefs
|
||||
instance HandleAction OpenPrefs
|
||||
|
||||
data MouseMove = MouseMove !( ℝ 2 )
|
||||
instance HandleAction MouseMove
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ import qualified Data.HashSet as HashSet
|
|||
( fromList, toMap )
|
||||
|
||||
-- MetaBrush
|
||||
import MetaBrush.Application.Action
|
||||
hiding ( save, saveAs )
|
||||
import {-# SOURCE #-} MetaBrush.Application.Action
|
||||
import MetaBrush.Application.Context
|
||||
import MetaBrush.Asset.Colours
|
||||
( Colours )
|
||||
|
@ -48,6 +47,8 @@ import MetaBrush.Asset.WindowIcons
|
|||
( drawMinimise, drawRestoreDown, drawMaximise, drawClose )
|
||||
import MetaBrush.GTK.Util
|
||||
( widgetAddClass, widgetAddClasses )
|
||||
import MetaBrush.Layer
|
||||
( Layer(..) )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Types for describing menu items.
|
||||
|
@ -92,6 +93,11 @@ menuActionNames = HashSet.fromList
|
|||
, WinAction "about"
|
||||
-- preferences
|
||||
, WinAction "prefs"
|
||||
-- stroke actions
|
||||
, WinAction "newGroupAbove"
|
||||
, WinAction "newGroupBelow"
|
||||
, WinAction "newGroupContaining"
|
||||
, WinAction "deleteLayer"
|
||||
]
|
||||
|
||||
createMenuActions :: IO ( HashMap ActionName GIO.SimpleAction )
|
||||
|
@ -165,6 +171,18 @@ helpMenuDescription =
|
|||
[ MenuItemDescription "About MetaBrush" ( Just $ WinAction "about", About ) ( Just "<Ctrl>question" )
|
||||
]
|
||||
|
||||
strokeMenuDescription :: Layer -> [ MenuItem ]
|
||||
strokeMenuDescription lay =
|
||||
[ case lay of
|
||||
StrokeLayer {} -> MenuItemDescription "Delete stroke" ( Nothing, DeleteLayer lay) Nothing
|
||||
GroupLayer {} -> MenuItemDescription "Delete group" ( Nothing, DeleteLayer lay) Nothing
|
||||
, Section ( Just "New group" ) $
|
||||
[ MenuItemDescription "...above" ( Nothing, NewGroup GroupAbove lay ) Nothing
|
||||
, MenuItemDescription "...below" ( Nothing, NewGroup GroupBelow lay ) Nothing
|
||||
, MenuItemDescription "...containing" ( Nothing, NewGroup GroupContaining lay ) Nothing
|
||||
]
|
||||
]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Creating a GTK popover menu bar from a menu description.
|
||||
|
||||
|
@ -225,7 +243,7 @@ createMenuBar uiElts@( UIElements { application, window, titleBar } ) vars colou
|
|||
--GTK.windowAddAccelGroup window accelGroup
|
||||
menu <- createMenu uiElts vars
|
||||
menuBar <- GTK.popoverMenuBarNewFromModel ( Just menu )
|
||||
widgetAddClasses menuBar [ "menu", "text", "plain" ]
|
||||
widgetAddClasses menuBar [ "headerMenu", "text", "plain" ]
|
||||
GTK.headerBarPackStart titleBar menuBar
|
||||
|
||||
-- TODO: this is a bit of a workaround to add hover highlight to top-level menu items.
|
||||
|
|
|
@ -67,7 +67,7 @@ createPanelBar panelBox = do
|
|||
for_ [ strokesTab, brushesTab, transformTab, historyTab ] \ tab -> do
|
||||
widgetAddClasses tab [ "plain", "text", "panelTab" ]
|
||||
|
||||
for_ [ layersScrolledWindow, brushesScrolledWindow ] \ w -> widgetAddClass w "panel"
|
||||
for_ [ layersScrolledWindow, brushesScrolledWindow ] \ w -> widgetAddClasses w [ "panel", "listViewPane" ]
|
||||
for_ [ transformPanelBox, historyPanelBox ] \ panel -> do
|
||||
widgetAddClass panel "panel"
|
||||
|
||||
|
|
|
@ -89,9 +89,13 @@ import MetaBrush.Brush
|
|||
import MetaBrush.Document
|
||||
import MetaBrush.Document.Diff
|
||||
import MetaBrush.Document.History
|
||||
import MetaBrush.GTK.Util
|
||||
import MetaBrush.Layer
|
||||
import MetaBrush.Stroke hiding ( Layer(..) )
|
||||
import MetaBrush.Unique
|
||||
import MetaBrush.UI.Menu
|
||||
( strokeMenuDescription, makeMenu )
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -418,6 +422,9 @@ newLayerView :: UIElements -> Variables -> IO GTK.ListView
|
|||
newLayerView uiElts@( UIElements { window } ) vars = mdo
|
||||
|
||||
layersListFactory <- GTK.signalListItemFactoryNew
|
||||
layerMenu <- GIO.menuNew
|
||||
layerPopover <- GTK.popoverMenuNewFromModel ( Nothing @GIO.Menu )
|
||||
widgetAddClasses layerPopover [ "strokeMenu", "text", "plain" ]
|
||||
|
||||
-- Connect to "setup" signal to create generic widgets for viewing the tree.
|
||||
--
|
||||
|
@ -440,13 +447,36 @@ newLayerView uiElts@( UIElements { window } ) vars = mdo
|
|||
|
||||
expander <- newLayerViewWidget
|
||||
GTK.listItemSetChild listItem ( Just expander )
|
||||
GTK.widgetAddCssClass expander "layer-item"
|
||||
widgetAddClass expander "layer-item"
|
||||
|
||||
LayerViewWidget
|
||||
{ layerViewLabel = label
|
||||
, layerViewCheckButton = visibleButton }
|
||||
<- getLayerViewWidget expander
|
||||
|
||||
------------------
|
||||
-- GestureClick --
|
||||
------------------
|
||||
|
||||
click <- GTK.gestureClickNew
|
||||
|
||||
void $ GTK.onGestureClickPressed click $ \ clickNo x y -> do
|
||||
case clickNo of
|
||||
_ -> do
|
||||
GTK.widgetUnparent layerPopover
|
||||
GTK.widgetSetParent layerPopover expander
|
||||
layer <- getLayerData listItem
|
||||
GIO.menuRemoveAll layerMenu
|
||||
makeMenu uiElts vars layerMenu ( strokeMenuDescription layer )
|
||||
GTK.popoverMenuSetMenuModel layerPopover ( Just layerMenu )
|
||||
rect <- GDK.newZeroRectangle
|
||||
GDK.setRectangleX rect ( round x )
|
||||
GDK.setRectangleY rect ( round y )
|
||||
GTK.popoverSetPointingTo layerPopover ( Just rect )
|
||||
GTK.popoverPopup layerPopover
|
||||
|
||||
_ -> return ()
|
||||
|
||||
----------------------------
|
||||
-- Visibility CheckButton --
|
||||
----------------------------
|
||||
|
@ -516,7 +546,7 @@ newLayerView uiElts@( UIElements { window } ) vars = mdo
|
|||
}
|
||||
|
||||
val <- GDK.contentProviderNewForValue =<< GIO.toGValue ( GI.HValue dnd_sourceItem )
|
||||
GTK.widgetAddCssClass window "dragging-item"
|
||||
widgetAddClass window "dragging-item"
|
||||
return $ Just val
|
||||
void $ GTK.onDragSourceDragBegin dragSource $ \ _drag -> do
|
||||
|
||||
|
@ -528,7 +558,7 @@ newLayerView uiElts@( UIElements { window } ) vars = mdo
|
|||
-}
|
||||
noPaintable <- GDK.paintableNewEmpty 0 0
|
||||
GTK.dragSourceSetIcon ?self ( Just noPaintable ) 0 0
|
||||
GTK.widgetAddCssClass expander "dragged"
|
||||
widgetAddClass expander "dragged"
|
||||
-- TODO: add "dragged" class for all descendants as well.
|
||||
void $ GTK.onDragSourceDragCancel dragSource $ \ _drag _reason -> do
|
||||
GTK.widgetRemoveCssClass window "dragging-item"
|
||||
|
@ -720,38 +750,39 @@ newLayerView uiElts@( UIElements { window } ) vars = mdo
|
|||
return True
|
||||
|
||||
void $ GTK.onDropTargetEnter dropTarget $ \ _x y -> do
|
||||
GTK.widgetAddCssClass expander "drag-over"
|
||||
widgetAddClass expander "drag-over"
|
||||
h <- GTK.widgetGetHeight expander
|
||||
if y < 0.5 * fromIntegral h
|
||||
then do
|
||||
GTK.widgetAddCssClass expander "drag-top"
|
||||
widgetAddClass expander "drag-top"
|
||||
else do
|
||||
GTK.widgetAddCssClass expander "drag-bot"
|
||||
widgetAddClass expander "drag-bot"
|
||||
mbNextItem <- getNextItem_maybe expander
|
||||
for_ mbNextItem $ \ nextItem -> do
|
||||
GTK.widgetAddCssClass nextItem "drag-top"
|
||||
widgetAddClass nextItem "drag-top"
|
||||
return [ GDK.DragActionCopy ]
|
||||
void $ GTK.onDropTargetMotion dropTarget $ \ _x y -> do
|
||||
h <- GTK.widgetGetHeight expander
|
||||
if y < 0.5 * fromIntegral h
|
||||
then do
|
||||
GTK.widgetRemoveCssClass expander "drag-bot"
|
||||
GTK.widgetAddCssClass expander "drag-top"
|
||||
widgetAddClass expander "drag-top"
|
||||
mbNextItem <- getNextItem_maybe expander
|
||||
for_ mbNextItem $ \ nextItem -> do
|
||||
GTK.widgetRemoveCssClass nextItem "drag-top"
|
||||
else do
|
||||
GTK.widgetRemoveCssClass expander "drag-top"
|
||||
GTK.widgetAddCssClass expander "drag-bot"
|
||||
widgetAddClass expander "drag-bot"
|
||||
mbNextItem <- getNextItem_maybe expander
|
||||
for_ mbNextItem $ \ nextItem -> do
|
||||
GTK.widgetAddCssClass nextItem "drag-top"
|
||||
widgetAddClass nextItem "drag-top"
|
||||
return [ GDK.DragActionCopy ]
|
||||
void $ GTK.onDropTargetLeave dropTarget $ do
|
||||
dropTargetCleanup
|
||||
|
||||
GTK.widgetAddController expander dragSource
|
||||
GTK.widgetAddController expander dropTarget
|
||||
GTK.widgetAddController expander click
|
||||
|
||||
-- Connect to "bind" signal to modify the generic widget to display the data for this list item.
|
||||
_ <- GTK.onSignalListItemFactoryBind layersListFactory $ \ listItem0 -> do
|
||||
|
|
Loading…
Reference in a new issue