diff options
author | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2010-08-18 17:18:40 +0200 |
---|---|---|
committer | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2010-08-18 17:18:40 +0200 |
commit | d40bbb2a271d48d10b95ba5a375df7db2484afa6 (patch) | |
tree | 5fa965c2615ae9cf2da0835176972345ebad64bf | |
parent | 801b16d29756a1c686c502e6d1988b6d5c51db71 (diff) | |
download | fpGUI-d40bbb2a271d48d10b95ba5a375df7db2484afa6.tar.xz |
UI Designer: Reworked the "Tab Order" and "Widget Order" dialog with a Treeview
* Original dialog used to use a ListBox with indentation
* Many reordering bugs in old design is now fixed in the new one.
Note:
Still outstanding is the sorting of the nodes by TabOrder when
using the "Tab Order" dialog mode.
-rw-r--r-- | uidesigner/uidesigner.lpr | 2 | ||||
-rw-r--r-- | uidesigner/vfddesigner.pas | 157 | ||||
-rw-r--r-- | uidesigner/vfdforms.pas | 147 | ||||
-rw-r--r-- | uidesigner/vfdmain.pas | 4 |
4 files changed, 106 insertions, 204 deletions
diff --git a/uidesigner/uidesigner.lpr b/uidesigner/uidesigner.lpr index 9f0a715f..a7fa44e5 100644 --- a/uidesigner/uidesigner.lpr +++ b/uidesigner/uidesigner.lpr @@ -1,7 +1,7 @@ { fpGUI - Free Pascal GUI Library - Copyright (C) 2006 - 2008 See the file AUTHORS.txt, included in this + Copyright (C) 2006 - 2010 See the file AUTHORS.txt, included in this distribution, for details of the copyright. See the file COPYING.modifiedLGPL, included in this distribution, diff --git a/uidesigner/vfddesigner.pas b/uidesigner/vfddesigner.pas index 5405b9bb..b55bc475 100644 --- a/uidesigner/vfddesigner.pas +++ b/uidesigner/vfddesigner.pas @@ -43,6 +43,8 @@ uses type + TfpgEditMode = (emWidgetOrder, emTabOrder); + TOtherWidget = class(TfpgWidget) protected FFont: TfpgFont; @@ -116,8 +118,7 @@ type procedure SelectNextWidget(fw: boolean); procedure MoveResizeWidgets(dx, dy, dw, dh: integer); procedure DeleteWidgets; - procedure EditWidgetOrder; - procedure EditTabOrder; + procedure EditWidgetOrTabOrder(AMode: TfpgEditMode); procedure InsertWidget(pwg: TfpgWidget; x, y: integer; wgc: TVFDWidgetClass); procedure UpdatePropWin; procedure OnPropTextChange(Sender: TObject); @@ -142,8 +143,12 @@ implementation uses vfdmain, - TypInfo; + TypInfo, + fpg_tree; +const + cEditOrder: array[TfpgEditMode] of string = ('Widget Order', 'Tab Order'); + { TWidgetDesigner } @@ -636,134 +641,80 @@ begin end; -procedure TFormDesigner.EditWidgetOrder; +procedure TFormDesigner.EditWidgetOrTabOrder(AMode: TfpgEditMode); var frm: TWidgetOrderForm; n, fi: integer; cd: TWidgetDesigner; identlevel: integer; + lFocused: TfpgTreeNode; + lNode: TfpgTreeNode; + s: string; - procedure AddChildWidgets(pwg: TfpgWidget; slist: TStrings); + procedure AddChildWidgets(AParent: TfpgWidget; ATreeNode: TfpgTreeNode); var f: integer; fcd: TWidgetDesigner; + lNode: TfpgTreeNode; begin - for f := 0 to FWidgets.Count - 1 do + for f := 0 to FWidgets.Count-1 do begin fcd := TWidgetDesigner(FWidgets.Items[f]); - - if fcd.Widget.Parent = pwg then + if fcd.Widget.Parent = AParent then begin - frm.list.Items.AddObject(StringOfChar(' ', identlevel) + fcd.Widget.Name + ' : ' + fcd.Widget.ClassName, fcd); - Inc(identlevel); - AddChildWidgets(fcd.Widget, slist); - Dec(identlevel); + if AMode = emTabOrder then + s := ' (' + IntToStr(fcd.Widget.TabOrder) + ')' + else + s := ''; + lNode := ATreeNode.AppendText(fcd.Widget.Name + ': ' + fcd.Widget.ClassName + s); + lNode.Data := fcd; + if fcd.Selected then + lFocused := lNode; + AddChildWidgets(fcd.Widget, lNode); end; - - if fcd.Selected then - fi := f + 1; end; end; - + begin frm := TWidgetOrderForm.Create(nil); - fi := 1; + frm.WindowTitle := cEditOrder[AMode]; + frm.lblTitle.Text := Format(frm.lblTitle.Text, [cEditOrder[AMode]]); + fi := 0; identlevel := 0; + frm.Treeview1.RootNode.Clear; + lFocused := nil; - AddChildWidgets(FForm, frm.list.Items); - - if fi <= frm.list.ItemCount then - frm.list.FocusItem := fi; + AddChildWidgets(FForm, frm.Treeview1.RootNode); + frm.Treeview1.FullExpand; + if lFocused <> nil then + frm.Treeview1.Selection := lFocused + else + frm.Treeview1.Selection := frm.Treeview1.Rootnode.FirstSubNode; + frm.Treeview1.SetFocus; + if frm.ShowModal = mrOK then begin - for n := 0 to FWidgets.Count - 1 do - TWidgetDesigner(FWidgets.Items[n]).Widget.Visible := False; - - for n := 0 to FWidgets.Count - 1 do - FWidgets.Items[n] := frm.List.Items.Objects[n]; - - for n := 0 to FWidgets.Count - 1 do + n := 0; + lNode := frm.Treeview1.NextNode(frm.Treeview1.RootNode); + while lNode <> nil do begin - cd := TWidgetDesigner(FWidgets.Items[n]); - cd.Widget.Visible := True; - end; - - for n := 0 to FWidgets.Count - 1 do - begin - cd := TWidgetDesigner(FWidgets.Items[n]); - if cd.Selected then + if AMode = emWidgetOrder then begin - // re-creating the resizers - cd.Selected := False; - cd.Selected := True; - end; - end; - - end; - frm.Free; -end; - -procedure TFormDesigner.EditTabOrder; -const - cDivider = ' : '; -var - frm: TWidgetOrderForm; - n, fi: integer; - identlevel: integer; - taborder: integer; - - procedure AddChildWidgets(pwg: TfpgWidget; slist: TStrings); - var - f: integer; - fcd: TWidgetDesigner; - begin - for f := 0 to FWidgets.Count - 1 do - begin - fcd := TWidgetDesigner(FWidgets.Items[f]); - - if fcd.Widget.Parent = pwg then + FWidgets.Items[n] := lNode.Data; + end + else if AMode = emTabOrder then begin - frm.list.Items.AddObject(StringOfChar(' ', identlevel) + fcd.Widget.Name + cDivider + fcd.Widget.ClassName, fcd); - Inc(identlevel, 2); - AddChildWidgets(fcd.Widget, slist); - Dec(identlevel, 2); + if IsPublishedProp(TWidgetDesigner(lNode.Data).Widget, 'TabOrder') then + begin + TWidgetDesigner(lNode.Data).Widget.TabOrder := n; + end; end; - - if fcd.Selected then - fi := f + 1; + lNode := frm.Treeview1.NextNode(lNode); + n := n + 1; end; - end; - -begin - frm := TWidgetOrderForm.Create(nil); - frm.WindowTitle := 'Tab Order'; - fi := 1; - identlevel := 0; - - AddChildWidgets(FForm, frm.list.Items); - - if fi <= frm.list.ItemCount then - frm.list.FocusItem := fi; - - if frm.ShowModal = mrOK then - begin - taborder := 1; - for n := 0 to frm.List.Items.Count - 1 do - begin - try - if IsPublishedProp(TWidgetDesigner(frm.List.Items.Objects[n]).Widget, 'TabOrder') then - begin -// SetPropValue(TWidgetDesigner(frm.List.Items.Objects[n]).Widget, 'TabOrder', taborder); - TWidgetDesigner(frm.List.Items.Objects[n]).Widget.TabOrder := taborder; - inc(taborder); - end; - except - // do nothing. TabOrder was not published - end; - end; - end; { if } + end; { if } frm.Free; end; @@ -799,7 +750,7 @@ begin 'F4: edit items' + LineEnding}, 'Small help'); keyF2: - EditWidgetOrder; + EditWidgetOrTabOrder(emTabOrder); //keyF4: //if frmProperties.btnEdit.Visible then diff --git a/uidesigner/vfdforms.pas b/uidesigner/vfdforms.pas index ec60265d..626c9cad 100644 --- a/uidesigner/vfdforms.pas +++ b/uidesigner/vfdforms.pas @@ -30,11 +30,11 @@ uses fpg_label, fpg_edit, fpg_button, - fpg_listbox, fpg_combobox, fpg_trackbar, fpg_checkbox, - fpg_panel; + fpg_panel, + fpg_tree; type @@ -83,17 +83,17 @@ type procedure AfterCreate; override; procedure OnButtonClick(Sender: TObject); end; - + TWidgetOrderForm = class(TVFDDialog) public {@VFD_HEAD_BEGIN: WidgetOrderForm} - l1: TfpgLabel; - list: TfpgListBox; + lblTitle: TfpgLabel; btnOK: TfpgButton; btnCancel: TfpgButton; btnUp: TfpgButton; btnDown: TfpgButton; + TreeView1: TfpgTreeView; {@VFD_HEAD_END: WidgetOrderForm} constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -254,67 +254,54 @@ begin inherited AfterCreate; {@VFD_BODY_BEGIN: WidgetOrderForm} Name := 'WidgetOrderForm'; - SetPosition(534, 173, 312, 258); + SetPosition(534, 173, 426, 398); WindowTitle := 'Widget order'; Hint := ''; WindowPosition := wpScreenCenter; - l1 := TfpgLabel.Create(self); - with l1 do + lblTitle := TfpgLabel.Create(self); + with lblTitle do begin - Name := 'l1'; - SetPosition(4, 4, 108, 16); + Name := 'lblTitle'; + SetPosition(4, 4, 248, 16); FontDesc := '#Label1'; Hint := ''; - Text := 'Form widget order:'; - end; - - list := TfpgListBox.Create(self); - with list do - begin - Name := 'list'; - SetPosition(4, 24, 220, 228); - Anchors := [anLeft,anRight,anTop,anBottom]; - FontDesc := '#List'; - Hint := ''; - HotTrack := False; - PopupFrame := False; - TabOrder := 1; + Text := 'Form %s:'; end; btnOK := TfpgButton.Create(self); with btnOK do begin Name := 'btnOK'; - SetPosition(232, 24, 75, 24); + SetPosition(346, 24, 75, 24); Anchors := [anRight,anTop]; Text := 'OK'; FontDesc := '#Label1'; Hint := ''; ImageName := 'stdimg.ok'; + ModalResult := mrOK; TabOrder := 2; - OnClick := @OnButtonClick; end; btnCancel := TfpgButton.Create(self); with btnCancel do begin Name := 'btnCancel'; - SetPosition(232, 52, 75, 24); + SetPosition(346, 52, 75, 24); Anchors := [anRight,anTop]; Text := 'Cancel'; FontDesc := '#Label1'; Hint := ''; ImageName := 'stdimg.cancel'; + ModalResult := mrCancel; TabOrder := 3; - OnClick := @OnButtonClick; end; btnUp := TfpgButton.Create(self); with btnUp do begin Name := 'btnUp'; - SetPosition(232, 108, 75, 24); + SetPosition(346, 108, 75, 24); Anchors := [anRight,anTop]; Text := 'Up'; FontDesc := '#Label1'; @@ -328,7 +315,7 @@ begin with btnDown do begin Name := 'btnDown'; - SetPosition(232, 136, 75, 24); + SetPosition(346, 136, 75, 24); Anchors := [anRight,anTop]; Text := 'Down'; FontDesc := '#Label1'; @@ -338,82 +325,45 @@ begin OnClick := @OnButtonClick; end; + TreeView1 := TfpgTreeView.Create(self); + with TreeView1 do + begin + Name := 'TreeView1'; + SetPosition(4, 24, 336, 368); + Anchors := [anLeft,anRight,anTop,anBottom]; + FontDesc := '#Label1'; + Hint := ''; + TabOrder := 7; + end; + {@VFD_BODY_END: WidgetOrderForm} end; procedure TWidgetOrderForm.OnButtonClick(Sender: TObject); var - i: integer; - n: integer; - myilev: integer; - - function IdentLevel(astr: string): integer; - var - s: string; - f: integer; - begin - Result := 0; - s := astr; - f := 1; - while (f <= length(s)) and (s[f] = ' ') do - begin - Inc(Result); - Inc(f); - end; - end; - + lNode: TfpgTreeNode; begin - if Sender = btnOK then - ModalResult := mrOK - else if Sender = btnCancel then - ModalResult := mrCancel - else + lNode := Treeview1.Selection; + if lNode = nil then + exit; + + if Sender = btnUp then begin - // up / down - i := list.FocusItem; - if i < 0 then - Exit; - - myilev := IdentLevel(list.Items[i]); - - if Sender = btnUP then - begin - if (i > 0) and (IdentLevel(list.Items[i - 1]) = myilev) then - begin - list.Items.Move(i, i - 1); - - n := i; - while (n < list.Items.Count) and (IdentLevel(list.Items[n]) > myilev) do - begin - list.Items.Move(n, n - 1); - Inc(n); - end; - - list.FocusItem := i - 1; - end; - end - else if Sender = btnDOWN then - if (i < list.Items.Count-1) then - begin - n := i; - while (n < list.Items.Count) and (IdentLevel(list.Items[n]) > myilev) do - Inc(n); - - if (i = n) and (i < list.Items.Count-1) and (IdentLevel(list.Items[i]) > myilev) then - Exit; - - if (n > list.Items.Count-1) then - Exit; //==> - - while (n >= i) do - begin - list.Items.Move(n, n + 1); - Dec(n); - end; - - list.FocusItem := i + 1; - end; + if lNode.Prev = nil then + exit; // nothing to do + lNode.MoveTo(lNode.Prev, naInsert); + end + else + begin // btnDown + if (lNode.Next = nil) then + exit; // nothing to do + if (lNode.Next.Next = nil) then // the last node doesn't have a next + lNode.MoveTo(lNode.Next, naAdd) + else + lNode.MoveTo(lNode.Next.Next, naInsert); end; + + Treeview1.Invalidate; end; { TVFDDialogBase } @@ -575,6 +525,7 @@ begin begin Name := 'edtDefaultExt'; SetPosition(28, 216, 68, 24); + ExtraHint := ''; Hint := ''; TabOrder := 5; Text := ''; diff --git a/uidesigner/vfdmain.pas b/uidesigner/vfdmain.pas index a6b8f0b2..234b40df 100644 --- a/uidesigner/vfdmain.pas +++ b/uidesigner/vfdmain.pas @@ -392,13 +392,13 @@ end; procedure TMainDesigner.OnEditWidgetOrder(Sender: TObject); begin if SelectedForm <> nil then - SelectedForm.EditWidgetOrder; + SelectedForm.EditWidgetOrTabOrder(emWidgetOrder); end; procedure TMainDesigner.OnEditTabOrder(Sender: TObject); begin if SelectedForm <> nil then - SelectedForm.EditTabOrder; + SelectedForm.EditWidgetOrTabOrder(emTabOrder); end; procedure TMainDesigner.OnExit(Sender: TObject); |