TreeCtrl now supports edit on click - WhenEdited

git-svn-id: svn://ultimatepp.org/upp/trunk@15316 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2020-10-28 14:24:31 +00:00
parent fd9ddb6560
commit 182275359b
5 changed files with 116 additions and 6 deletions

View file

@ -88,6 +88,8 @@ private:
bool DnDInsert(int i, int py, PasteClip& d, int q);
void DnD(int _drop, bool _insert);
friend class FileList;
public:
enum {

View file

@ -162,10 +162,11 @@ void FileList::StartEdit() {
edit.SetFocus();
int pos = int(GetFileExtPos(cf.name) - ~cf.name);
edit.SetSelection(0, pos);
sb.Disable();
}
void FileList::EndEdit() {
KillTimeCallback(TIMEID_STARTEDIT);
KillEdit();
int b = edit.HasFocus();
edit.Hide();
if(b) SetFocus();
@ -180,6 +181,7 @@ void FileList::OkEdit() {
void FileList::KillEdit()
{
sb.Enable();
KillTimeCallback(TIMEID_STARTEDIT);
}
@ -191,7 +193,7 @@ void FileList::LeftDown(Point p, dword flags) {
}
ColumnList::LeftDown(p, flags);
KillEdit();
if(c == GetCursor() && c >= 0 && !HasCapture() && renaming && !(flags & (K_SHIFT|K_CTRL)))
if(c == GetCursor() && c >= 0 && !HasCapture() && renaming && WhenRename && !(flags & (K_SHIFT|K_CTRL)))
SetTimeCallback(750, THISBACK(StartEdit), TIMEID_STARTEDIT);
}

View file

@ -471,6 +471,7 @@ void TreeCtrl::SyncTree(bool immediate)
SyncAfterSync(restorefocus);
else
PostCallback(PTEBACK1(SyncAfterSync, restorefocus));
KillEdit();
}
void TreeCtrl::SyncCtrls(bool add, Ctrl *restorefocus)
@ -839,6 +840,18 @@ void TreeCtrl::LeftDrag(Point p, dword keyflags)
WhenDrag();
}
Rect TreeCtrl::GetValueRect(const Line& l) const
{
const Item& m = item[l.itemi];
Size msz = m.GetSize(display);
Size isz = m.image.GetSize();
Size vsz = m.GetValueSize(display);
Point org = sb;
return RectC(levelcx + l.level * levelcx + isz.cx - org.x + m.margin,
l.y - org.y + (msz.cy - vsz.cy) / 2,
vsz.cx, vsz.cy);
}
void TreeCtrl::DoClick(Point p, dword flags, bool down)
{
Point org = sb;
@ -864,6 +877,11 @@ void TreeCtrl::DoClick(Point p, dword flags, bool down)
}
SetWantFocus();
int q = cursor;
int qq = q;
if(IsEdit()) {
OkEdit();
qq = -1;
}
SetCursorLine(i, true, false, true);
if(multiselect) {
int id = GetCursor();
@ -880,15 +898,63 @@ void TreeCtrl::DoClick(Point p, dword flags, bool down)
anchor = cursor;
}
}
if(cursor != q) {
if(cursor != q)
WhenAction();
}
if(down)
WhenLeftClick();
Select();
KillEdit();
if(cursor == qq && qq >= 0 && !HasCapture() && WhenEdited && !(flags & (K_SHIFT|K_CTRL)) &&
GetValueRect(l).Contains(p))
SetTimeCallback(750, [=] { StartEdit(); }, TIMEID_STARTEDIT);
}
}
void TreeCtrl::KillEdit()
{
sb.x.Enable();
sb.y.Enable();
KillTimeCallback(TIMEID_STARTEDIT);
}
void TreeCtrl::StartEdit() {
if(cursor < 0) return;
if(!editor) {
edit_string.Create();
editor = ~edit_string;
}
AddChild(editor);
const Line& l = line[cursor];
const Item& m = item[l.itemi];
Rect r = GetValueRect(l);
r.Inflate(2);
editor->SetFrame(BlackFrame());
r.right = GetSize().cx;
editor->SetRect(r);
*editor <<= m.value;
editor->Show();
editor->SetFocus();
sb.x.Disable();
sb.y.Disable();
}
void TreeCtrl::EndEdit() {
KillEdit();
if(editor) {
int b = editor->HasFocus();
editor->Hide();
if(b) SetFocus();
}
}
void TreeCtrl::OkEdit() {
EndEdit();
int c = GetCursor();
if(c >= 0 && editor)
WhenEdited(~*editor);
}
void TreeCtrl::SyncInfo()
{
if(IsShutdown() || IsPainting())
@ -1180,7 +1246,14 @@ bool TreeCtrl::Key(dword key, int)
key &= ~K_SHIFT;
switch(key) {
case K_ENTER:
Select();
if(IsEdit())
OkEdit();
else
Select();
break;
case K_ESCAPE:
if(IsEdit())
EndEdit();
break;
case K_TAB:
return Tab(1);

View file

@ -122,6 +122,9 @@ private:
struct LineLess {
bool operator()(int y, const Line& l) const { return y < l.y; }
};
One<EditString> edit_string;
Ctrl *editor = NULL;
struct SortOrder;
@ -157,6 +160,17 @@ private:
void DoClick(Point p, dword flags, bool down);
void SyncInfo();
void SyncAfterSync(Ptr<Ctrl> restorefocus);
Rect GetValueRect(const Line& l) const;
void StartEdit();
void EndEdit();
void KillEdit();
bool IsEdit() const { return editor && editor->IsVisible(); }
void OkEdit();
enum {
TIMEID_STARTEDIT = Ctrl::TIMEID_COUNT,
TIMEID_COUNT
};
using Ctrl::Close;
@ -179,6 +193,8 @@ public:
Event<int, PasteClip&> WhenDropItem;
Event<int, int, PasteClip&> WhenDropInsert;
Event<PasteClip&> WhenDrop;
Event<const Value&> WhenEdited;
// deprecated - use WhenSel
Event<> WhenCursor;
@ -322,6 +338,7 @@ public:
TreeCtrl& HighlightCtrl(bool a = true) { highlight_ctrl = a; Refresh(); return *this; }
TreeCtrl& RenderMultiRoot(bool a = true) { multiroot = a; Refresh(); return *this; }
TreeCtrl& EmptyNodeIcon(const Image& a) { imgEmpty = a; Refresh(); return *this; }
TreeCtrl& Editor(Ctrl& e) { editor = &e; return *this; }
TreeCtrl& SetScrollBarStyle(const ScrollBar::Style& s) { sb.SetStyle(s); return *this; }

View file

@ -1,5 +1,4 @@
topic "TreeCtrl";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,0#27521748481378242620020725143825:desc]
[0 $$3,0#96390100711032703541132217272105:end]
@ -9,6 +8,7 @@ topic "TreeCtrl";
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[2 $$0,0#00000000000000000000000000000000:Default]
[{_}
[ {{10000@3 [s0; [*@(229)4 TreeCtrl]]}}&]
[s3;%% &]
@ -84,6 +84,17 @@ do not apply `- drop into empty area. See [^PasteClip^ PasteClip]
for more details.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:TreeCtrl`:`:WhenEdited: [_^Upp`:`:Event^ Event]<[@(0.0.255) const]_Value[@(0.0.255) `&
]>_[* WhenEdited]&]
[s2;%% When defined, TreeCtrl will start editing the node value when
clicked on already select one (after a while) in a way similar
to e.g. FileSel file renaming. When the value is accepted, WhenEdit
is called with a new value. Value is not changed in TreeCtrl,
if that is desired, it is a responsibility of code that is assigned
to the WhenEdited. Default editor is EditString and can be changed
with Editor modifier method.&]
[s3; &]
[s4; &]
[s5;:TreeCtrl`:`:WhenCursor: [_^Callback^ Callback]_[* WhenCursor]&]
[s2;%% Cursor has changed (including KillCursor). Deprecated.&]
[s3; &]
@ -602,6 +613,11 @@ level and has not elements, [%-*@3 a] is drawn on the left side
to indicate it is empty.&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:TreeCtrl`:`:Editor`(Upp`:`:Ctrl`&`): [_^Upp`:`:TreeCtrl^ TreeCtrl][@(0.0.255) `&
]_[* Editor]([_^Upp`:`:Ctrl^ Ctrl][@(0.0.255) `&]_[*@3 e])&]
[s2;%% Assigns alternative editor for WhenEdited functionality.&]
[s3;%% &]
[s4; &]
[s5;:TreeCtrl`:`:SetScrollBarStyle`(const ScrollBar`:`:Style`&`): [_^TreeCtrl^ TreeCtrl
][@(0.0.255) `&]_[* SetScrollBarStyle]([@(0.0.255) const]_[_^ScrollBar`:`:Style^ ScrollBa
r`::Style][@(0.0.255) `&]_[*@3 s])&]