diff --git a/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Defines.pas b/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Defines.pas index 595bd67..4b42f2e 100644 --- a/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Defines.pas +++ b/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Defines.pas @@ -38,6 +38,10 @@ interface SeparatorDarkColor = TAlphaColor($FF505050); HoverLightColor = TAlphaColor($FFE0E0E0); HoverDarkColor = TAlphaColor($FF3E3E3E); + // A pressed toolbar button sits one step beyond hover, so the active view mode + // stays readable while the pointer rests on one of its neighbours. + ActiveLightColor = TAlphaColor($FFCBCBCB); + ActiveDarkColor = TAlphaColor($FF525252); TabActiveLightColor = TAlphaColor($FFFFFFFF); TabActiveDarkColor = TAlphaColor($FF3F3F3F); TabHoverLightColor = TAlphaColor($FFEAEAEA); diff --git a/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Main.pas b/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Main.pas index 19635cd..07b5ad6 100644 --- a/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Main.pas +++ b/Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Main.pas @@ -72,6 +72,9 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell) FItalicButton: TRectangle; FLinkButton: TRectangle; FCodeButton: TRectangle; + FViewEditorButton: TRectangle; + FViewSplitButton: TRectangle; + FViewPreviewButton: TRectangle; FThemeButton: TRectangle; FTocButton: TRectangle; FZenButton: TRectangle; @@ -83,6 +86,7 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell) FSeparators: TArray; FToolbarFill: TAlphaColor; FHoverColor: TAlphaColor; + FActiveColor: TAlphaColor; FTocFill: TAlphaColor; FTocTextColor: TAlphaColor; FChromeTextColor: TAlphaColor; @@ -157,6 +161,8 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell) procedure AddSeparator; procedure HandleIconMouseEnter(Sender: TObject); procedure HandleIconMouseLeave(Sender: TObject); + function RestingColorFor(const Button: TRectangle): TAlphaColor; + procedure UpdateViewModeButtons; procedure BuildTitleBar; function AddCaptionButton(const Glyph: string; const Hint: string; const Handler: TNotifyEvent): TRectangle; @@ -235,6 +241,9 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell) procedure HandleItalicClick(Sender: TObject); procedure HandleLinkClick(Sender: TObject); procedure HandleCodeClick(Sender: TObject); + procedure HandleViewEditorClick(Sender: TObject); + procedure HandleViewSplitClick(Sender: TObject); + procedure HandleViewPreviewClick(Sender: TObject); procedure HandleThemeClick(Sender: TObject); procedure HandleTocClick(Sender: TObject); procedure HandleZenClick(Sender: TObject); @@ -406,6 +415,12 @@ procedure TMarkdown4DStudioFMXForm.BuildToolbar; FTocButton := AddIconButton(GlyphToc, HintToc, HandleTocClick); FThemeButton := AddIconButton(GlyphTheme, HintTheme, HandleThemeClick); + // Left aligned FMX controls stack in reverse of the order they are created, so + // these read as editor, split, preview on screen and match the VCL toolbar. + FViewPreviewButton := AddIconButton(GlyphViewPreview, HintViewPreview, HandleViewPreviewClick); + FViewSplitButton := AddIconButton(GlyphViewSplit, HintViewSplit, HandleViewSplitClick); + FViewEditorButton := AddIconButton(GlyphViewEditor, HintViewEditor, HandleViewEditorClick); + AddSeparator; FCodeButton := AddIconButton(GlyphCode, HintCode, HandleCodeClick); @@ -536,10 +551,35 @@ procedure TMarkdown4DStudioFMXForm.HandleIconMouseEnter(Sender: TObject); procedure TMarkdown4DStudioFMXForm.HandleIconMouseLeave(Sender: TObject); begin const Button = Sender as TRectangle; - Button.Fill.Color := FToolbarFill; + Button.Fill.Color := RestingColorFor(Button); HideHint; end; +function TMarkdown4DStudioFMXForm.RestingColorFor(const Button: TRectangle): TAlphaColor; +begin + // The view mode buttons carry a pressed state, so they do not fall back to the + // plain toolbar fill once the pointer leaves or the theme is swapped. + if ((Button = FViewEditorButton) and (FViewMode = TPadViewMode.EditorOnly)) or + ((Button = FViewSplitButton) and (FViewMode = TPadViewMode.Split)) or + ((Button = FViewPreviewButton) and (FViewMode = TPadViewMode.PreviewOnly)) then + Result := FActiveColor + else + Result := FToolbarFill; +end; + +procedure TMarkdown4DStudioFMXForm.UpdateViewModeButtons; +begin + // Keep the lit button in step with the mode however it was set: toolbar click, + // Ctrl+1/2/3, the command palette, session restore or leaving zen mode. The nil + // guard covers ApplyViewMode running before BuildToolbar. + if FViewSplitButton = nil then + Exit; + + FViewEditorButton.Fill.Color := RestingColorFor(FViewEditorButton); + FViewSplitButton.Fill.Color := RestingColorFor(FViewSplitButton); + FViewPreviewButton.Fill.Color := RestingColorFor(FViewPreviewButton); +end; + procedure TMarkdown4DStudioFMXForm.BuildTitleBar; begin FTitleBar := TRectangle.Create(Self); @@ -1212,6 +1252,8 @@ procedure TMarkdown4DStudioFMXForm.ApplyViewMode; else raise ENotSupportedException.CreateFmt('Unsupported view mode: %d', [Ord(FViewMode)]); end; + + UpdateViewModeButtons; end; procedure TMarkdown4DStudioFMXForm.ShowFindBar; @@ -1608,6 +1650,21 @@ procedure TMarkdown4DStudioFMXForm.HandleCodeClick(Sender: TObject); FEditor.SetFocus; end; +procedure TMarkdown4DStudioFMXForm.HandleViewEditorClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.EditorOnly); +end; + +procedure TMarkdown4DStudioFMXForm.HandleViewSplitClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.Split); +end; + +procedure TMarkdown4DStudioFMXForm.HandleViewPreviewClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.PreviewOnly); +end; + procedure TMarkdown4DStudioFMXForm.HandleThemeClick(Sender: TObject); begin ToggleDarkTheme; @@ -1990,6 +2047,7 @@ procedure TMarkdown4DStudioFMXForm.ApplyTheme; FToolbarFill := ToolbarDarkColor; FHoverColor := HoverDarkColor; + FActiveColor := ActiveDarkColor; IconColor := IconDarkColor; SeparatorColor := SeparatorDarkColor; end @@ -2000,6 +2058,7 @@ procedure TMarkdown4DStudioFMXForm.ApplyTheme; FToolbarFill := ToolbarLightColor; FHoverColor := HoverLightColor; + FActiveColor := ActiveLightColor; end; FTocFill := FToolbarFill; @@ -2013,7 +2072,7 @@ procedure TMarkdown4DStudioFMXForm.ApplyTheme; for var Button in FIconButtons do begin - Button.Fill.Color := FToolbarFill; + Button.Fill.Color := RestingColorFor(Button); end; for var GlyphText in FIconGlyphs do diff --git a/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Defines.pas b/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Defines.pas index 2e3fdb2..3c39c9d 100644 --- a/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Defines.pas +++ b/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Defines.pas @@ -22,6 +22,7 @@ interface StatusLabelLeftMargin = 8; ButtonSpacing = 4; IconGlyphSize = 14; + ViewModeGroupIndex = 1; // TSpeedButton group for the mutually exclusive view mode buttons ToolbarLightColor = TColor($00F3F3F3); ToolbarDarkColor = TColor($002D2D2D); IconLightColor = TColor($00404040); diff --git a/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Main.pas b/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Main.pas index a6d90c2..52230df 100644 --- a/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Main.pas +++ b/Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Main.pas @@ -87,6 +87,9 @@ TPadChrome = record FItalicButton: TSpeedButton; FLinkButton: TSpeedButton; FCodeButton: TSpeedButton; + FViewEditorButton: TSpeedButton; + FViewSplitButton: TSpeedButton; + FViewPreviewButton: TSpeedButton; FThemeButton: TSpeedButton; FTocButton: TSpeedButton; FZenButton: TSpeedButton; @@ -175,6 +178,10 @@ TPadChrome = record procedure HandleItalicClick(Sender: TObject); procedure HandleLinkClick(Sender: TObject); procedure HandleCodeClick(Sender: TObject); + procedure HandleViewEditorClick(Sender: TObject); + procedure HandleViewSplitClick(Sender: TObject); + procedure HandleViewPreviewClick(Sender: TObject); + procedure UpdateViewModeButtons; procedure HandleExportClick(Sender: TObject); procedure HandleCopyHtmlClick(Sender: TObject); procedure ExecuteFormatCommand(const Command: TEditorCommand); @@ -394,6 +401,16 @@ procedure TMarkdown4DStudioVCLForm.BuildToolbar; AddSeparator; + // The view mode buttons share a GroupIndex, so the VCL keeps exactly one of them + // down: clicking one releases the other two, and clicking the active one keeps it + // down because AllowAllUp stays False. + FViewEditorButton := AddIconButton(GlyphViewEditor, HintViewEditor, HandleViewEditorClick); + FViewEditorButton.GroupIndex := ViewModeGroupIndex; + FViewSplitButton := AddIconButton(GlyphViewSplit, HintViewSplit, HandleViewSplitClick); + FViewSplitButton.GroupIndex := ViewModeGroupIndex; + FViewPreviewButton := AddIconButton(GlyphViewPreview, HintViewPreview, HandleViewPreviewClick); + FViewPreviewButton.GroupIndex := ViewModeGroupIndex; + FThemeButton := AddIconButton(GlyphTheme, HintTheme, HandleThemeClick); FTocButton := AddIconButton(GlyphToc, HintToc, HandleTocClick); FZenButton := AddIconButton(GlyphZen, HintZen, HandleZenClick); @@ -757,6 +774,34 @@ procedure TMarkdown4DStudioVCLForm.HandleCodeClick(Sender: TObject); mdEditor.SetFocus; end; +procedure TMarkdown4DStudioVCLForm.HandleViewEditorClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.EditorOnly); +end; + +procedure TMarkdown4DStudioVCLForm.HandleViewSplitClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.Split); +end; + +procedure TMarkdown4DStudioVCLForm.HandleViewPreviewClick(Sender: TObject); +begin + SetViewMode(TPadViewMode.PreviewOnly); +end; + +procedure TMarkdown4DStudioVCLForm.UpdateViewModeButtons; +begin + // Keep the pressed button in step with the mode however it was set: toolbar click, + // Ctrl+1/2/3, the command palette, session restore or leaving zen mode. The nil + // guard covers ApplyViewMode running before BuildToolbar. + if FViewSplitButton = nil then + Exit; + + FViewEditorButton.Down := FViewMode = TPadViewMode.EditorOnly; + FViewSplitButton.Down := FViewMode = TPadViewMode.Split; + FViewPreviewButton.Down := FViewMode = TPadViewMode.PreviewOnly; +end; + procedure TMarkdown4DStudioVCLForm.HandleExportClick(Sender: TObject); begin DoExportHtml; @@ -1742,6 +1787,7 @@ procedure TMarkdown4DStudioVCLForm.ApplyViewMode; end; end; + UpdateViewModeButtons; EnforceTopBarOrder; EnforceLeftPaneOrder; end; diff --git a/Examples/Shared/Markdown4DStudio.Defines.pas b/Examples/Shared/Markdown4DStudio.Defines.pas index 6116a62..a9bdec0 100644 --- a/Examples/Shared/Markdown4DStudio.Defines.pas +++ b/Examples/Shared/Markdown4DStudio.Defines.pas @@ -23,6 +23,9 @@ interface GlyphItalic = Char($E8DB); GlyphLink = Char($E71B); GlyphCode = Char($E943); + GlyphViewEditor = Char($E70F); // Edit (pencil) + GlyphViewSplit = Char($E89A); // TwoPage + GlyphViewPreview = Char($E890); // View (eye) GlyphTheme = Char($E793); GlyphToc = Char($E8FD); GlyphFind = Char($E721); @@ -41,6 +44,9 @@ interface HintItalic = 'Italic (Ctrl+I)'; HintLink = 'Link (Ctrl+K)'; HintCode = 'Code block'; + HintViewEditor = 'Editor only (Ctrl+1)'; + HintViewSplit = 'Split view (Ctrl+2)'; + HintViewPreview = 'Preview only (Ctrl+3)'; HintTheme = 'Toggle theme'; HintToc = 'Toggle contents'; HintFind = 'Find in preview';