Home » Extra libraries, Code snippets, applications etc. » U++ users applications in progress and useful code snippets, including reference examples! » "Forlano tabs" - how to reduce a headache by the proper use of the designer...
| "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2135] |
Sun, 02 April 2006 12:11  |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
I christened this topic "Forlano tabs" - how to reduce a headache by the proper use of the designer... because it's a continuation of forlano's series of "U++ beginners fundamental questions" which you can find in other parts of our forums... (inc. "How to combine two widget-class in the topwindow" )
So, why the code below and "program all your widgets by hand" is a headache?
//personalized tab (1 child) widget
class LuigiTab : public ParentCtrl {
Button btnAdd, btnDel, btnClear, btnModify;
DocEdit doc;
LabelBox lbox;
Label label[10];
EditString editName, editCountry, editBirth, editNatRat,
editNatId, editFIDEId, editFIDERat;
DropList editTitle;
Option tsex;
EditInt kcoeff;
ArrayCtrl arr;
public:
typedef LuigiTab CLASSNAME;
LuigiTab();
~LuigiTab(){;}
};
LuigiTab::LuigiTab() {
// label
lbox.SetLabel(t_("Edit Player")).LeftPosZ(16, 648).TopPosZ(16, 80);
Add(lbox);
label[0].SetLabel(t_("Name")).SetAlign(ALIGN_CENTER).LeftPosZ(28, 132).TopPosZ(32, 19);
Add(label[0]);
label[1].SetLabel(t_("Fed")).SetAlign(ALIGN_CENTER).LeftPosZ(168, 40).TopPosZ(32, 19);
Add(label[1]);
label[2].SetLabel(t_("Birthday")).SetAlign(ALIGN_CENTER).LeftPosZ(208, 56).TopPosZ(32, 19);
Add(label[2]);
label[3].SetLabel(t_("Gender")).SetAlign(ALIGN_CENTER).LeftPosZ(264, 56).TopPosZ(32, 19);
Add(label[3]);
label[4].SetLabel(t_("Title")).SetAlign(ALIGN_CENTER).LeftPosZ(324, 40).TopPosZ(32, 19);
Add(label[4]);
label[5].SetLabel(t_("ID FIDE")).SetAlign(ALIGN_CENTER).LeftPosZ(380, 48).TopPosZ(32, 19);
Add(label[5]);
label[6].SetLabel(t_("Rat FIDE")).SetAlign(ALIGN_CENTER).LeftPosZ(440, 48).TopPosZ(32, 19);
Add(label[6]);
label[7].SetLabel(t_("ID Nat")).SetAlign(ALIGN_CENTER).LeftPosZ(496, 48).TopPosZ(32, 19);
Add(label[7]);
label[8].SetLabel(t_("Rat Nat")).SetAlign(ALIGN_CENTER).LeftPosZ(558, 48).TopPosZ(32, 19);
Add(label[8]);
label[9].SetLabel(t_("K")).SetAlign(ALIGN_CENTER).LeftPosZ(616, 24).TopPosZ(32, 19);
Add(label[9]);
//active widget
editName.MaxLen(25).LeftPosZ(28, 136).TopPosZ(56, 19);
Add(editName);
editCountry.MaxLen(3).LeftPosZ(172, 32).TopPosZ(56, 19);
Add(editCountry);
editNatId.MaxLen(8).LeftPosZ(496, 48).TopPosZ(56, 19);
Add(editNatId);
editBirth.MaxLen(10).LeftPosZ(212, 56).TopPosZ(56, 19);
Add(editBirth);
editFIDERat.MaxLen(8).LeftPosZ(440, 48).TopPosZ(56, 19);
Add(editFIDERat);
tsex.SetLabel(t_("Male")).LeftPosZ(280, 42).TopPosZ(56, 20);
Add(tsex);
editTitle.DisplayAll(true).LeftPosZ(328, 42).TopPosZ(56, 20);
Add(editTitle);
editFIDEId.MaxLen(8).LeftPosZ(380, 48).TopPosZ(56, 19);
Add(editFIDEId);
editNatRat.MaxLen(8).LeftPosZ(554, 56).TopPosZ(56, 19);
Add(editNatRat);
kcoeff.Min(0).Max(100).LeftPosZ(620, 24).TopPosZ(56, 19);
Add(kcoeff);
// button
btnAdd.SetLabel(t_("Add Player")).LeftPosZ(24, 96).TopPosZ(116, 24);
Add(btnAdd);
btnModify.SetLabel(t_("Modify Player")).LeftPosZ(148, 96).TopPosZ(116, 24);
Add(btnModify);
btnDel.SetLabel(t_("Delete Player")).LeftPosZ(56, 96).TopPosZ(328, 24);
Add(btnDel);
btnClear.SetLabel(t_("Clear Data")).LeftPosZ(284, 96).TopPosZ(116, 24);
Add(btnClear);
// array ctrl
arr.Moving(true).Removing(true).AppendLine(true).Inserting(true).LeftPosZ(16, 648).TopPosZ(172, 148);
Add(arr);
arr.AddColumn("Name");
arr.AddColumn("Fed");
arr.AddColumn("Birthday");
arr.AddColumn("Gender");
arr.AddColumn("Title");
arr.AddColumn("ID FIDE");
arr.AddColumn("Rat FIDE");
arr.AddColumn("ID Nat");
arr.AddColumn("Rat Nat");
arr.AddColumn("K");
arr.AddColumn("Available");
1. This way can't go through all your forms quickly and "visually" and add new widgets during the process of improvements.
2. Accessing labels only by index is a headache, too.
[to be continued...]
P.S Comments are welcome!
[Updated on: Sun, 02 April 2006 12:12] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2153 is a reply to message #2151] |
Sun, 02 April 2006 15:19   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
So, here we go:
#include <CtrlLib/CtrlLib.h>
//"Forlano tabs example"- might not be very correct but might be usuful for learning...
//with added added one layout from the designer
//Step1 - if you want to use layouts - always include something like this
#define LAYOUTFILE "editmask.lay"
#include <CtrlCore/lay.h>
//Step 2 - please check that you have LAYOUT(Tab1Layout, 680, 368)
//personally I find renaming layouts faster in text mode...
//Step 3 - the Tab1 class below is pasted from automatically generated by the Designer
//using Alt_C first option "Dialog class"
class Tab1 : public WithTab1Layout<TopWindow> {
public:
typedef Tab1 CLASSNAME;
Tab1();
};
Tab1::Tab1()
{
CtrlLayout(*this, "");
}
//the code below is what you had had before, except Step 4
//personalized tab (1 child) widget
class LuigiTab : public ParentCtrl {
Button btn;
DocEdit doc;
public:
typedef LuigiTab CLASSNAME;
LuigiTab();
~LuigiTab(){;}
};
LuigiTab::LuigiTab() {
btn.SetLabel("Just Button");
btn.SetRect(20,20,100,25);
Add(btn);
//I strongly recommend to learn positioning from Designer- use Ctrl-T!
doc.LeftPosZ(30, 500).TopPosZ(50, 300);
Add(doc);
}
//personalized tabs (many -container) widget
class LuigiTabs : public TabCtrl {
Tab1 tab1; //Step 4 - this is your new tab!!!
LuigiTab tab2,tab3; //tab1 removed
public:
typedef LuigiTabs CLASSNAME;
LuigiTabs();
~LuigiTabs(){;}
};
//the code below is all the same
Now you can make your tab1 changes using the designer... 
What's next?
[Updated on: Sun, 02 April 2006 15:56] Report message to a moderator
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2157 is a reply to message #2153] |
Sun, 02 April 2006 15:56   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
What next.. I guess you will want to have some columns in your ArrayCtrl...
You will need 2 more steps:
1. Create a name for it in your *.lay file e.g. - arr
2. initialize it in the constructor like this:
Tab1::Tab1()
{
CtrlLayout(*this, "");
arr.AddColumn("col1");
arr.AddColumn("col2");
arr.AddColumn("col3");
}
Edit:
or
Tab1::Tab1()
{
CtrlLayout(*this, "");
arr.AddColumn("Name");
arr.AddColumn("Fed");
arr.AddColumn("Birthday");
arr.AddColumn("Gender");
arr.AddColumn("Title");
arr.AddColumn("ID FIDE");
arr.AddColumn("Rat FIDE");
arr.AddColumn("ID Nat");
arr.AddColumn("Rat Nat");
arr.AddColumn("K");
arr.AddColumn("Available");
}
[Updated on: Sun, 02 April 2006 16:21] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2171 is a reply to message #2167] |
Sun, 02 April 2006 20:46   |
 |
forlano
Messages: 1224 Registered: March 2006 Location: Italy
|
Senior Contributor |
|
|
| fudadmin wrote on Sun, 02 April 2006 19:58 |
1. as you should know from C experience #define is a substitutor.
If you write only on part of it, it your compiler replaces it with nothing. This is useful only in #ifdefs or if you want to not use what you define... 
|
ooops... I mean #include and not define.
| Quote: |
3. It is sufficient to write just
#define LAYOUTFILE "editmask.lay"
if you keep this file in your package folder where other files reside e.g in c:\MyApps\tabs\ ...
|
In this way doesn't work on my PC. But it works in the other way, so let's save time and forget about it (the lazy man spirit sometime come out )
| Quote: |
| forlano wrote on Sun, 02 April 2006 17:51 |
Fantastic... 
|
...And remember I told you - do not struggle alone and do it in a lazy man's way? When you wrote in our label topic:
| Quote: |
but I'm a lazy man, , and I do not want to loose time...
|
And then in this topic you wrote:
| Quote: | ...I lost many hours to wright it and I'm not at all satisfact. Now I must retouch some widget with the result to retouch again all their position.
|
That means you are not lazy enough... ... to be an inventor...
I guess Mirek and Tom are lazy enough... That's why they invented Ultimate++... to let us all enjoy our laziness!
So, from now on, if you feel that some tasks with Ultimate++ are not enjoyable - ask how they can be converted... 
|
After you spent a lot of time for me, I was forced to produce something... unfortunately it was useless . But I learned the lesson.
This tool is really great... and the forum is even greater.
The next step is to fill the fields with some data (the drop list need some data like: item1, item2, item3), retrieve them and accomodate in the arrayctrl. By the way, the last coloumn should contain a checkbox (on/off) that should be set by default to on. Later we collect the data from the array and save them in txt file ';' separated.
I've no idea about how to fill the drop list, and how to add a checkbox inside the arrayctrl. For the rest I can try. I'll do it tomorrow afternoon and post here the code. For the moment I guess I must define a callback for the button "Add" that do the job.
Thanks a lot,
Luigi
|
|
|
|
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2176 is a reply to message #2173] |
Mon, 03 April 2006 00:17   |
 |
forlano
Messages: 1224 Registered: March 2006 Location: Italy
|
Senior Contributor |
|
|
| luzr wrote on Sun, 02 April 2006 20:54 |
| forlano wrote on Sun, 02 April 2006 14:46 |
I've no idea about how to fill the drop list, and how to add a checkbox inside the arrayctrl. [snip]
|
DropList dl;
ArrayCtrl ar;
....
dl.Add(1, "First item");
dl.Add("Second", "Second item");
ar.AddColumn("Check").Ctrls<Option>();
Mirek
|
Thank you Mirek,
I've not resisted to the temptetion to write the code before to go to sleep... even because I was afraid that Fudadmin (by the way... which is your human name?) could anticipate me once more . With my surprise I was able to perform everything in not more than 10 minutes! (two day ago I wont bet a cent). Here is the new class Tab1 code with Add and Clear button activated:
class Tab1 : public WithTab1Layout<TopWindow> {
public:
typedef Tab1 CLASSNAME;
Tab1();
void AddPlayer(); //callback from Add_Player button
void MaskDefaultValue(); //callback from Clera button
};
Tab1::Tab1()
{
CtrlLayout(*this, "");
arr.AddColumn("Name");
arr.AddColumn("Fed");
arr.AddColumn("Birthday");
arr.AddColumn("Gender");
arr.AddColumn("Title");
arr.AddColumn("ID FIDE");
arr.AddColumn("Rat FIDE");
arr.AddColumn("ID Nat");
arr.AddColumn("Rat Nat");
arr.AddColumn("K");
arr.AddColumn("Available").Ctrls<Option>();
// how to set ON the checkbox?
//drop list widget
editTitle.Add(1, "First");
editTitle.Add(2, "Second");
editTitle.Add(3, "Third");
//set the callback for the Add_Player button
btnAdd <<= THISBACK(AddPlayer);
btnClear <<= THISBACK(MaskDefaultValue);
//fill with default value
MaskDefaultValue();
}
void Tab1::AddPlayer() // body of the callback
{
if ( (~editName) == Null) {
PromptOK("The Name field cannot be empty!");
return;
}
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff);
arr.GoEnd();
// editName <<= editCountry <<= editBirth <<= tsex <<= editTitle <<= editFIDEId <<=
// editFIDERat <<= editNatId <<= editNatRat <<=kcoeff <<= Null;
ActiveFocus(editName);
MaskDefaultValue();
}
void Tab1::MaskDefaultValue() // body of the callback
{
editName <<= Null;
editCountry <<= "--";
editBirth <<= "00.00.00";
tsex <<= 1;
editTitle <<= "GM";
editFIDEId <<= editFIDERat <<= editNatId <<= editNatRat <<= 0;
kcoeff <<= 30;
ActiveFocus(editName);
}
Now arise some questions that regards the details (the details make the difference as everybody knows):
1. I desire my user do not enter more than 25 character in the editName widget. It is not enough that a pink colour appear. I desire that the widget refuse to write any character further the 25th. Is there such limitation?
2. I desire that the lenght of the arrayCtrl in corrispondence, for example, of field Name be 25 character long. The user can tune it manually but I prefer to set it initially to some lenght. How to do it?
3. The check box appear in the array but it is not set to ON (checked) but it is unchecked. How to set it to ON?
4. I desire that the even numbered line of the array be colored, say light blue (I love this feature. By the way, in the past this feature attracted my attention toward Ultimate++)
Now I can go to sleep very . Today was a great day!
The next step is to click on the array, retrieve the data of the row, and sent them in the above mask for some modification.
Good night,
Luigi
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2177 is a reply to message #2176] |
Mon, 03 April 2006 13:23   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
| Quote: | 3. The check box appear in the array but it is not set to ON (checked) but it is unchecked. How to set it to ON?
|
The simpliest solution is this:
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, 1);
//1 - for option
[Updated on: Mon, 03 April 2006 13:23] Report message to a moderator
|
|
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2179 is a reply to message #2177] |
Mon, 03 April 2006 13:29   |
 |
forlano
Messages: 1224 Registered: March 2006 Location: Italy
|
Senior Contributor |
|
|
| fudadmin wrote on Mon, 03 April 2006 13:23 |
| Quote: | 3. The check box appear in the array but it is not set to ON (checked) but it is unchecked. How to set it to ON?
|
The simpliest solution is this:
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, 1);
//1 - for option
|
Very nice solution! (The simplest is always the better)
Now remain 1 more question
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2180 is a reply to message #2178] |
Mon, 03 April 2006 13:32   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
Regarding 3. option...
...or 3.1 add to your *.lay
ITEM(Label, dv___1, SetLabel(t_("Avail?")).SetAlign(ALIGN_CENTER).LeftPosZ(652, 32).TopPosZ(32, 19))
ITEM(Option, optAvail, LeftPosZ(660, 16).TopPosZ(56, 19))
3.2 initialize
arr.AddColumn("Available").Ctrls<Option>();
// how to set ON the checkbox?
optAvail.Set(1);
3.3 don't forget to add to the array:
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, ~optAvail);
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2181 is a reply to message #2178] |
Mon, 03 April 2006 13:45   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
Regarding column widths- I would prefer to see what width is set for which column:
arr.AddColumn("Name",10);
arr.AddColumn("Fed",3);
arr.AddColumn("Birthday",4);
arr.AddColumn("Gender",4);
arr.AddColumn("Title",4);
arr.AddColumn("ID FIDE",4);
arr.AddColumn("Rat FIDE",4);
arr.AddColumn("ID Nat",4);
arr.AddColumn("Rat Nat",4);
arr.AddColumn("K",3);
arr.AddColumn("Available",3).Ctrls<Option>();
or even calculated from edit field layouts or from column text lengths or something combined...
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2184 is a reply to message #2177] |
Mon, 03 April 2006 16:33   |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, 1);
//1 - for option
BTW, you can use "true" for clarity.. (bool is Value compatible, and inside Value, int64, int, double and bool are all inter-convertible).
Mirek
[Updated on: Mon, 03 April 2006 16:34] Report message to a moderator
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2185 is a reply to message #2184] |
Mon, 03 April 2006 16:37   |
 |
fudadmin
Messages: 1321 Registered: November 2005 Location: Kaunas, Lithuania
|
Ultimate Contributor Administrator |
|
|
| luzr wrote on Mon, 03 April 2006 15:33 |
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, 1);
//1 - for option
BTW, you can use "true" for clarity.. (bool is Value compatible, and inside Value, int64, int, double and bool are all inter-convertible).
Mirek
|
"true" is 4 times more to type!!!
|
|
|
|
|
|
| Re: "Forlano tabs" - how to reduce a headache by the proper use of the designer... [message #2188 is a reply to message #2185] |
Mon, 03 April 2006 16:39  |
 |
mirek
Messages: 14291 Registered: November 2005
|
Ultimate Member |
|
|
| fudadmin wrote on Mon, 03 April 2006 10:37 |
| luzr wrote on Mon, 03 April 2006 15:33 |
arr.Add(~editName, ~editCountry, ~editBirth, ~tsex, ~editTitle,
~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, 1);
//1 - for option
BTW, you can use "true" for clarity.. (bool is Value compatible, and inside Value, int64, int, double and bool are all inter-convertible).
Mirek
|
"true" is 4 times more to type!!!
|
"can" != "must" 
Mirek
|
|
|
|
Goto Forum:
Current Time: Sun May 17 00:09:22 GMT+2 2026
Total time taken to generate the page: 0.01664 seconds
|