Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » TreeCtrl » SetFocus with EditString as Node
SetFocus with EditString as Node [message #40901] Sat, 05 October 2013 15:35 Go to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
This is simple edit node example (based on <a href=" http://www.ultimatepp.org/forum/index.php?t=msg&th=6380& amp;start=0&" target="_blank"></a>) with SetFocus problem when first "Add" button click:
class EditableTree : public TreeCtrl {
public:
	EditableTree() : selId_(-1) {
		editNode.SetCtrl(edit);
		OpenDeep(0, true);
	}
	
	void AddNode() {
		CloseEdit();
		
		int selId_ = Add(0);

   		edit.SetData("Node" + AsString(selId_));
   		edit.Show();
    	        edit.AutoSize();
		edit.SetFocus();//at first not select because IsOpen is false => why?

		SetNode(selId_, editNode);
	}
	
	void CloseEdit() {
		if (selId_ > 0) {
			SetNode(selId_, Node(~edit));
			edit.Hide();
		}
	}
	
private:
	int selId_;
    EditString edit;
   	TreeCtrl::Node editNode;
};

GUI_APP_MAIN
{	
	TopWindow wnd;
	Button btn;
	wnd.Add(btn.SetLabel("Add").LeftPos(10).TopPos(10));
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	btn <<= callback(&tree, &EditableTree::AddNode);
        wnd.Run();
}

[Updated on: Sat, 05 October 2013 15:35]

Report message to a moderator

Re: SetFocus with EditString as Node [message #40918 is a reply to message #40901] Mon, 07 October 2013 20:20 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
iST1 wrote on Sat, 05 October 2013 09:35

This is simple edit node example (based on <a href=" http://www.ultimatepp.org/forum/index.php?t=msg&th=6380& amp; amp;start=0&" target="_blank"></a>) with SetFocus problem when first "Add" button click:
class EditableTree : public TreeCtrl {
public:
	EditableTree() : selId_(-1) {
		editNode.SetCtrl(edit);
		OpenDeep(0, true);
	}
	
	void AddNode() {
		CloseEdit();
		
		int selId_ = Add(0);

   		edit.SetData("Node" + AsString(selId_));
   		edit.Show();
    	        edit.AutoSize();
		edit.SetFocus();//at first not select because IsOpen is false => why?

		SetNode(selId_, editNode);
	}
	
	void CloseEdit() {
		if (selId_ > 0) {
			SetNode(selId_, Node(~edit));
			edit.Hide();
		}
	}
	
private:
	int selId_;
    EditString edit;
   	TreeCtrl::Node editNode;
};

GUI_APP_MAIN
{	
	TopWindow wnd;
	Button btn;
	wnd.Add(btn.SetLabel("Add").LeftPos(10).TopPos(10));
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	btn <<= callback(&tree, &EditableTree::AddNode);
        wnd.Run();
}



Should be fixed, however you have to use SetFocus AFTER SetNode,
because only widget that is descendant of open window can have focus and until SetNode, edit is not assigned to any window. However, TreeCtrl still needed fixing to make it work...
Re: SetFocus with EditString as Node [message #41022 is a reply to message #40918] Mon, 21 October 2013 18:40 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
Now i set cursor at the end of EditString, but how to set it under mouse (on left click)? It is exist GetMousePos(), but no analogue found in EditString.

[Updated on: Mon, 21 October 2013 18:41]

Report message to a moderator

Re: SetFocus with EditString as Node [message #41034 is a reply to message #41022] Tue, 22 October 2013 19:34 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
iST1 wrote on Mon, 21 October 2013 12:40

Now i set cursor at the end of EditString, but how to set it under mouse (on left click)? It is exist GetMousePos(), but no analogue found in EditString.


I am not quite sure what you mean by that...
Re: SetFocus with EditString as Node [message #41037 is a reply to message #41034] Wed, 23 October 2013 08:38 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
I want to set EditString::SetSelection on mouse's position after left click (when we substituted a EditString instead Node).
Re: SetFocus with EditString as Node [message #41039 is a reply to message #41037] Wed, 23 October 2013 08:49 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Well, last original issue fixed - I mean there was a bit of moving of items when going up/down, this now fixed.

As for your mouse problem, I am afraid it is not so easy to fix. The easier way I can see is to send the EditString 'syntetic' LeftDown event, based on current GetMousePos and EditString's GetScreenView (GetMousePos() - GetScreenView().TopLeft() is the mouse pos in widget's view - same coordinates as used for LeftDown).

Anyway, I think the much easier approach is not to try to wrangle with the original design of TreeCtrl and provide EditString for each Node (and not single one for the whole thing). Sure, EditString will eat something like 512 byte and makes all slower, so if you are going after a lot of data, your approach makes sense.

Mirek
Re: SetFocus with EditString as Node [message #41070 is a reply to message #41039] Mon, 28 October 2013 17:58 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
I followed the advice to keep all EditString's in the tree nodes, but some error occur if WhenOpen used (select NODE1 -> add button click -> assertion failed)
class EditableTree : public TreeCtrl {
public:
	typedef EditableTree CLASSNAME;
		
	EditableTree() : selId_(0) {
		NoRoot().MultiSelect(true).HighlightCtrl(false);
		WhenSel = THISBACK(OnSelect);				
		WhenOpen = THISBACK1(ChangeNodeImg, true);
	}
	
	int AddNode(int parent) {
		EditString &edit = edit_.Add();
   		edit.SetData("NODE" + AsString(GetChildCount(0) + 1));
    	edit.AutoSize();
		edit.SetFrame(NullFrame());
	
		Node node;
		node.SetCtrl(edit);        
       	return Add(parent, node);       
	}
	
	void OnAddNode() {
		int id = AddNode(selId_);	        
		Open(selId_);
        SelectNode(id);
	}
	
	void SelectNode(int id) {
		ClearSelection();
		SelectOne(id);
		selId_ = GetSel()[0];
		ASSERT(selId_ == id);//failed
	}

	void OnSelect() {
		if (GetSelectCount() <= 0 || selId_ == GetSel()[0])
			return;
		
		selId_ = GetSel()[0];
	}
	
	void ChangeNodeImg(int selId, bool open) {
		if (!selId) 
			return;
	
		Node node = GetNode(selId);
		//...some image assignment
		
		SetNode(selId, node);//if comment => no ASSERT(selId_ == id); failed
	}
	
private:
	int selId_;
    Array<EditString> edit_;
};
 
GUI_APP_MAIN
{	
	TopWindow wnd;
	Button btn;
	wnd.Add(btn.SetLabel("Add").LeftPos(10).TopPos(10));
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	tree.AddNode(0);
	tree.AddNode(0);
	btn <<= callback(&tree, &EditableTree::OnAddNode);
    wnd.Run();
}
Re: SetFocus with EditString as Node [message #41082 is a reply to message #41070] Wed, 30 October 2013 09:46 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
This is because if any slave widget has focus, this one and only this one widget is selected. In other words, with widgets, you cannot really use SelectOne (perhaps I should add an ASSERT there).

I guess your code might get fixed it you used SetFocus or ActiveFocus instead of SelectOne...

Mirek
Re: SetFocus with EditString as Node [message #41104 is a reply to message #41082] Thu, 31 October 2013 15:06 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
Mirek, can you fixed this code? I have no idea
class EditableTree : public TreeCtrl {
public:
	typedef EditableTree CLASSNAME;
		
	EditableTree() : selId_(0) {
		NoRoot().MultiSelect(true).HighlightCtrl(false);
		WhenSel = THISBACK(OnSelect);				
	}
	
	int AddNode(int parent) {
		EditString &edit = edit_.Add(edit_.GetCount());
   		edit.SetData("NODE" + AsString(GetChildCount(parent) + 1));
    	edit.AutoSize();
		edit.SetFrame(NullFrame());
	
		Node node;
		node.SetCtrl(edit);        
       	return Add(parent, node);       
	}
	
	void OnAddNode() {
		int id = AddNode(selId_);	        
		Open(selId_);
		edit_.Get(edit_.GetCount() - 1).SetFocus();
	}

	void OnSelect() {
		if (GetSelectCount() <= 0 || selId_ == GetSel()[0])
			return;
		
		selId_ = GetSel()[0];
	}
	
private:
	int selId_;
    ArrayMap<int, EditString> edit_;
};
 
GUI_APP_MAIN
{	
	TopWindow wnd;
	Button btn;
	wnd.Add(btn.SetLabel("Add").LeftPos(10).TopPos(10));
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	tree.AddNode(0);
	tree.AddNode(0);
	btn <<= callback(&tree, &EditableTree::OnAddNode);
    wnd.Run();
}

[Updated on: Thu, 31 October 2013 15:07]

Report message to a moderator

Re: SetFocus with EditString as Node [message #41127 is a reply to message #41104] Sun, 03 November 2013 08:20 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
It's all the exact same problem with the Ctrl::IsOpen Sad
Re: SetFocus with EditString as Node [message #41128 is a reply to message #41127] Sun, 03 November 2013 10:05 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
Yet another fix should be added:
GUI_APP_MAIN
{	
	TreeCtrl tree;
	tree.MultiSelect(true);

	TopWindow wnd;
	wnd.Add(tree.SizePos());
	
	int id = tree.Add(0, TreeCtrl::Node("Node1"));
	tree.SelectOne(id, true);	
	ASSERT(tree.GetSel()[0] == id);
	
	//tree.SelectOne(id, false);//if comment => removed node stay selected and ASSERTION in (*) failed
	//tree.ClearSelection();//solution: ClearSelection must be added to the top of Remove method
	tree.Remove(id);	

	tree.Add(0, TreeCtrl::Node("Node2"));	
	
	id = tree.Add(0, TreeCtrl::Node("Node3"));	
	tree.SelectOne(id, true);	
	ASSERT(tree.GetSel()[0] == id);//(*)

	wnd.Run();
}
Re: SetFocus with EditString as Node [message #41148 is a reply to message #41128] Wed, 06 November 2013 16:36 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
And some one trouble
class EditableTree : public TreeCtrl {
public:
	typedef EditableTree CLASSNAME;
		
	EditableTree() : selId_(0) {
		NoRoot().MultiSelect(true).HighlightCtrl(false);
		WhenSel = THISBACK(OnSelect);				
	}
	
	bool Key(dword key, int count) {
		if (K_ENTER != key || selId_ <= 0) {
			return 1;
		}
		AddNode(0);
		Single<TopWindow>().Run();//=> ASSERTION: WindowProc invoked for class Upp::TopWindow while in Paint routine
	}

	int AddNode(int parent) {
		EditString &edit = edit_.Add(edit_.GetCount());
   		edit.SetData("NODE" + AsString(GetChildCount(parent) + 1));
    	edit.AutoSize();
		edit.SetFrame(NullFrame());
	
		Node node;
		node.SetCtrl(edit);        
       	return Add(parent, node);       
	}
	
	void OnSelect() {
		if (GetSelectCount() <= 0 || selId_ == GetSel()[0])
			return;
		
		selId_ = GetSel()[0];
	}
	
private:
    int selId_;
    ArrayMap<int, EditString> edit_;
};
 
GUI_APP_MAIN
{	
	TopWindow wnd;
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	tree.AddNode(0);
	tree.AddNode(0);
        wnd.Run();
}

[Updated on: Wed, 06 November 2013 16:37]

Report message to a moderator

Re: SetFocus with EditString as Node [message #41160 is a reply to message #41128] Thu, 07 November 2013 10:33 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
edit_.Get(edit_.GetCount() - 1)


is most likely wrong at the first sight...

You are retrieving Edit with key edit_.GetCount() - 1, which IMO is not what you wanted to do (see ArrayMap docs).

More coming...

Mirek
Re: SetFocus with EditString as Node [message #41161 is a reply to message #41160] Thu, 07 November 2013 15:58 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
I think this might do what you need:

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

class EditableTree : public TreeCtrl {
	Array<EditString> edits;

public:
	typedef EditableTree CLASSNAME;
		
	EditableTree() {
		NoRoot().HighlightCtrl(false);
	}

	int AddNode(int parent_id) {
		EditString& edit = edits.Add();
		edit.AutoSize().SetFrame(NullFrame());
		static int i;
		edit <<= "NODE" + AsString(GetChildCount(parent_id) + 1);
		return Add(parent_id, Null, edit);
	}
	
	void OnAddNode() {
		if(!IsCursor())
			return;
		SetCursor(AddNode(GetCursor()));
	}
};
 
GUI_APP_MAIN
{
	TopWindow wnd;

	Button btn;
	wnd.Add(btn.SetLabel("Add").LeftPos(10).TopPos(10));
	Button btn2;
	wnd.Add(btn2.SetLabel("Show").LeftPos(100).TopPos(10));
	
	EditableTree tree;
	wnd.Add(tree.VSizePos(40).HSizePos());

	tree.AddNode(0);
	tree.AddNode(0);
	btn <<= callback(&tree, &EditableTree::OnAddNode);
    wnd.Run();
}


I apologize for delay - I had to fix some subtle focus issues in TreeCtrl for this particular mode of operation... (so you need latest sources for it to work correctly).

Mirek
icon14.gif  Re: SetFocus with EditString as Node [message #41162 is a reply to message #41161] Thu, 07 November 2013 18:38 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
Thank you very much!
There is another moment: in my old code MultiSelect(true) is used to set cursor in the end of EditString:
 edit.SetSelection(AsString(~edit).GetCount());
when node selecting (WhenSel callback). The example before whit MultiSelect(true) doesn't work correctly. It is easy to solve? PS: ideally when user clicked mouse selId_ value must be set, whereupon we can do everything whit appropriate node.

[Updated on: Thu, 07 November 2013 18:44]

Report message to a moderator

Re: SetFocus with EditString as Node [message #41165 is a reply to message #41162] Fri, 08 November 2013 07:58 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
iST1 wrote on Thu, 07 November 2013 12:38

Thank you very much!
There is another moment: in my old code MultiSelect(true) is used to set cursor in the end of EditString:
 edit.SetSelection(AsString(~edit).GetCount());
when node selecting (WhenSel callback). The example before whit MultiSelect(true) doesn't work correctly. It is easy to solve? PS: ideally when user clicked mouse selId_ value must be set, whereupon we can do everything whit appropriate node.


MultiSelect is option that makes possible to select more than one node (Ctrl+Mouse). It is inherently incompatible with your case.

WhenSel is called always when selection changes, that includes normal cursor moves too. Also, no need to store selID_ separately, GetCursor should be valid always.

What do your really need to achieve?

Mirek
Re: SetFocus with EditString as Node [message #41170 is a reply to message #41165] Fri, 08 November 2013 11:14 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
For example, if you select a node I need to change the font, so is need to catch the appropriate event.
Re: SetFocus with EditString as Node [message #41171 is a reply to message #41170] Fri, 08 November 2013 11:26 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
iST1 wrote on Fri, 08 November 2013 05:14

For example, if you select a node I need to change the font, so is need to catch the appropriate event.


And what is stopping you?

Mirek
Re: SetFocus with EditString as Node [message #41173 is a reply to message #41171] Fri, 08 November 2013 11:40 Go to previous messageGo to next message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
WhenSel when Multiselect is false not work in your example
Re: SetFocus with EditString as Node [message #41178 is a reply to message #41173] Fri, 08 November 2013 17:46 Go to previous messageGo to previous message
iST1 is currently offline  iST1
Messages: 107
Registered: August 2013
Experienced Member
UDP: small fixes to illustrate trouble
 class EditableTree : public TreeCtrl {
	Array<EditString> edits;

public:
	typedef EditableTree CLASSNAME;
		
	EditableTree() : selId_(0) {
		NoRoot().HighlightCtrl(false);
		WhenSel = THISBACK(OnSelect);				
	}

	void OnSelect() {
		selId_ = GetCursor();//not called
                //..some node view preparing
	}
	
	int AddNode(int parent_id) {
		EditString& edit = edits.Add();
		edit.AutoSize().SetFrame(NullFrame());
		
		edit <<= "NODE" + AsString(GetChildCount(parent_id) + 1);
		return Add(parent_id, Null, edit);
	}
	
	void OnAddNode() {
		if (!IsCursor())
			return;
		
		SetCursor(AddNode(selId_));
	}

private:
	int selId_;
};

[Updated on: Mon, 11 November 2013 09:35]

Report message to a moderator

Previous Topic: Hide expand/collapse ico
Next Topic: Node id calculation after removal ?
Goto Forum:
  


Current Time: Thu Mar 28 16:08:36 CET 2024

Total time taken to generate the page: 0.02217 seconds