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 » U++ Widgets - General questions or Mixed problems » List of custom controls, how?
List of custom controls, how? [message #37717] Mon, 05 November 2012 12:35 Go to next message
crydev is currently offline  crydev
Messages: 151
Registered: October 2012
Location: Netherlands
Experienced Member
Hello devs, I have been busy with a movie managing program for myself. The idea is that you can configure multiple directories containing movies that will be loaded into a library (list that loads all information about them). I also have a functionality that grabs IMDb information. It currently looks as shown below.

index.php?t=getfile&id=3910&private=0

Now the links you see in the IMDb section are testing links. These are links found in a search operation. However, I would like these links to be displayed in a custom control. The way I would like to have it is as following.

index.php?t=getfile&id=3911&private=0

I have some experience with C# so I know a thing or two about custom controls. However, I am not using the designer with layouts because I use Visual Studio aside of U++ for debugging purposes.

- 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!
  • Attachment: Now.PNG
    (Size: 124.53KB, Downloaded 750 times)
  • Attachment: DoWant.png
    (Size: 110.30KB, Downloaded 772 times)
Re: List of custom controls, how? [message #37718 is a reply to message #37717] Mon, 05 November 2012 13:46 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

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 #37723 is a reply to message #37718] Mon, 05 November 2012 19:50 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13984
Registered: November 2005
Ultimate Member
You can also consider using Qtf and RichTextCtrl - in these "display" cases, it tends to be quite versatile solution.

Mirek
Re: List of custom controls, how? [message #37726 is a reply to message #37717] Mon, 05 November 2012 21:48 Go to previous messageGo to next message
crydev is currently offline  crydev
Messages: 151
Registered: October 2012
Location: Netherlands
Experienced Member
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 Embarassed )

Could you help me out with the parent/container control?
Re: List of custom controls, how? [message #37735 is a reply to message #37726] Wed, 07 November 2012 10:02 Go to previous messageGo to next message
crydev is currently offline  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 Embarassed )

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 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

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 Smile

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 Smile

Honza
Re: List of custom controls, how? [message #37745 is a reply to message #37717] Thu, 08 November 2012 09:29 Go to previous messageGo to next message
crydev is currently offline  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 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

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 Smile

Best regards,
Honza
Re: List of custom controls, how? [message #38001 is a reply to message #37717] Tue, 27 November 2012 17:33 Go to previous messageGo to next message
crydev is currently offline  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.

index.php?t=getfile&id=3936&private=0

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 Sad

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 Smile
  • Attachment: situation.PNG
    (Size: 27.91KB, Downloaded 609 times)
Re: List of custom controls, how? [message #38008 is a reply to message #38001] Wed, 28 November 2012 07:30 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1789
Registered: August 2008
Location: Czech Republic
Ultimate Contributor

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 Wink

Honza
  • Attachment: springs.png
    (Size: 3.58KB, Downloaded 269 times)
Re: List of custom controls, how? [message #38011 is a reply to message #38008] Wed, 28 November 2012 08:20 Go to previous message
crydev is currently offline  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 Wink

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

Previous Topic: Control refresh time
Next Topic: VScrollBar in a StaticText
Goto Forum:
  


Current Time: Sun Jun 16 08:27:26 CEST 2024

Total time taken to generate the page: 0.02611 seconds