Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 56 additions & 22 deletions Examples/Markdown4DStudioFMX/Markdown4DStudioFMX.Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell)
procedure CopyHtmlToClipboard(const Fragment: string);
procedure CloseApplication;
procedure BuildToolbar;
procedure FocusEditor;
function ResolveIconFontName: string;
function AddIconButton(const Glyph: string; const Hint: string; const Handler: TNotifyEvent): TRectangle;
procedure AddSeparator;
Expand Down Expand Up @@ -192,6 +193,7 @@ TMarkdown4DStudioFMXForm = class(TForm, IPadEditorView, IPadShell)
function TryHandleCommandShortcut(const Key: Word): Boolean;
function TryHandleGlobalKey(const Key: Word): Boolean;
procedure ExecuteFormatCommand(const Command: TEditorCommand);
function AdoptPreviewSelection: Boolean;
procedure ToggleDarkTheme;
procedure ToggleTocPane;
procedure HandleDocumentHandedOver(const FileName: string);
Expand Down Expand Up @@ -318,7 +320,8 @@ implementation
Markdown4DStudio.LinkPolicy,
Markdown4DStudio.HtmlExport,
Markdown4D.Extensions.Chart.BlockOverride,
Markdown4D.Extensions.Mermaid.BlockOverride;
Markdown4D.Extensions.Mermaid.BlockOverride,
Markdown4D.Parser.SourceMap;

constructor TMarkdown4DStudioFMXForm.Create(Owner: TComponent);
begin
Expand Down Expand Up @@ -392,6 +395,15 @@ destructor TMarkdown4DStudioFMXForm.Destroy;
FLightTheme.Free;
end;

procedure TMarkdown4DStudioFMXForm.FocusEditor;
begin
// Preview only mode hides the editor, and focusing a control that is not
// visible raises. Every path that returns focus to the editor goes through
// here so none of them can.
if FEditor.CanFocus then
FEditor.SetFocus;
end;

procedure TMarkdown4DStudioFMXForm.BuildToolbar;
begin
FToolbar := TRectangle.Create(Self);
Expand Down Expand Up @@ -940,17 +952,17 @@ function TMarkdown4DStudioFMXForm.BuildCommandActions: TPadCommandActions;
Result.ShowFind := procedure begin ShowFindBar; end;
Result.ShowReplace := procedure begin ShowReplaceBar; end;
Result.FindInPreview := procedure begin ExecuteFind; end;
Result.Undo := procedure begin FEditor.Undo; FEditor.SetFocus; end;
Result.Redo := procedure begin FEditor.Redo; FEditor.SetFocus; end;
Result.SelectAll := procedure begin FEditor.SelectAll; FEditor.SetFocus; end;
Result.Indent := procedure begin FEditor.Indent; FEditor.SetFocus; end;
Result.Outdent := procedure begin FEditor.Outdent; FEditor.SetFocus; end;
Result.DeleteWordLeft := procedure begin FEditor.DeleteWordLeft; FEditor.SetFocus; end;
Result.Undo := procedure begin FEditor.Undo; FocusEditor; end;
Result.Redo := procedure begin FEditor.Redo; FocusEditor; end;
Result.SelectAll := procedure begin FEditor.SelectAll; FocusEditor; end;
Result.Indent := procedure begin FEditor.Indent; FocusEditor; end;
Result.Outdent := procedure begin FEditor.Outdent; FocusEditor; end;
Result.DeleteWordLeft := procedure begin FEditor.DeleteWordLeft; FocusEditor; end;
Result.ExecuteFormat :=
procedure(const Command: TEditorCommand)
begin
FEditor.ExecuteCommand(Command);
FEditor.SetFocus;
FocusEditor;
end;
end;

Expand Down Expand Up @@ -1134,10 +1146,36 @@ function TMarkdown4DStudioFMXForm.TryHandleGlobalKey(const Key: Word): Boolean;
Result := True;
end;

function TMarkdown4DStudioFMXForm.AdoptPreviewSelection: Boolean;
begin
// Text selected in the preview is the user pointing at characters of the
// document, so move the editor onto them before the command runs. A selection
// that cannot be traced back exactly is left alone rather than guessed at.
Result := False;

if not FPreview.Visible then
Exit;

var Span: TMarkdownSourceSpan;
if not FPreview.TrySelectedSourceSpan(Span) then
Exit;

FEditor.SetSelection(Span.StartOffset - 1, Span.Length);
FPreview.ClearSelection;
Result := True;
end;

procedure TMarkdown4DStudioFMXForm.ExecuteFormatCommand(const Command: TEditorCommand);
begin
const FromPreview = AdoptPreviewSelection;

// A command aimed at the preview needs the editor on screen, otherwise the
// change lands where the user cannot see it.
if FromPreview and (FViewMode = TPadViewMode.PreviewOnly) then
SetViewMode(TPadViewMode.Split);

FEditor.ExecuteCommand(Command);
FEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioFMXForm.DoShow;
Expand Down Expand Up @@ -1241,7 +1279,7 @@ procedure TMarkdown4DStudioFMXForm.CloseFindBar;
FFindBar.Visible := False;
FEditor.ClearHighlights;

FEditor.SetFocus;
FocusEditor;
end;


Expand Down Expand Up @@ -1288,7 +1326,7 @@ procedure TMarkdown4DStudioFMXForm.ClosePalette;
begin
FPalette.Visible := False;

FEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioFMXForm.RefreshPaletteList;
Expand Down Expand Up @@ -1409,7 +1447,7 @@ procedure TMarkdown4DStudioFMXForm.EnterZen;
UpdateZenPadding;

FZenActive := True;
FEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioFMXForm.ExitZen;
Expand All @@ -1428,7 +1466,7 @@ procedure TMarkdown4DStudioFMXForm.ExitZen;
ApplyViewMode;

FZenActive := False;
FEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioFMXForm.UpdateZenPadding;
Expand Down Expand Up @@ -1586,26 +1624,22 @@ procedure TMarkdown4DStudioFMXForm.CopyHtmlToClipboard(const Fragment: string);

procedure TMarkdown4DStudioFMXForm.HandleBoldClick(Sender: TObject);
begin
FEditor.ExecuteCommand(TEditorCommand.Bold);
FEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Bold);
end;

procedure TMarkdown4DStudioFMXForm.HandleItalicClick(Sender: TObject);
begin
FEditor.ExecuteCommand(TEditorCommand.Italic);
FEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Italic);
end;

procedure TMarkdown4DStudioFMXForm.HandleLinkClick(Sender: TObject);
begin
FEditor.ExecuteCommand(TEditorCommand.Link);
FEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Link);
end;

procedure TMarkdown4DStudioFMXForm.HandleCodeClick(Sender: TObject);
begin
FEditor.ExecuteCommand(TEditorCommand.CodeBlock);
FEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.CodeBlock);
end;

procedure TMarkdown4DStudioFMXForm.HandleThemeClick(Sender: TObject);
Expand Down Expand Up @@ -1733,7 +1767,7 @@ procedure TMarkdown4DStudioFMXForm.HandleTocChange(Sender: TObject);
FTocFollowing := False;
end;

FEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioFMXForm.HandleTick(Sender: TObject);
Expand Down
80 changes: 55 additions & 25 deletions Examples/Markdown4DStudioVCL/Markdown4DStudioVCL.Main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ TPadChrome = record
procedure ShowSaveError(const FileName, ErrorMessage: string);
procedure CloseApplication;
procedure ConfigureControls;
procedure FocusEditor;
procedure BuildToolbar;
function ResolveIconFontName: string;
function AddIconButton(const Glyph: string; const Hint: string; const Handler: TNotifyEvent): TSpeedButton;
Expand All @@ -178,6 +179,7 @@ TPadChrome = record
procedure HandleExportClick(Sender: TObject);
procedure HandleCopyHtmlClick(Sender: TObject);
procedure ExecuteFormatCommand(const Command: TEditorCommand);
function AdoptPreviewSelection: Boolean;
procedure DoExportHtml;
procedure DoCopyHtml;
procedure CopyHtmlToClipboard(const Fragment: string);
Expand Down Expand Up @@ -301,7 +303,8 @@ implementation
Markdown4DStudio.Workspace,
Markdown4DStudio.LinkPolicy,
Markdown4DStudio.SingleInstance,
Markdown4DStudio.HtmlExport;
Markdown4DStudio.HtmlExport,
Markdown4D.Parser.SourceMap;

{$R *.dfm}

Expand Down Expand Up @@ -370,6 +373,15 @@ procedure TMarkdown4DStudioVCLForm.ConfigureControls;
lblFindCount.Caption := EmptyFindCaption;
end;

procedure TMarkdown4DStudioVCLForm.FocusEditor;
begin
// Preview only mode hides the editor, and the VCL refuses to focus a control
// that is not visible. Every path that returns focus to the editor goes
// through here so none of them can raise.
if mdEditor.CanFocus then
mdEditor.SetFocus;
end;

procedure TMarkdown4DStudioVCLForm.BuildToolbar;
begin
FIconFontName := ResolveIconFontName;
Expand Down Expand Up @@ -735,26 +747,22 @@ procedure TMarkdown4DStudioVCLForm.HandleRecentItemClick(Sender: TObject);

procedure TMarkdown4DStudioVCLForm.HandleBoldClick(Sender: TObject);
begin
mdEditor.ExecuteCommand(TEditorCommand.Bold);
mdEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Bold);
end;

procedure TMarkdown4DStudioVCLForm.HandleItalicClick(Sender: TObject);
begin
mdEditor.ExecuteCommand(TEditorCommand.Italic);
mdEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Italic);
end;

procedure TMarkdown4DStudioVCLForm.HandleLinkClick(Sender: TObject);
begin
mdEditor.ExecuteCommand(TEditorCommand.Link);
mdEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.Link);
end;

procedure TMarkdown4DStudioVCLForm.HandleCodeClick(Sender: TObject);
begin
mdEditor.ExecuteCommand(TEditorCommand.CodeBlock);
mdEditor.SetFocus;
ExecuteFormatCommand(TEditorCommand.CodeBlock);
end;

procedure TMarkdown4DStudioVCLForm.HandleExportClick(Sender: TObject);
Expand All @@ -767,10 +775,36 @@ procedure TMarkdown4DStudioVCLForm.HandleCopyHtmlClick(Sender: TObject);
DoCopyHtml;
end;

function TMarkdown4DStudioVCLForm.AdoptPreviewSelection: Boolean;
begin
// Text selected in the preview is the user pointing at characters of the
// document, so move the editor onto them before the command runs. A selection
// that cannot be traced back exactly is left alone rather than guessed at.
Result := False;

if not mdPreview.Visible then
Exit;

var Span: TMarkdownSourceSpan;
if not mdPreview.TrySelectedSourceSpan(Span) then
Exit;

mdEditor.SetSelection(Span.StartOffset - 1, Span.Length);
mdPreview.ClearSelection;
Result := True;
end;

procedure TMarkdown4DStudioVCLForm.ExecuteFormatCommand(const Command: TEditorCommand);
begin
const FromPreview = AdoptPreviewSelection;

// A command aimed at the preview needs the editor on screen, otherwise the
// change lands where the user cannot see it.
if FromPreview and (FViewMode = TPadViewMode.PreviewOnly) then
SetViewMode(TPadViewMode.Split);

mdEditor.ExecuteCommand(Command);
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.DoExportHtml;
Expand Down Expand Up @@ -1138,7 +1172,7 @@ procedure TMarkdown4DStudioVCLForm.HandleTocListClick(Sender: TObject);
mdEditor.ScrollToSourceLine(SourceLine);

lstToc.ItemIndex := Index;
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.HandleTick(Sender: TObject);
Expand Down Expand Up @@ -1691,12 +1725,12 @@ function TMarkdown4DStudioVCLForm.BuildCommandActions: TPadCommandActions;
Result.ShowFind := procedure begin ShowFindBar; end;
Result.ShowReplace := procedure begin ShowReplaceBar; end;
Result.FindInPreview := procedure begin ExecuteFind; end;
Result.Undo := procedure begin mdEditor.Undo; mdEditor.SetFocus; end;
Result.Redo := procedure begin mdEditor.Redo; mdEditor.SetFocus; end;
Result.SelectAll := procedure begin mdEditor.SelectAll; mdEditor.SetFocus; end;
Result.Indent := procedure begin mdEditor.Indent; mdEditor.SetFocus; end;
Result.Outdent := procedure begin mdEditor.Outdent; mdEditor.SetFocus; end;
Result.DeleteWordLeft := procedure begin mdEditor.DeleteWordLeft; mdEditor.SetFocus; end;
Result.Undo := procedure begin mdEditor.Undo; FocusEditor; end;
Result.Redo := procedure begin mdEditor.Redo; FocusEditor; end;
Result.SelectAll := procedure begin mdEditor.SelectAll; FocusEditor; end;
Result.Indent := procedure begin mdEditor.Indent; FocusEditor; end;
Result.Outdent := procedure begin mdEditor.Outdent; FocusEditor; end;
Result.DeleteWordLeft := procedure begin mdEditor.DeleteWordLeft; FocusEditor; end;
Result.ExecuteFormat :=
procedure(const Command: TEditorCommand)
begin
Expand Down Expand Up @@ -1829,8 +1863,7 @@ procedure TMarkdown4DStudioVCLForm.CloseFindBar;

EnforceTopBarOrder;

if mdEditor.CanFocus then
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.FindInEditor;
Expand Down Expand Up @@ -1866,8 +1899,7 @@ procedure TMarkdown4DStudioVCLForm.ClosePalette;
begin
FPalette.Visible := False;

if mdEditor.CanFocus then
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.RefreshPaletteList;
Expand Down Expand Up @@ -2018,8 +2050,7 @@ procedure TMarkdown4DStudioVCLForm.EnterZen;

FZenActive := True;

if mdEditor.CanFocus then
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.ExitZen;
Expand All @@ -2039,8 +2070,7 @@ procedure TMarkdown4DStudioVCLForm.ExitZen;

FZenActive := False;

if mdEditor.CanFocus then
mdEditor.SetFocus;
FocusEditor;
end;

procedure TMarkdown4DStudioVCLForm.UpdateZenPadding;
Expand Down
Loading