|
|
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » List of custom controls, how?
|
Re: List of custom controls, how? [message #37718 is a reply to message #37717] |
Mon, 05 November 2012 13:46 |
|
crydev wrote on Mon, 05 November 2012 12:35 | - I know I have to make a new class deriving from (Ctrl)?
- I have to override the Paint(Draw& g) method
- I have to draw a rectangle inside the paint method in which the contents of my custom control will be drawn.
I really don't know how this would work. I have tried to find out the things I need to know but it is hard to find. Can somebody supply me with an example of how it works or how they would do this? I really appriciate your help!
|
Hi crydev,
It is sure possible to draw the contents of you Ctrl yourself, but in most cases it is not needed. You can also create new Ctrls by combining already existng ones, e.g. in your case you'd take an Image and two Ctrls for text display (Label, RichTextCtrl, etc...). Something like this should be sufficient (plus you have to add your logic to fill the data of course):struct MyCtrl : public ParentCtrl { // it is easier to inherit from ParentCtrl,
private: // because it paint it's background
ImageCtrl img;
Label title;
Label info;
public:
MyCtrl() {
Add(img.LeftPosZ(5,30).TopPosZ(5,30));
Add(title.LeftPosZ(40,90).TopPosZ(5,30));
Add(info.HSizePosZ(5,5).VSizePosZ(40,5));
SetValues();
}
void SetValues(){
img.SetImage(CtrlImg::save()); // some random image
title.SetText("Save private Ryan"); // some title
info.SetText("This is some info."); // some info text
}
};
This way you can simple group many widgets and then use them in your app just as any other U++ Ctrl. The Labels used are just an example, you will probably want to use something more fancy, like RichTextCtrl.
Best regards,
Honza
PS: If you want to try the other way, with overriding paint etc., you should have a look at Gui tutorial, chapter 21.
[Updated on: Mon, 05 November 2012 13:48] Report message to a moderator
|
|
|
|
|
Re: List of custom controls, how? [message #37735 is a reply to message #37726] |
Wed, 07 November 2012 10:02 |
crydev
Messages: 151 Registered: October 2012 Location: Netherlands
|
Experienced Member |
|
|
crydev wrote on Mon, 05 November 2012 21:48 | Thanks dolik.rce, I see what u mean and it is easy for me to understand. I see how easy it can be. However, there is one more issue for me. The control and the way I should code them is clear to me, but how should I do the container?
The way I thought it out I'd use a ParentCtrl as container. I tried this out, but I think there is more I will have to do as just adding them to a ParentCtrl does not work. (This is not because I am so stupid that I didn't expect it not to work, just because I wanted to know what would happen )
Could you help me out with the parent/container control?
|
Ok I found a ColumnList for Ctrl's. I tested it with standard controls and it works! However, when I try to add my own controls it draws a scrollbar, but it doesn't draw any of my controls.
- Why does it not draw itself? I tried to inherit from Ctrl and ParentCtrl.
- The thread in which the CtrlColumnList was posted also has posts stating that the idea to implement this functionality into the existing ColumnList or ArrayCtrl could be worked out. I have found functions like Add(Ctrl&/* ctrl) in these controls so can I assume the extra code for the CtrlColumnList would not be nessecary anymore?
|
|
|
Re: List of custom controls, how? [message #37741 is a reply to message #37735] |
Wed, 07 November 2012 20:25 |
|
crydev wrote on Wed, 07 November 2012 10:02 | Ok I found a ColumnList for Ctrl's. I tested it with standard controls and it works! However, when I try to add my own controls it draws a scrollbar, but it doesn't draw any of my controls.
- Why does it not draw itself? I tried to inherit from Ctrl and ParentCtrl.
- The thread in which the CtrlColumnList was posted also has posts stating that the idea to implement this functionality into the existing ColumnList or ArrayCtrl could be worked out. I have found functions like Add(Ctrl&/* ctrl) in these controls so can I assume the extra code for the CtrlColumnList would not be nessecary anymore?
|
It is very hard to say why it doesn't work without seeing the code. Also, I'm not very familiar with ColumnList as I don't like some aspects of its behavior
But for what you need ColumnList or ArrayCtrl are probably overkill anyway. It can be achieved relatively simply by using a ScrollBar. Here is some code for your inspiration:#include <CtrlLib/CtrlLib.h>
using namespace Upp;
// arbitrary custom Ctrl
struct MyCtrl : public ParentCtrl{
Label l;
MyCtrl(){
Add(l.HSizePos(10,10).VSizePos(5,5));
l.SetFrame(InsetFrame());
}
virtual void SetData(const Value& data){
l.SetText(AsString(data));
}
};
struct App : public TopWindow {
typedef App CLASSNAME;
Array<MyCtrl> ctrls;
ScrollBar sb;
int height;
App() {
//initialize
Title("Test").Sizeable();
SetRect(0, 0, 120, 400);
height = 40;
//populate
for(int i = 0; i < 12; i++){
ctrls.Add() <<= "Widget #"+IntStr(i);
Add(ctrls[i].HSizePos().TopPos(height*i, height));
}
//set up scrollbar
sb.Vert().AutoHide().SetTotal(ctrls.GetCount() * height);
sb.WhenScroll = THISBACK(Scroll);
AddFrame(sb);
}
void Scroll() {
//update position
int pos = sb.Get();
for(int i = 0; i < ctrls.GetCount(); i++){
ctrls[i].TopPos(height*i - pos, height);
}
}
virtual void Layout() {
//window was resized, adjust scrollbar
sb.SetPage(GetSize().cy);
}
virtual bool Key(dword key, int) {
// pass key event to scrollbar
return sb.VertKey(key);
}
};
GUI_APP_MAIN{
App().Run();
};
You will probably want to implement something similar to this but based on ParentCtrl instead of TopWindow, so you can position it inside the rest of your app (I wrote as a selfstanding app just so it is easy to compile and test...). The whole idea is to have a ScrollBar and whenever it is moved, you just iterate over your Ctrls and adjust their position. Any Ctrls that are outside of their parent are not rendered, so in the end, it will result in nice smooth scrolling effect. It is really simple
Honza
|
|
|
Re: List of custom controls, how? [message #37745 is a reply to message #37717] |
Thu, 08 November 2012 09:29 |
crydev
Messages: 151 Registered: October 2012 Location: Netherlands
|
Experienced Member |
|
|
Thanks a lot Honza! Your example made sense to me. I implemented it in my application the following way:
// Initialization of the scrollbar frame.
mScrollBar.Vert().AutoHide();
mScrollBar.WhenScroll = THISBACK(ScrollImdbResults);
mImdbSearchResults.AddFrame(mScrollBar);
Code populating the ParentCtrl with controls.
mImdbCtrls.Clear();
ImdbManager im;
im.ImdbSearch(SEARCHMODE_KEYWORD, mMovieList.Get(row, 0));
auto tmpRes = im.GetValues();
for (int i = 0; i < /*tmpRes.GetCount()*/20; i++)
{
ImdbSearchResult *m = new ImdbSearchResult(); // This is weird! I had it a struct with a default constructor but that
// kept giving me an error about not having a 'copy constructor'. I still
// don't know why this notation is not resulting in a memory leak.
m->SetValues(CtrlImg::save(), tmpRes[i].cTitle, tmpRes[i].cUrl);
mImdbCtrls.Add(m); // Array<ImdbSearchResult> mImdbCtrls;
mImdbSearchResults.Add(mImdbCtrls[i].HSizePos().TopPos(IMDBCTRLHEIGHT * i, IMDBCTRLHEIGHT)); // ParentCtrl mImdbSearchResults;
}
mScrollBar.SetTotal(mImdbCtrls.GetCount() * IMDBCTRLHEIGHT); // const int IMDBCTRLHEIGHT = 60;
The scroll event function
void MovieManager::ScrollImdbResults()
{
int pos = mScrollBar.Get();
for (int i = 0; i < mImdbCtrls.GetCount(); i++)
{
mImdbCtrls[i].TopPos(IMDBCTRLHEIGHT * i - pos, IMDBCTRLHEIGHT);
}
}
The Key function
bool MovieManager::Key(dword key, int)
{
return mScrollBar.VertKey(key);
}
The Layout function
void MovieManager::Layout()
{
mScrollBar.SetPage(GetSize().cy);
}
There still is one thing that doesn't work that I would like to work. Using the mouse scrollwheel to scroll though the objects is not working. My guess is that this should be implemented in the Key(dword key, int) function. Is there maybe a builtin property or function to handle this? And which keys are being handled by the Key(dword key, int) function?
Thank you!
[Updated on: Thu, 08 November 2012 09:30] Report message to a moderator
|
|
|
Re: List of custom controls, how? [message #37747 is a reply to message #37745] |
Thu, 08 November 2012 10:07 |
|
crydev wrote on Thu, 08 November 2012 09:29 | There still is one thing that doesn't work that I would like to work. Using the mouse scrollwheel to scroll though the objects is not working. My guess is that this should be implemented in the Key(dword key, int) function. Is there maybe a builtin property or function to handle this? And which keys are being handled by the Key(dword key, int) function?
|
If you look at reference/ScrollBar, you'll see it can be done with the MouseWheel virtual function: virtual void MouseWheel(Point, int zdelta, dword)
{
sb.Wheel(zdelta);
}
The only problem with this is that sometimes the wheel event is consumed by the Ctrl immediately under the cursor, so this MouseWheel is never invoked. I'm not really sure how this should be handled properly. Hopefully someone else will help us with that
Best regards,
Honza
|
|
|
Re: List of custom controls, how? [message #38001 is a reply to message #37717] |
Tue, 27 November 2012 17:33 |
crydev
Messages: 151 Registered: October 2012 Location: Netherlands
|
Experienced Member |
|
|
Hi, I wrote the custom control solution as Honza suggested me and it works for me. However, there still is one peculiarity here. The behaviour when drawn is as following:
The situation that the controls are in now is as following. I have an image, a title and another description text under the title. All three should be visible. However, the description text is not visible by default. When I resize the control by dragging the bar to the right, the text becomes visible. The following picture cleares it up a bit.
When I drag the bar back to the left, the description becomes hidden again. It seems like an element is interfering with the description label, but I don't know which and I also cannot find out
What could be the problem in this situation? I am planning on creating custom controls for other purposes this way, because I am happy the way it behaves, but I think I will run into this problem again. It would be nice if I could solve it here
|
|
|
Re: List of custom controls, how? [message #38008 is a reply to message #38001] |
Wed, 28 November 2012 07:30 |
|
crydev wrote on Tue, 27 November 2012 17:33 | When I drag the bar back to the left, the description becomes hidden again.
|
This sounds like you got the positioning/sizing code slightly wrong. If you use layout file, check the "springs" that the label is correctly anchored. You want it to be fixed on all sides, so when resizing it keeps same distance from edges of layout:img]index.php?t=getfile&id=3937&private=0[/im g]
If you position the label in code, it should be done with something like this: myLabel.HSizePosZ(leftMargin, rightMargin).VSizePosZ(topMargin, bottomMargin);
If needed, you can post the relevant part of you code and I can perhaps give you more precise advice
Honza
-
Attachment: springs.png
(Size: 3.58KB, Downloaded 268 times)
|
|
|
Re: List of custom controls, how? [message #38011 is a reply to message #38008] |
Wed, 28 November 2012 08:20 |
crydev
Messages: 151 Registered: October 2012 Location: Netherlands
|
Experienced Member |
|
|
dolik.rce wrote on Wed, 28 November 2012 07:30 |
crydev wrote on Tue, 27 November 2012 17:33 | When I drag the bar back to the left, the description becomes hidden again.
|
This sounds like you got the positioning/sizing code slightly wrong. If you use layout file, check the "springs" that the label is correctly anchored. You want it to be fixed on all sides, so when resizing it keeps same distance from edges of layout:img]index.php?t=getfile&id=3937&private=0[/im g]
If you position the label in code, it should be done with something like this: myLabel.HSizePosZ(leftMargin, rightMargin).VSizePosZ(topMargin, bottomMargin);
If needed, you can post the relevant part of you code and I can perhaps give you more precise advice
Honza
|
Thanks for you response Honza, I fixed the problem. The problem was as following:
Add(mImg.LeftPosZ(5, 30).TopPosZ(10, 30));
Add(mTitle.LeftPosZ(40, 300).TopPosZ(5, 30));
// I thought that 300 was the width of the control, because I used that value in the two above.
// However, As in your post, it is not the width, but the margin from the right side.
Add(mInfo.HSizePosZ(40, 300).VSizePosZ(30, 5)); // changed 300 to 10
It works now, stupid mistake of mine though. Thanks for your help!
[Updated on: Wed, 28 November 2012 08:21] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Tue Jun 04 01:04:35 CEST 2024
Total time taken to generate the page: 0.03809 seconds
|
|
|