About Store Forum Documentation Contact



Post Reply 
Internal GUI Controls
Author Message
fatcoder Offline
Member

Post: #1
Internal GUI Controls
I remember discussing this on the forum over a year ago. Anyway, I just wanted to bring this up again, as a feature request. I am finding that many of the gui controls have internal gui controls. For example, the region control has internal slidebar controls, which have internal button controls.

The problem is that if you override the button control to do custom drawing, then the slidebar buttons look different to the rest of your buttons as you can't override them without overriding the entire slidebar control, which in turn means you need to override the region control. This is making it very hard to have a consistent look across the gui without literally overriding everything. I find myself having to rebuild the functionality of entire controls just to get it to draw a specific way. The main one I'm having a problem with is the region slidebar buttons.

It would be nice if it was possible to represent these internal controls in a manner that allowed them to be swapped out with custom versions without having to touch the parent control.
03-19-2013 01:44 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
RE: Internal GUI Controls
Hello,

If you'd like that kind of functionality made in first priority I can add it to the Store contributions section, please let me know.

Or alternative choice if you would show a screenshot of what effect you want to achieve, and what code you're using for drawing the gui objects, perhaps I could consider integrating that functionality to builtin objects.
03-31-2013 09:49 PM
Find all posts by this user Quote this message in a reply
fatcoder Offline
Member

Post: #3
RE: Internal GUI Controls
Probably no point adding it to the store as I doubt there would be enough people interested to make it worth your while.

Here is a screen shot from the List tutorial using a custom (extended) button. The custom button's draw function has been overridden to give it a unique display (copied from another tutorial). The problem is that there is no way to change the display of the slider buttons in the list to match without overriding the entire draw function of the list. I would be happy to override the List draw function, however I don't know all the code required to draw the whole list correctly.

   

On a side note, .Net Winforms uses "parts" to draw Windows gui controls. This allows you to override a control's OnPaint method and have the control draw the parts you want by default and you draw the other parts yourself, for custom painting. Perhaps you could use a similar approach here too. That way you could let the List draw all parts except for the silder buttons, those parts you draw yourself for custom buttons. Just an idea.
04-01-2013 10:29 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #4
RE: Internal GUI Controls
Hi,

Yes I know what you want to achieve (what kind of functionality), but I was asking about the final effect (how the end screenshot would look like), how you want to override draw and how to draw it differently.

The Slidebar is not integrated with the List but with Region.
List is drawn separately from Slidebar.
04-01-2013 04:02 PM
Find all posts by this user Quote this message in a reply
fatcoder Offline
Member

Post: #5
RE: Internal GUI Controls
Yes, sorry, I meant the region as the slidebars are part of the region.

I use a set of 4 images for the buttons. One for the normal state, one for the hovered state (mouse over), one for the pressed state and one for the hovered and pressed state. Doing this gives a lot of freedom as to how the buttons can look in each state.

Anyway, I have managed to partly solve the problem by overriding the draw() function of the region and changing the image of the slidebar buttons as needed using code like this.

Code:
if(!slidebar[1].button[1]())
{
   if(Gui.ms() != &slidebar[1].button[1])
      slidebar[1].button[1].image = "off.gfx";
   else
      slidebar[1].button[1].image = "hover.gfx";
}
else
   slidebar[1].button[1].image = "on.gfx";

I then just repeat this code for each of the buttons in the slidebar. Not ideal, but it seems to work. However, this leaves two problems though.

1. There is no way to turn the highlighting off on the buttons. The buttons still highlight when you mouse over them. An option to turn that off for the Button control would solve that problem.

When using custom images like this, the highlight isn't necessary as any sort of "highlight" feedback is already built into the images.

2. It is not possible to change the tex_frac used in the Button control's default drawing when it calls drawButton on the image. I use a different tex_frac value, so perhaps tex_frac could be added to the Button control as a member variable that is passed through to the drawButton call.
04-02-2013 05:03 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #6
RE: Internal GUI Controls
An idea popped to my head how to do this easily:

Next release will feature new FixedArray container:
Code:
/******************************************************************************

   Use 'FixedArray' for fixed size array container.

   An example:
      int                normal_array[4];
      FixedArray<int, 4>  fixed_array   ; // 'fixed_array' is the same as 'normal_array' (stores 4 int's)

   'FixedArray' stores elements in continuous memory, for example:
      [ABCDE]

   'FixedArray' has a constant number of elements, pre-defined at the moment of array declaration,
      which means that it does not support adding/removing elements.
  
   'FixedArray' however allows to dynamically change the class of elements in this array.

/******************************************************************************/
const_mem_addr template<typename TYPE, const Int ELMS> struct FixedArray // array of fixed size, with the option to dynamically replace the type of elements !! must be stored in constant memory address !!
{
     TYPE& operator[](Int i)  {RANGE_ASSERT(i, ELMS); return *(TYPE*)((Byte*)_data+i*_elm_size);} // get i-th element in the container
   C TYPE& operator[](Int i)C {RANGE_ASSERT(i, ELMS); return *(TYPE*)((Byte*)_data+i*_elm_size);} // get i-th element in the container

   Int elms   ()C {return  ELMS    ;} // get number of          elements in this container
   Int elmSize()C {return _elm_size;} // get size   of a single element  in this container

   T1(DERIVED) FixedArray& replaceClass(); // replace the type of class stored in the container, all elements are automatically removed before changing the type of the class, the new type must be derived from the base 'TYPE' (if you're receiving a compilation error pointing to this method this means that the new class isn't derived from the base class)

   FixedArray&   del(); // manually delete, this deletes objects which were dynamically created through the 'replaceClass' method, and resets the container element class to default 'TYPE'
  ~FixedArray() {del();}
   FixedArray();

private:
   Int  _elm_size;
   TYPE _data_org[ELMS], *_data;
};
/******************************************************************************/
template<typename TYPE, const Int ELMS> inline Int Elms(C FixedArray<TYPE, ELMS> &fix_arr) {return fix_arr.elms();}
/******************************************************************************/
it will be used to store Buttons in the SlideBar, and SlideBars in Region, and allows to replace the class, but it's cool that it doesn't require memory allocation when the class is not replaced (default case).
this replaceClass should be called in extended class constructor
like this
Code:
class SlideBarEx : SlideBar
{
   SlideBarEx() {button.replaceClass<ButtonEx>();}
}

Also Button will have 2 internal methods made accessible from the header:
Code:
class Button
{
protected:
   virtual void drawImage(C Rect &screen_rect); // this method is used by 'Button.draw' method to draw the image part of the button, you can override 'draw' and manually call this method, 'screen_rect'=screen space button rectangle equal to "Button.rect+gpc.offset", this method does not set 'D.clip' (be sure to apply it manually before calling this method)
   virtual void drawText (C Rect &screen_rect); // this method is used by 'Button.draw' method to draw the text  part of the button, you can override 'draw' and manually call this method, 'screen_rect'=screen space button rectangle equal to "Button.rect+gpc.offset", this method does not set 'D.clip' (be sure to apply it manually before calling this method)
}
04-04-2013 02:12 PM
Find all posts by this user Quote this message in a reply
fatcoder Offline
Member

Post: #7
RE: Internal GUI Controls
I almost went into cardiac arrest reading this. I've never been so excited about a peice of code before! lol

Don't forget to update 1.0 too. blushing
04-04-2013 03:52 PM
Find all posts by this user Quote this message in a reply
fatcoder Offline
Member

Post: #8
RE: Internal GUI Controls
I forgot to point out that ComboBox also uses two internal controls, which makes it very hard to override the look of it to match the rest of the gui. I've had to use a lot of duplicate code and some "hacks" to make the button and cmenu look right. Would be great if you could use the FixedArray here too.

Code:
FixedArray<Button, 1> button;
FixedArray<CMenu, 1> cmenu;
04-09-2013 01:32 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #9
RE: Internal GUI Controls
Yes 1.0 will also have this.
I can add FixedArray for ComboBox button as well.
As for the ComboBox cmenu could you please give me first an example of what things you'd like to override in Cmenu class? thank you
04-09-2013 11:01 AM
Find all posts by this user Quote this message in a reply
fatcoder Offline
Member

Post: #10
RE: Internal GUI Controls
Quote:I can add FixedArray for ComboBox button as well.

Thanks for that.

Quote:As for the ComboBox cmenu could you please give me first an example of what things you'd like to override in Cmenu class?

The cmenu actually isn't a very big problem. It is mainly just the button that is the problem as my needs for the cmenu are very minor, so probably not worth the trouble for you. I just listed it above for completeness as I thought you might want to use the FixedArray for all internal controls across all gui controls, but if not that is ok.
04-09-2013 12:23 PM
Find all posts by this user Quote this message in a reply
Post Reply