From a2a47250423e3b22bdcf1a52f2e214b71102579c Mon Sep 17 00:00:00 2001 From: Graeme Geldenhuys Date: Thu, 21 Feb 2013 15:33:08 +0000 Subject: nanoedit - a mini notepad like text editor I have been using this for some time now. I required a mini editor on non-Windows platforms, so created this project to solve that. This is also a testbed project for my "elastic tabstops" implementation. --- examples/apps/nanoedit/README.txt | 10 + examples/apps/nanoedit/elastictabstops.pas | 219 +++++++++++++++++++ examples/apps/nanoedit/extrafpc.cfg | 6 + examples/apps/nanoedit/frm_find.pas | 196 +++++++++++++++++ examples/apps/nanoedit/install/nanoedit.desktop | 9 + examples/apps/nanoedit/install/nanoedit.xpm | 47 +++++ examples/apps/nanoedit/mainfrm.pas | 267 ++++++++++++++++++++++++ examples/apps/nanoedit/nanoedit.lpi | 82 ++++++++ examples/apps/nanoedit/nanoedit.lpr | 27 +++ examples/apps/nanoedit/testfiles/file1.pas | 109 ++++++++++ examples/apps/nanoedit/testfiles/file2.pas | 19 ++ 11 files changed, 991 insertions(+) create mode 100644 examples/apps/nanoedit/README.txt create mode 100644 examples/apps/nanoedit/elastictabstops.pas create mode 100644 examples/apps/nanoedit/extrafpc.cfg create mode 100644 examples/apps/nanoedit/frm_find.pas create mode 100644 examples/apps/nanoedit/install/nanoedit.desktop create mode 100644 examples/apps/nanoedit/install/nanoedit.xpm create mode 100644 examples/apps/nanoedit/mainfrm.pas create mode 100644 examples/apps/nanoedit/nanoedit.lpi create mode 100644 examples/apps/nanoedit/nanoedit.lpr create mode 100644 examples/apps/nanoedit/testfiles/file1.pas create mode 100644 examples/apps/nanoedit/testfiles/file2.pas diff --git a/examples/apps/nanoedit/README.txt b/examples/apps/nanoedit/README.txt new file mode 100644 index 00000000..50b5bbab --- /dev/null +++ b/examples/apps/nanoedit/README.txt @@ -0,0 +1,10 @@ +Title: nanoedit +Author: Graeme Geldenhuys +Description: +------------ +I often need a Notepad like (very basic) editor on non-Windows platforms, +for some of my other projects. I created nanoedit for that reason. I'm +also using nanoedit as a testing platform for the fpg_textedit unit +(part of the Maximus IDE example project), and for my experimental +"elastic tabstops" [http://nickgravgaard.com/elastictabstops/] +implementation. diff --git a/examples/apps/nanoedit/elastictabstops.pas b/examples/apps/nanoedit/elastictabstops.pas new file mode 100644 index 00000000..53861ad8 --- /dev/null +++ b/examples/apps/nanoedit/elastictabstops.pas @@ -0,0 +1,219 @@ +unit elastictabstops; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpg_memo; + +type + + TMutableInteger = class(TObject) + public + Value: integer; + end; + + + TETLine = class(TObject) + public + StartPos: integer; + EndPos: integer; + NumTabs: integer; + constructor Create; + end; + + + TETTabstop = class(TObject) + public + TextWidthPix: integer; + WidestWidthPix: TMutableInteger; + StartPos: integer; + EndPos: integer; + EndsInTab: boolean; + constructor Create; + end; + + + + TElasticTabstopsDocFilter = class(TObject) + private + FMemo: TfpgMemo; + FTabMultiples: integer; + FTabMinimum: integer; + FTabPadding: integer; + FMaxTabstops: integer; + protected + property Memo: TfpgMemo read FMemo; + function CalcTabWidth(TextWidthInTab: integer): integer; + public + constructor Create(AMemo: TfpgMemo); + procedure StretchTabstops; + property MaxTabstops: integer read FMaxTabstops write FMaxTabstops; + end; + + +implementation + +{ TETLine } + +constructor TETLine.Create; +begin + StartPos := 0; + EndPos := 0; + NumTabs := 0; +end; + +{ TETTabstop } + +constructor TETTabstop.Create; +begin + TextWidthPix := 0; +// WidestWidthPix := 0; + StartPos := 0; + EndPos := 0; + EndsInTab := False; +end; + + +{ TElasticTabstopsDocFilter } + +function TElasticTabstopsDocFilter.CalcTabWidth(TextWidthInTab: integer): integer; +var + w: integer; +begin + w := ((TextWidthInTab div FTabMultiples) + 1) * FTabMultiples; + if w < FTabMinimum then + w := FTabMinimum; + Inc(w, FTabPadding); + Result := w; +end; + +constructor TElasticTabstopsDocFilter.Create(AMemo: TfpgMemo); +begin + FMemo := AMemo; + // tabstops are at least 32 pixels plus 8 pixels of padding + FTabMultiples := 1; // must be greater than 0 + FTabMinimum := 32; + FTabPadding := 8; + + FMaxTabstops := 32; // tabs per line +end; + +procedure TElasticTabstopsDocFilter.StretchTabstops; +var + linecount: integer; + lines: array of TETLine; + grid: array of array of TETTabstop; + l: integer; + t: integer; + c: integer; + lineStart: integer; + lineEnd: integer; + lineText: string; + tabs_on_line: integer; + textWidthInTab: integer; + theWidestWidthPix: TMutableInteger; + maxWidth: integer; + accTabStop: integer; +begin + linecount := FMemo.Lines.Count; + SetLength(lines, linecount); + SetLength(grid, linecount, FMaxTabstops); + + // initialise array + for l := 0 to linecount - 1 do // for each line + begin + lines[l] := TETLine.Create; + for t := 0 to MaxTabstops - 1 do // for each column + grid[l, t] := TETTabstop.Create; + end; + + // get width of text in cells + for l := 0 to linecount - 1 do // for each line + begin + {$Note What must these be??? } + lineStart := 0; + lineEnd := 0; + lines[l].StartPos := lineStart; + lines[l].EndPos := lineEnd; + + lineText := FMemo.Lines[l]; + tabs_on_line := 0; + textWidthInTab := 0; + + for c := 1 to Length(lineText) do // for each char in current line + begin + if c = Length(lineText) then + begin + grid[l, tabs_on_line].EndsInTab := False; + grid[l, tabs_on_line].EndPos := lineStart + c; + textWidthInTab := 0; + end + else if lineText[c] = #9 then + begin + grid[l, tabs_on_line].EndsInTab := True; + grid[l, tabs_on_line].EndPos := lineStart + c; + grid[l, tabs_on_line].TextWidthPix := CalcTabWidth(textWidthInTab); + Inc(tabs_on_line, 1); + grid[l, tabs_on_line].StartPos := lineStart + c + 1; + Inc(lines[l].NumTabs, 1); + textWidthInTab := 0; + end + else + Inc(textWidthInTab, FMemo.Canvas.Font.TextWidth(lineText[c])); + end; { for c } + end; { for l } + + // find columns blocks and stretch to fit the widest cell + for t := 0 to MaxTabstops - 1 do // for each column + begin + // All tabstops in column block point to same number. You change one, and + // they all change + theWidestWidthPix := TMutableInteger.Create; // reference + theWidestWidthPix.Value := 0; + maxWidth := 0; + for l := 0 to linecount - 1 do // for each line + begin + if grid[l, t].EndsInTab then + begin + grid[l, t].WidestWidthPix := theWidestWidthPix; // copy reference + if grid[l, t].TextWidthPix < maxWidth then + grid[l, t].TextWidthPix := maxWidth + else + begin + maxWidth := grid[l, t].TextWidthPix; + theWidestWidthPix.Value := maxWidth; + end; + end + else // end column block + begin + theWidestWidthPix := TMutableInteger.Create; // new reference + theWidestWidthPix.Value := 0; + maxWidth := 0; + end; { if/else } + end; { for l } + end; + + // apply tabstop sizes to the text + for l := 0 to linecount - 1 do // for each line + begin + // accumulate tabstop widths + accTabStop := 0; + for t := 0 to lines[l].NumTabs - 1 do + begin + Inc(accTabStop, grid[l, t].WidestWidthPix.Value); + grid[l, t].TextWidthPix := accTabStop; + end; + + // SetBlocksTabStops(grid[l], lines[l].NumTabs); +// Delete(); + +// FMemo.Lines[l]; +// FMemo.Invalidate; + end; + +end; + +end. + diff --git a/examples/apps/nanoedit/extrafpc.cfg b/examples/apps/nanoedit/extrafpc.cfg new file mode 100644 index 00000000..034a7b9d --- /dev/null +++ b/examples/apps/nanoedit/extrafpc.cfg @@ -0,0 +1,6 @@ +-FUunits +-Fu../../lib/$fpctarget +-Fu../ide/src/ +-Xs +-XX +-CX diff --git a/examples/apps/nanoedit/frm_find.pas b/examples/apps/nanoedit/frm_find.pas new file mode 100644 index 00000000..96bfe6fa --- /dev/null +++ b/examples/apps/nanoedit/frm_find.pas @@ -0,0 +1,196 @@ +unit frm_find; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils, Classes, fpg_base, fpg_main, fpg_form, fpg_label, + fpg_edit, fpg_button, fpg_checkbox, fpg_panel, fpg_radiobutton, + fpg_textedit; + +type + + TFindForm = class(TfpgForm) + private + {@VFD_HEAD_BEGIN: FindForm} + Label1: TfpgLabel; + FindEdit: TfpgEdit; + btnFind: TfpgButton; + btnCancel: TfpgButton; + GroupBox1: TfpgGroupBox; + chkWholeWord: TfpgCheckBox; + chkCaseSensitive: TfpgCheckBox; + rbForward: TfpgRadioButton; + rbBackward: TfpgRadioButton; + {@VFD_HEAD_END: FindForm} + procedure btnFindClicked(Sender: TObject); + function GetTextToFind: TfpgString; + function GetIsForward: boolean; + function GetFindOptions: TfpgFindOptions; + public + procedure AfterCreate; override; + function Execute: boolean; + property TextToFind: TfpgString read GetTextToFind; + property IsForward: boolean read GetIsForward; + property FindOptions: TfpgFindOptions read GetFindOptions; + end; + +{@VFD_NEWFORM_DECL} + +implementation + +{@VFD_NEWFORM_IMPL} + +procedure TFindForm.btnFindClicked(Sender: TObject); +begin + ModalResult := mrOK; +end; + +function TFindForm.GetTextToFind: TfpgString; +begin + Result := FindEdit.Text; +end; + +function TFindForm.GetIsForward: boolean; +begin + Result := rbForward.Checked; +end; + +function TFindForm.GetFindOptions: TfpgFindOptions; +begin + Result := [foEntireScope]; + if chkWholeWord.Checked then + Result := Result + [foWholeWords]; + if chkCaseSensitive.Checked then + Result := Result + [foMatchCase]; +end; + +procedure TFindForm.AfterCreate; +begin + {%region 'Auto-generated GUI code' -fold} + {@VFD_BODY_BEGIN: FindForm} + Name := 'FindForm'; + SetPosition(292, 173, 429, 110); + WindowTitle := 'Find'; + Hint := ''; + + Label1 := TfpgLabel.Create(self); + with Label1 do + begin + Name := 'Label1'; + SetPosition(4, 4, 280, 16); + FontDesc := '#Label1'; + Hint := ''; + Text := 'Text to find:'; + end; + + FindEdit := TfpgEdit.Create(self); + with FindEdit do + begin + Name := 'FindEdit'; + SetPosition(4, 20, 332, 24); + Anchors := [anLeft,anRight,anTop]; + ExtraHint := ''; + FontDesc := '#Edit1'; + Hint := ''; + TabOrder := 2; + Text := ''; + end; + + btnFind := TfpgButton.Create(self); + with btnFind do + begin + Name := 'btnFind'; + SetPosition(345, 8, 80, 24); + Anchors := [anRight,anTop]; + Text := 'Find'; + FontDesc := '#Label1'; + Hint := ''; + ImageName := ''; + TabOrder := 3; + OnClick := @btnFindClicked; + end; + + btnCancel := TfpgButton.Create(self); + with btnCancel do + begin + Name := 'btnCancel'; + SetPosition(345, 36, 80, 24); + Anchors := [anRight,anTop]; + Text := 'Cancel'; + FontDesc := '#Label1'; + Hint := ''; + ImageName := ''; + ModalResult := mrCancel; + TabOrder := 4; + end; + + GroupBox1 := TfpgGroupBox.Create(self); + with GroupBox1 do + begin + Name := 'GroupBox1'; + SetPosition(160, 56, 176, 44); + FontDesc := '#Label1'; + Hint := ''; + Text := 'Direction'; + end; + + chkWholeWord := TfpgCheckBox.Create(self); + with chkWholeWord do + begin + Name := 'chkWholeWord'; + SetPosition(4, 52, 148, 20); + FontDesc := '#Label1'; + Hint := ''; + TabOrder := 6; + Text := 'Whole words only'; + end; + + chkCaseSensitive := TfpgCheckBox.Create(self); + with chkCaseSensitive do + begin + Name := 'chkCaseSensitive'; + SetPosition(4, 72, 148, 20); + FontDesc := '#Label1'; + Hint := ''; + TabOrder := 7; + Text := 'Case sensitive'; + end; + + rbForward := TfpgRadioButton.Create(GroupBox1); + with rbForward do + begin + Name := 'rbForward'; + SetPosition(8, 20, 76, 20); + Checked := True; + FontDesc := '#Label1'; + GroupIndex := 0; + Hint := ''; + TabOrder := 1; + Text := 'Forword'; + end; + + rbBackward := TfpgRadioButton.Create(GroupBox1); + with rbBackward do + begin + Name := 'rbBackward'; + SetPosition(88, 20, 84, 20); + FontDesc := '#Label1'; + GroupIndex := 0; + Hint := ''; + TabOrder := 2; + Text := 'Backward'; + end; + + {@VFD_BODY_END: FindForm} + {%endregion} +end; + +function TFindForm.Execute: boolean; +begin + Result := ShowModal <> mrCancel; +end; + + +end. diff --git a/examples/apps/nanoedit/install/nanoedit.desktop b/examples/apps/nanoedit/install/nanoedit.desktop new file mode 100644 index 00000000..0670af6e --- /dev/null +++ b/examples/apps/nanoedit/install/nanoedit.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Exec='/path/to/nanoedit/nanoedit' %f +Name=NanoEdit +Icon=/path/to/fpgui/examples/apps/nanoedit/install/nanoedit.xpm +Comment=fpGUI's own mini text editor +NoDisplay=true diff --git a/examples/apps/nanoedit/install/nanoedit.xpm b/examples/apps/nanoedit/install/nanoedit.xpm new file mode 100644 index 00000000..cf439e29 --- /dev/null +++ b/examples/apps/nanoedit/install/nanoedit.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *editpad[] = { +"32 32 11 1", +"0 c None", +"1 c #000000", +"2 c #FFFFFF", +"3 c #00DF00", +"4 c #6BFF6B", +"5 c #00DF4A", +"6 c #009600", +"7 c #848284", +"8 c #C6C3C6", +"9 c #000084", +"a c #0000FF", +"00000000000110110110110110110000", +"00000000011211211211211211211100", +"00000000133144144144144144153610", +"00000000134444444444444444433171", +"00000001344444444444444444436171", +"00000001344444444444444444331871", +"00000013444411111111114444361871", +"00000013444444444444444443318871", +"00000134444111111111144443619971", +"00000134444444444444444433188871", +"00001344444444444444444436188871", +"00001344444444444444444331999971", +"00013444444444444444444361882871", +"00013444444444444444443318882871", +"0013444444444444444444361999a971", +"00134444444444444444433188822871", +"01344444444444444444436188822871", +"013444444444444444443319999aa971", +"13444444444444444444361888222871", +"13333333333333333333318888222871", +"16666666666666666666619999aaa971", +"01111111111111111111188882222871", +"00000000018888888888888822222871", +"000000000199999999999999aaaaa971", +"00000000018888888888888222222871", +"00000000018888888888888222222871", +"0000000001999999999999aaaaaaa971", +"00000000018888888888822222222871", +"00000000012222222222222222228871", +"00000000001888888888888888888771", +"00000000000177777777777777777710", +"00000000000011111111111111111100" +}; diff --git a/examples/apps/nanoedit/mainfrm.pas b/examples/apps/nanoedit/mainfrm.pas new file mode 100644 index 00000000..bcacf714 --- /dev/null +++ b/examples/apps/nanoedit/mainfrm.pas @@ -0,0 +1,267 @@ +unit mainfrm; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils, Classes, fpg_base, fpg_main, + fpg_form, fpg_button, fpg_menu, fpg_textedit; + +type + + TMainForm = class(TfpgForm) + private + {@VFD_HEAD_BEGIN: MainFrom} + menu: TfpgMenuBar; + mnuFile: TfpgPopupMenu; + mnuSearch: TfpgPopupMenu; + memEditor: TfpgTextEdit; + btnGO: TfpgButton; + {@VFD_HEAD_END: MainFrom} + FTextToFind: TfpgString; + FFindOptions: TfpgFindOptions; + FIsForward: boolean; + procedure FormShow(Sender: TObject); + procedure miOpenClick(Sender: TObject); + procedure miSaveClick(Sender: TObject); + procedure miSaveAsClick(Sender: TObject); + procedure miGoToLineClick(Sender: TObject); + procedure miFindClick(Sender: TObject); + procedure miFindNextClick(Sender: TObject); + procedure miQuitClick(Sender: TObject); + procedure btnGOClick(Sender: TObject); + procedure memEditorChanged(Sender: TObject); + public + procedure AfterCreate; override; + end; + +{@VFD_NEWFORM_DECL} + +implementation + +uses + elastictabstops, + fpg_dialogs, + frm_find; + +{@VFD_NEWFORM_IMPL} + +procedure TMainForm.FormShow(Sender: TObject); +var + s: string; +begin + if ParamCount > 0 then + begin + ShowMessage(ParamStr(1)); + s := ParamStr(1); + if Pos('file://', s) > 0 then + s := StringReplace(s, 'file://', '', []); + memEditor.LoadFromFile(s); + end; +end; + +procedure TMainForm.miOpenClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunOpenFile then + begin + memEditor.Lines.LoadFromFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miSaveClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunSaveFile then + begin + memEditor.Lines.SaveToFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miSaveAsClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunSaveFile then + begin + memEditor.Lines.SaveToFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miGoToLineClick(Sender: TObject); +var + sValue: string; + i: integer; +begin + if fpgInputQuery('Go to line', 'Go to line number?', sValue) then + begin + try + i := StrToInt(sValue); + memEditor.GotoLine(i); + except + on E: Exception do + ShowMessage('Invalid line number.' + LineEnding + E.Message); + end; + end; +end; + +procedure TMainForm.miFindClick(Sender: TObject); +var + dlg: TFindForm; +begin + FTextToFind := ''; + dlg := TFindForm.Create(nil); + try + if dlg.Execute then + begin + FTextToFind := dlg.TextToFind; + FFindOptions := dlg.FindOptions; + FIsForward := dlg.IsForward; + miFindNextClick(nil); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miFindNextClick(Sender: TObject); +begin + if FTextToFind <> '' then + memEditor.FindText(FTextToFind, FFindOptions, FIsForward); +end; + +procedure TMainForm.miQuitClick(Sender: TObject); +begin + Close; +end; + +procedure TMainForm.btnGOClick(Sender: TObject); +var + ftr: TElasticTabstopsDocFilter; +begin +{ + ftr := TElasticTabstopsDocFilter.Create(memEditor); + try + try + ftr.StretchTabstops; + finally + ftr.Free; + end; + except + on E: exception do + ShowMessage(e.Message); + end; +} +end; + +procedure TMainForm.memEditorChanged(Sender: TObject); +var + ftr: TElasticTabstopsDocFilter; +begin +{ + ftr := TElasticTabstopsDocFilter.Create(memEditor); + try + try + ftr.StretchTabstops; + finally + ftr.Free; + end; + except + on E: exception do + ShowMessage(e.Message); + end; +} +end; + +procedure TMainForm.AfterCreate; +begin + {@VFD_BODY_BEGIN: MainFrom} + Name := 'MainFrom'; + SetPosition(298, 169, 717, 410); + WindowTitle := 'fpGUI nanoedit'; + Hint := ''; + WindowPosition := wpScreenCenter; + OnShow := @FormShow; + + menu := TfpgMenuBar.Create(self); + with menu do + begin + Name := 'menu'; + SetPosition(0, 0, 717, 24); + Anchors := [anLeft,anRight,anTop]; + end; + + mnuFile := TfpgPopupMenu.Create(self); + with mnuFile do + begin + Name := 'mnuFile'; + SetPosition(320, 4, 120, 20); + AddMenuItem('Open...', 'Ctrl+O', @miOpenClick); + AddMenuItem('Save', 'Ctrl+S', @miSaveClick); + AddMenuItem('Save as...', 'Ctrl+Shift+S', @miSaveAsClick); + AddMenuItem('-', '', nil); + AddMenuItem('Quit', 'Ctrl+Q', @miQuitClick); + end; + + mnuSearch := TfpgPopupMenu.Create(self); + with mnuSearch do + begin + Name := 'mnuSearch'; + SetPosition(320, 25, 120, 20); + AddMenuItem('Find...', 'Ctrl+F', @miFindClick); + AddMenuItem('Find next', 'F3', @miFindNextClick); + AddMenuItem('Replace', 'Ctrl+R', nil).Enabled := False; + AddMenuitem('-', '', nil); + AddMenuItem('Go to line...', 'Ctrl+G', @miGoToLineClick); + end; + + memEditor := TfpgTextEdit.Create(self); + with memEditor do + begin + Name := 'memEditor'; + SetPosition(0, 52, 717, 358); + Anchors := [anLeft,anRight,anTop,anBottom]; + FontDesc := '#edit2'; + GutterVisible := True; + RightEdge := True; + end; + + btnGO := TfpgButton.Create(self); + with btnGO do + begin + Name := 'btnGO'; + SetPosition(260, 26, 75, 24); + Text := 'GO'; + FontDesc := '#Label1'; + Hint := ''; + ImageName := ''; + TabOrder := 4; + OnClick := @btnGOClick; + end; + + {@VFD_BODY_END: MainFrom} + + menu.AddMenuItem('&File', nil).SubMenu := mnuFile; + menu.AddMenuItem('&Search', nil).SubMenu := mnuSearch; +end; + + +end. diff --git a/examples/apps/nanoedit/nanoedit.lpi b/examples/apps/nanoedit/nanoedit.lpi new file mode 100644 index 00000000..3eb499a8 --- /dev/null +++ b/examples/apps/nanoedit/nanoedit.lpi @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apps/nanoedit/nanoedit.lpr b/examples/apps/nanoedit/nanoedit.lpr new file mode 100644 index 00000000..659ed7d5 --- /dev/null +++ b/examples/apps/nanoedit/nanoedit.lpr @@ -0,0 +1,27 @@ +program nanoedit; + +{$mode objfpc}{$H+} +{$ifdef mswindows} {$apptype gui} {$endif} + +uses + Classes, fpg_main, mainfrm; + + +procedure MainProc; +var + frm: TMainForm; +begin + fpgApplication.Initialize; + frm := TMainForm.Create(nil); + try + frm.Show; + fpgApplication.Run; + finally + frm.Free; + end; +end; + +begin + MainProc; +end. + diff --git a/examples/apps/nanoedit/testfiles/file1.pas b/examples/apps/nanoedit/testfiles/file1.pas new file mode 100644 index 00000000..717c65d1 --- /dev/null +++ b/examples/apps/nanoedit/testfiles/file1.pas @@ -0,0 +1,109 @@ +unit file1; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils, Classes, gfxbase, fpgfx, gui_edit, + gfx_widget, gui_form, gui_label, gui_button, + gui_listbox, gui_memo, gui_combobox, gui_grid, + gui_dialogs, gui_checkbox, gui_tree, gui_trackbar, + gui_progressbar, gui_radiobutton, gui_tab, gui_menu; + +type + + TMainForm = class(TfpgForm) + private + procedure miOpenClick(Sender: TObject); + procedure miSaveClick(Sender: TObject); + procedure miQuitClick(Sender: TObject); + public + {@VFD_HEAD_BEGIN: MainFrom} + menu: TfpgMenuBar; + mnuFile: TfpgPopupMenu; + memEditor: TfpgMemo; + {@VFD_HEAD_END: MainFrom} + + procedure AfterCreate; override; + end; + +{@VFD_NEWFORM_DECL} + +implementation + +{@VFD_NEWFORM_IMPL} + +procedure TMainForm.miOpenClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunOpenFile then + begin + memEditor.Lines.LoadFromFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miSaveClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunSaveFile then + begin + memEditor.Lines.SaveToFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; + +procedure TMainForm.miQuitClick(Sender: TObject); +begin + Close; +end; + +procedure TMainForm.AfterCreate; +begin + {@VFD_BODY_BEGIN: MainFrom} + SetPosition(327, 283, 500, 348); + WindowPosition := wpScreenCenter; + WindowTitle := 'fpGUI nanoedit'; + + menu := TfpgMenuBar.Create(self); + with menu do + begin + SetPosition(0, 0, 500, 24); + Anchors := [anTop, anLeft, anRight]; + end; + + mnuFile := TfpgPopupMenu.Create(self); + with mnuFile do + begin + SetPosition(320, 4, 120, 20); + AddMenuItem('Open...', '', @miOpenClick); + AddMenuItem('Save...', '', @miSaveClick); + AddMenuItem('Quit', '', @miQuitClick); + end; + + memEditor := TfpgMemo.Create(self); + with memEditor do + begin + SetPosition(0, 24, 500, 324); + Anchors := [anLeft,anRight,anTop,anBottom]; + FontDesc := '#Edit1'; + end; + + {@VFD_BODY_END: MainFrom} + + menu.AddMenuItem('&File', nil).SubMenu := mnuFile; +end; + + +end. diff --git a/examples/apps/nanoedit/testfiles/file2.pas b/examples/apps/nanoedit/testfiles/file2.pas new file mode 100644 index 00000000..86144432 --- /dev/null +++ b/examples/apps/nanoedit/testfiles/file2.pas @@ -0,0 +1,19 @@ +{ ************************************** + * oeu oe uoe uoeu * + * oeu oe uoe uoeu * + * oeu oe uoe uoeu * + ************************************** } +procedure TMainForm.miOpenClick(Sender: TObject); +var + dlg: TfpgFileDialog; +begin + dlg := TfpgFileDialog.Create(nil); + try + if dlg.RunOpenFile then + begin + memEditor.Lines.LoadFromFile(dlg.FileName); + end; + finally + dlg.Free; + end; +end; -- cgit v1.2.3-70-g09d2