|
|
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » Howto create control-collection -control? [SOLVED -good example]
Howto create control-collection -control? [SOLVED -good example] [message #1519] |
Tue, 07 March 2006 22:45 |
wilho
Messages: 19 Registered: February 2006
|
Promising Member |
|
|
Hi!
Edit: this was a way too hasty question now slowly becoming tutorial it seems I'm creating simple control by combining splitter, button and user defined control. Couple of these SplitterButtons could create something like there's in outlook's left pane. So here's what I got so far:
class SplitterButton : public ParentCtrl{
Splitter splitter;
Button button;
typedef SplitterButton CLASSNAME;
public:
SplitterButton();
void Vert(Ctrl&);
void Toggle();
void SplitterButton::SetSplitPos(int);
};
SplitterButton::SplitterButton(){
button <<= THISBACK(Toggle);
Add(splitter);
}
void SplitterButton::Vert(Ctrl& ctrl){
splitter.Vert(ctrl, button);
}
void SplitterButton::Toggle(){
splitter.Zoom(splitter.GetZoom() == 1 ? -1 : 1);
//todo:resize code
}
void SplitterButton::SetSplitPos(int newpos){
splitter.SetPos(newpos);
}
Next thing is to create code for the control to resize itself...I suppose that there's no way link controls position into another one, so I have to move other controls out of the way and back by hand?
If you think this is wrong approach or here's something wrong, feel free to open up. I'll be back.
[Updated on: Sun, 09 April 2006 04:08] by Moderator Report message to a moderator
|
|
|
|
|
|
Re: Howto create control-collection -control? [message #1657 is a reply to message #1655] |
Sat, 11 March 2006 19:33 |
wilho
Messages: 19 Registered: February 2006
|
Promising Member |
|
|
Thanks for the tips. I'll have some ultimizing to do.
luzr wrote on Sat, 11 March 2006 12:43 |
Well, a What is "dummy" class for?
|
It shouldn't change a thing shouldn't it? But anyway, if I removed it, the toggle buttons just didn't appear and I don't know why... I made new separate cpp/h -files for the classes, derived SButtons class from ParentCtrl as you suggested, and now it works fine without it. And please, don't think I've lost my marbles, I retested this couple of times
luzr wrote on Sat, 11 March 2006 12:43 |
Why Empty layout?
|
I bet I once had a good reason for this...
luzr wrote on Sat, 11 March 2006 12:43 | Well, a What is
The important part is that Rearrange should reset the splitter and add all subpanes again. And both Add and CloseButton should call Rearrange....
|
I was pondering if I'm going to do this or not, I will if this seems messy in actual context.
|
|
|
|
Re: Howto create control-collection -control? [message #1663 is a reply to message #1519] |
Sun, 12 March 2006 11:25 |
wilho
Messages: 19 Registered: February 2006
|
Promising Member |
|
|
OK, you convinced me.
class ExpressPane : public Ctrl {
struct SlaveControl {
bool isInSplitter;
Ctrl* slave;
};
Array<Button> closer;
Array<SlaveControl> slaves;
Splitter splitter;
static const int BTN_SPACE = 22;
typedef ExpressPane CLASSNAME;
int btnIndx;
void Toggle(int);
public:
void Add(const char *text, Ctrl& slave);
ExpressPane();
};
ExpressPane::ExpressPane(){
Ctrl::Add(splitter);
splitter.Vert();
}
void ExpressPane::Toggle(int indx){
slaves[indx].isInSplitter = slaves[indx].isInSplitter == true ? false:true;
for(int loopI=slaves.GetCount()-1; loopI>-1; loopI--){
splitter.RemoveChild( slaves[loopI].slave );
if (slaves[loopI].isInSplitter == true){
splitter << *slaves[loopI].slave;
}
}
splitter.RefreshLayout();
}
void ExpressPane::Add(const char *text, Ctrl& slave){
Button* button = new Button;
Callback argCB = callback1(this,Toggle, btnIndx++);
*button <<= argCB;
button->SetLabel(text);
button->HSizePosZ(0, 0).BottomPosZ(BTN_SPACE * (btnIndx-1), BTN_SPACE -2);
splitter.HSizePosZ(0, 0).VSizePosZ(0, BTN_SPACE * btnIndx);
Ctrl::Add(*button);
closer.Add(button);
SlaveControl slvCtrl;
slvCtrl.isInSplitter = false;
slvCtrl.slave = &slave;
slaves.Add(slvCtrl);
}
Thank you, this has ben very...educational
[Updated on: Sun, 12 March 2006 11:26] Report message to a moderator
|
|
|
Re: Howto create control-collection -control? [message #1666 is a reply to message #1663] |
Sun, 12 March 2006 12:47 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
Callback argCB = callback1(this,Toggle, btnIndx++);
usually, we now prefer to place
typedef ExpressPane CLASSNAME;
inside ExpressPane declaration and then
Callback argCB = THISBACK1(Toggle, btnIndx++);
(pays off if you are about to assing more callbacks.
Avoid btnIndex, use "closer.GetCount()".
Also, avoid "new":
Button& button = closer.Add();
means:
void ExpressPane::Add(const char *text, Ctrl& slave){
int btnIndx = closer.GetCount();
Button& button = closer.Add();
button <<= THISBACK1(Toggle, btnIndx);
button.SetLabel(text);
button.HSizePosZ(0, 0).BottomPosZ(BTN_SPACE * (btnIndx-1), BTN_SPACE -2);
splitter.HSizePosZ(0, 0).VSizePosZ(0, BTN_SPACE * btnIndx);
Ctrl::Add(button);
SlaveControl& slvCtrl = slaves.Add();
slvCtrl.isInSplitter = false;
slvCtrl.slave = &slave;
}
Even more optimal would be to place Button inside SlaveControl and manage just a single array...
(I am still missing Rearrange, just toying with the code as it is)
Mirek
[Updated on: Sun, 12 March 2006 12:50] Report message to a moderator
|
|
|
Re: Howto create control-collection -control? [message #1684 is a reply to message #1663] |
Mon, 13 March 2006 20:42 |
wilho
Messages: 19 Registered: February 2006
|
Promising Member |
|
|
Ok, here we go again:
class DblClckBtn : public Button {
public:
Callback WhenLeftDouble;
virtual void DblClckBtn::LeftDouble(Point, dword);
};
class ExpressPane : public Ctrl {
struct SlaveControl {
bool isInSplitter;
DblClckBtn button;
Ctrl* slave;
};
Array<SlaveControl> slaves;
Splitter splitter;
static const int BTN_SPACE = 22;
typedef ExpressPane CLASSNAME;
void Toggle(int);
void OpenOne(int);
public:
void Add(const char *text, Ctrl& slave);
void Rearrange();
ExpressPane();
};
void DblClckBtn::LeftDouble(Point p, dword) {
if(IsReadOnly()) return;
WhenLeftDouble();
}
ExpressPane::ExpressPane(){
Ctrl::Add(splitter);
splitter.Vert();
}
void ExpressPane::OpenOne(int indx){
for(int loopI=slaves.GetCount()-1; loopI>-1; loopI--){
slaves[loopI].isInSplitter = false;
}
slaves[indx].isInSplitter = true;
Rearrange();
}
void ExpressPane::Toggle(int indx){
slaves[indx].isInSplitter = !slaves[indx].isInSplitter;
Rearrange();
}
void ExpressPane::Rearrange(){
for(int loopI=slaves.GetCount()-1; loopI>-1; loopI--){
splitter.RemoveChild( slaves[loopI].slave );
if (slaves[loopI].isInSplitter == true){
splitter << *slaves[loopI].slave;
}
}
splitter.RefreshLayout();
}
void ExpressPane::Add(const char *text, Ctrl& slave){
SlaveControl& slvCtrl = slaves.Add();
int btnIndx = slaves.GetCount()-1;
slvCtrl.button <<= THISBACK1(Toggle,btnIndx);
slvCtrl.button.WhenLeftDouble << THISBACK1(OpenOne,btnIndx);
slvCtrl.button.SetLabel(text);
slvCtrl.button.HSizePosZ(0, 0).BottomPosZ(BTN_SPACE * (btnIndx), BTN_SPACE -2);
slvCtrl.isInSplitter = false;
slvCtrl.slave = &slave;
splitter.HSizePosZ(0, 0).VSizePosZ(0, BTN_SPACE * (btnIndx+1));
Ctrl::Add(slvCtrl.button);
}
Here's rearrange and some use for it in form double-click feature. And I finally got the !visible hint
[Updated on: Mon, 13 March 2006 20:46] Report message to a moderator
|
|
|
Re: Howto create control-collection -control? [message #1692 is a reply to message #1684] |
Mon, 13 March 2006 22:04 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
wilho wrote on Mon, 13 March 2006 14:42 | Ok, here we go again:
class DblClckBtn : public Button {
public:
Callback WhenLeftDouble;
virtual void DblClckBtn::LeftDouble(Point, dword);
};
class ExpressPane : public Ctrl {
struct SlaveControl {
bool isInSplitter;
DblClckBtn button;
Ctrl* slave;
};
Array<SlaveControl> slaves;
Splitter splitter;
static const int BTN_SPACE = 22;
typedef ExpressPane CLASSNAME;
void Toggle(int);
void OpenOne(int);
public:
void Add(const char *text, Ctrl& slave);
void Rearrange();
ExpressPane();
};
void DblClckBtn::LeftDouble(Point p, dword) {
if(IsReadOnly()) return;
WhenLeftDouble();
}
ExpressPane::ExpressPane(){
Ctrl::Add(splitter);
splitter.Vert();
}
void ExpressPane::OpenOne(int indx){
for(int loopI=slaves.GetCount()-1; loopI>-1; loopI--){
slaves[loopI].isInSplitter = false;
}
slaves[indx].isInSplitter = true;
Rearrange();
}
void ExpressPane::Toggle(int indx){
slaves[indx].isInSplitter = !slaves[indx].isInSplitter;
Rearrange();
}
void ExpressPane::Rearrange(){
for(int loopI=slaves.GetCount()-1; loopI>-1; loopI--){
splitter.RemoveChild( slaves[loopI].slave );
if (slaves[loopI].isInSplitter == true){
splitter << *slaves[loopI].slave;
}
}
splitter.RefreshLayout();
}
void ExpressPane::Add(const char *text, Ctrl& slave){
SlaveControl& slvCtrl = slaves.Add();
int btnIndx = slaves.GetCount()-1;
slvCtrl.button <<= THISBACK1(Toggle,btnIndx);
slvCtrl.button.WhenLeftDouble << THISBACK1(OpenOne,btnIndx);
slvCtrl.button.SetLabel(text);
slvCtrl.button.HSizePosZ(0, 0).BottomPosZ(BTN_SPACE * (btnIndx), BTN_SPACE -2);
slvCtrl.isInSplitter = false;
slvCtrl.slave = &slave;
splitter.HSizePosZ(0, 0).VSizePosZ(0, BTN_SPACE * (btnIndx+1));
Ctrl::Add(slvCtrl.button);
}
Here's rearrange and some use for it in form double-click feature. And I finally got the !visible hint
|
Well, now this actually looks like some U++ code
Mirek
|
|
|
|
|
|
Re: Howto create control-collection -control? [SOLVED -good example] [message #20786 is a reply to message #20782] |
Tue, 07 April 2009 12:10 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
kbyte wrote on Tue, 07 April 2009 09:53 | Any simple app example to show the way how we use this new control?
Alex
|
It's very easy:
class CtrlLibTest : public WithCtrlLibTestLayout<TopWindow> {
public:
typedef CtrlLibTest CLASSNAME;
WithTestLayout<ParentCtrl> c1, c2;
ExpressPane pane;
CtrlLibTest::CtrlLibTest()
{
CtrlLayout(*this, "Window title");
Sizeable();
CtrlLayout(c1);
CtrlLayout(c2);
pane.Add("Child 1", c1);
pane.Add("Child 2", c2);
Add(pane.SizePos());
}
};
It's basically a Splitter with a set of buttons at the bottom for different Ctrls that can be dynamically added/removed by the user. A nice concept.
My suggestions for improvement:
-Instead of having the buttons in the Splitter put them in a FrameSplitter. This will make your layout simpler and also give you the option of having the buttons on the left, right or top of the ctrl.
-The buttons would look better if you used a ButtonOption, maybe with a custom Style, and no spacing between them. This would also remove the need for the isInSplitter member.
-Inherit from ParentCtrl, not Ctrl.
-I'm not entirely convinced a Splitter is the best way here, Outlook seems to just swap the controls (only having one visible at a time).
-You may also be interested in this package, which is a different approach to a similar problem.
James
[Updated on: Wed, 08 April 2009 10:47] Report message to a moderator
|
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Sat Apr 27 18:44:59 CEST 2024
Total time taken to generate the page: 0.06768 seconds
|
|
|