From 237fb4a7d73b03c720e5cf773879178725918739 Mon Sep 17 00:00:00 2001 From: sheaf Date: Sun, 3 Nov 2024 11:46:34 +0100 Subject: [PATCH] disable keyboard shortcuts when text editing --- src/app/MetaBrush/GTK/Util.hs | 9 +++-- src/app/MetaBrush/UI/FileBar.hs | 12 ++++--- src/app/MetaBrush/UI/StrokeTreeView.hs | 49 ++++++++++++++++++-------- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/app/MetaBrush/GTK/Util.hs b/src/app/MetaBrush/GTK/Util.hs index 1a935e6..a28237b 100644 --- a/src/app/MetaBrush/GTK/Util.hs +++ b/src/app/MetaBrush/GTK/Util.hs @@ -91,11 +91,14 @@ infixl 1 >>?= -- controllers attached to it, as we don't want the label to participate in -- drag-and-drop operations, especially because having it participate in -- drag-and-drop operations triggers segfaults due to a GTK bug. -editableLabelNew :: IO GTK.EditableLabel -editableLabelNew = do - label <- GTK.editableLabelNew " " +editableLabelNew :: Text -> IO GTK.EditableLabel +editableLabelNew txt = do + label <- GTK.editableLabelNew txt widget <- GTK.toWidget label removeControllers widget + -- Make the label not editable to start with, + -- because we want it to be editable on double-clicks not single clicks. + GTK.editableSetEditable label False return label where diff --git a/src/app/MetaBrush/UI/FileBar.hs b/src/app/MetaBrush/UI/FileBar.hs index a8392d8..a0bf021 100644 --- a/src/app/MetaBrush/UI/FileBar.hs +++ b/src/app/MetaBrush/UI/FileBar.hs @@ -13,7 +13,7 @@ module MetaBrush.UI.FileBar import Control.Monad ( join, void, when ) import Data.Foldable - ( sequenceA_ ) + ( sequenceA_, traverse_ ) import Data.Traversable ( for ) @@ -77,7 +77,7 @@ import MetaBrush.UI.Viewport import MetaBrush.Unique ( Unique, freshUnique, uniqueText ) import MetaBrush.GTK.Util - ( widgetAddClass, widgetAddClasses ) + ( editableLabelNew, widgetAddClass, widgetAddClasses ) -------------------------------------------------------------------------------- @@ -103,8 +103,7 @@ newFileTab newDocUniq <- STM.atomically $ runReaderT freshUnique uniqueSupply pure ( newDocUniq, newHistory $ emptyDocument ( "Untitled " <> uniqueText newDocUniq ) ) - pgLabel <- GTK.editableLabelNew ( documentName $ documentMetadata $ present thisTabDocHist ) - GTK.editableSetEditable pgLabel False + pgLabel <- editableLabelNew ( documentName $ documentMetadata $ present thisTabDocHist ) -- Connect a signal for editing the document name. -- @@ -114,6 +113,9 @@ newFileTab hasFocus <- GTK.widgetHasFocus pgLabel when hasFocus do newDocName <- GTK.editableGetText pgLabel + traverse_ ( `GIO.setSimpleActionEnabled` True ) menuActions + -- NB: 'updateUIAction' below will properly re-disable 'undo' + -- and 'redo' if there is nothing to undo or redo. uiUpdate <- STM.atomically $ do STM.modifyTVar' openDocumentsTVar @@ -180,6 +182,8 @@ newFileTab 1 -> do handleAction uiElts vars ( SwitchTo thisTabDocUnique ) when ( nbClicks > 1 ) do + -- Disable all accelerators when doing text entry. + traverse_ ( `GIO.setSimpleActionEnabled` False ) menuActions GTK.editableSetEditable pgLabel True GTK.editableLabelStartEditing pgLabel void $ GTK.widgetGrabFocus pgLabel diff --git a/src/app/MetaBrush/UI/StrokeTreeView.hs b/src/app/MetaBrush/UI/StrokeTreeView.hs index eff2ae8..e276c2c 100644 --- a/src/app/MetaBrush/UI/StrokeTreeView.hs +++ b/src/app/MetaBrush/UI/StrokeTreeView.hs @@ -22,9 +22,9 @@ module MetaBrush.UI.StrokeTreeView import Control.Arrow ( second ) import Control.Monad - ( void ) + ( void, when ) import Data.Foldable - ( for_ ) + ( for_, traverse_ ) import Data.List ( elemIndex ) import qualified Data.List.NonEmpty as NE @@ -347,7 +347,7 @@ newLayerViewWidget = do contentBox <- GTK.boxNew GTK.OrientationHorizontal 0 GTK.treeExpanderSetChild expander ( Just contentBox ) - itemLabel <- editableLabelNew + itemLabel <- editableLabelNew " " GTK.boxAppend contentBox itemLabel visibleButton <- GTK.buttonNew @@ -537,22 +537,42 @@ newLayerView uiElts@( UIElements { window, colours } ) vars = mdo -- EditableLabel -- ------------------- + labelClicks <- GTK.gestureClickNew + -- Connect a signal for editing the layer name. -- -- NB: we don't use the 'onEditableChanged' signal, as that updates -- after every key stroke. void $ GI.after label ( GI.PropertyNotify #hasFocus ) $ \ _ -> do - newText <- GTK.editableGetText label - layer <- getLayerData listItem - modifyingCurrentDocument uiElts vars \ doc -> do - let doc' = - over ( field' @"documentMetadata" . field' @"layerMetadata" - . field' @"layerNames" - ) - ( Map.insert ( layerUnique layer ) newText ) - doc - return $ - UpdateDoc $ UpdateDocumentTo doc' TrivialDiff + hasFocus <- GTK.widgetHasFocus label + when hasFocus do + newText <- GTK.editableGetText label + layer <- getLayerData listItem + GTK.editableSetEditable label False + traverse_ ( `GIO.setSimpleActionEnabled` True ) ( menuActions uiElts ) + -- NB: 'modifyingCurrentDocument' below will properly re-disable + -- 'undo' and 'redo' if there is nothing to undo or redo. + modifyingCurrentDocument uiElts vars \ doc -> do + let doc' = + over ( field' @"documentMetadata" . field' @"layerMetadata" + . field' @"layerNames" + ) + ( Map.insert ( layerUnique layer ) newText ) + doc + return $ + UpdateDoc ( UpdateDocumentTo doc' TrivialDiff ) + + void $ GTK.onGestureClickReleased labelClicks $ \ nbClicks _x _y -> do + button <- GTK.gestureSingleGetCurrentButton ?self + case button of + 1 -> + when ( nbClicks > 1 ) do + -- Disable all accelerators when doing text entry. + traverse_ ( `GIO.setSimpleActionEnabled` False ) ( menuActions uiElts ) + GTK.editableSetEditable label True + GTK.editableLabelStartEditing label + void $ GTK.widgetGrabFocus label + _ -> return () ---------------- -- DragSource -- @@ -823,6 +843,7 @@ newLayerView uiElts@( UIElements { window, colours } ) vars = mdo void $ GTK.onDropTargetLeave dropTarget $ do dropTargetCleanup + GTK.widgetAddController label labelClicks GTK.widgetAddController expander dragSource GTK.widgetAddController expander dropTarget GTK.widgetAddController expander click