Drawing a slider or a scrollbar is similar to drawing a progress bar, in that you need to express the slider’s current position as a percentage of its client rectangle, giving you the position at which to draw the “pointer” (or, for a scrollbar, the elevator). You’ll have to make some slight modifications for horizontal vs. vertical controls - I got around these by implementing a base class, gui_slider, which contained all of the common code, and all of the member variables, and then implementing two specific derivatives, gui_slider_horz and gui_slider_vert, which handled the differences in drawing and clicking logic.

As for processing mouse clicks, I opted for the easy way when I created my sliders. If a mouse click occurs in the client area of a scrollbar, I automatically scroll directly to that position. In my sliders, you can’t click in the “shaft” and move the position by a page at a time - you jump directly to where you clicked. This was a decision I made primarily because it was easy, but also because I dislike the default Windows behavior of paging.

As for the scrollbar / slider logic, you’ve got the same basic setup as a progress bar - min, max, and current positions. Unlike a progress bar, however, the user can change the current position by clicking in the control.

Now, scrollbars. I decided, for my GUI, that scrollbars are just sliders with two buttons tacked onto either side. These two buttons (the up/down or left/right arrows) move the elevator one position. This method eliminated a lot of code duplication between the pushbutton class and the scrollbars, and I would highly recommend that you take a look at doing something similar.

Now that we’ve got scrollbars, we can tackle the most complex control of them all… the listbox.

<p>The Listbox Control</p>

Resign yourself to this now - the listbox control is where you’re going to be spending the most time.

// represents a column in our listbox

class gui_listbox_column {

public:

 gui_listbox_column() {}

 virtual ~gui_listbox_column() {}

 virtual void draw(uti_rectangle& where);

 void setname(const char *name) { m_name = name; }

 uti_string getname(void) { return(m_name); }

 int getwidth(void) { return(m_width); }

 void setwidth(int w) { m_width = w; }

private:

 uti_string m_name;

 int m_width;

};

// an item in our listbox

class gui_listbox_item {

public:

 gui_listbox_item() { m_isselected = 0; m_indent = 0; }

 virtual ~gui_listbox_item() {}

 virtual drawitem(int colnum, uti_rectangle& where);

 void clearallcolumns(void); // boring

 void setindent(int i) { m_indent = i; }

 int getindent(void) { return(m_indent); }

 void settext(int colnum, const char *text); // boring

 uti_string gettext(int colnum = 0); // boring

 void setitemdata(UL itemdata) { m_itemdata = itemdata; }

 UL getitemdata(void) { return(m_itemdata); }

 void setselected(int s = 1) { m_isselected = s; }

 int getselected(void) { return(m_isselected); }

private:

 int m_isselected;

 int m_indent; // # of pixels to indent this item

 UL m_itemdata;

 uti_pointerarray m_coltext;

};

// the listbox itself

class gui_fancylistbox: public gui_window {

public:

 gui_fancylistbox() { m_multiselect = 0; }

 virtual ~gui_fancylistbox() { clear(); }

 int getselected(int iter = 0);

 virtual int wm_command(gui_window *win, int cmd, int param);

 virtual int wm_paint(coord x, coord y);

 virtual int wm_lbuttondown(coord x, coord y);

 gui_fancyscrollbar_horz& gethscroll(void) { return(m_hscroll); }

Перейти на страницу:

Похожие книги