NXWidgets  1.19
ccyclebutton.cxx
Go to the documentation of this file.
1 /****************************************************************************
2  * NxWidgets/libnxwidgets/src/ccyclebutton.cxx
3  *
4  * Copyright (C) 2012 Gregory Nutt. All rights reserved.
5  * Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
18  * me be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ****************************************************************************
35  *
36  * Portions of this package derive from Woopsi (http://woopsi.org/) and
37  * portions are original efforts. It is difficult to determine at this
38  * point what parts are original efforts and which parts derive from Woopsi.
39  * However, in any event, the work of Antony Dzeryn will be acknowledged
40  * in most NxWidget files. Thanks Antony!
41  *
42  * Copyright (c) 2007-2011, Antony Dzeryn
43  * All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions are met:
47  *
48  * * Redistributions of source code must retain the above copyright
49  * notice, this list of conditions and the following disclaimer.
50  * * Redistributions in binary form must reproduce the above copyright
51  * notice, this list of conditions and the following disclaimer in the
52  * documentation and/or other materials provided with the distribution.
53  * * Neither the names "Woopsi", "Simian Zombie" nor the
54  * names of its contributors may be used to endorse or promote products
55  * derived from this software without specific prior written permission.
56  *
57  * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``AS IS'' AND ANY
58  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60  * DISCLAIMED. IN NO EVENT SHALL Antony Dzeryn BE LIABLE FOR ANY
61  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67  *
68  ****************************************************************************/
69 
70 /****************************************************************************
71  * Included Files
72  ****************************************************************************/
73 
74 #include <nuttx/config.h>
75 
76 #include <sys/types.h>
77 #include <stdint.h>
78 #include <stdbool.h>
79 
80 #include <nuttx/nx/nxglib.h>
81 
82 #include "ccyclebutton.hxx"
83 #include "cgraphicsport.hxx"
84 #include "cbitmap.hxx"
85 #include "glyphs.hxx"
86 
87 /****************************************************************************
88  * Pre-Processor Definitions
89  ****************************************************************************/
90 
91 /****************************************************************************
92  * CButton Method Implementations
93  ****************************************************************************/
94 
95 using namespace NXWidgets;
96 
97 /**
98  * Constructor for cycle buttons.
99  *
100  * @param pWidgetControl The widget control for the display.
101  * @param x The x coordinate of the button, relative to its parent.
102  * @param y The y coordinate of the button, relative to its parent.
103  * @param width The width of the button.
104  * @param height The height of the button.
105  * @param style The style that the button should use. If this is not
106  * specified, the button will use the values stored in the global
107  * g_defaultWidgetStyle object. The button will copy the properties of
108  * the style into its own internal style object.
109  */
110 
112  nxgl_coord_t x, nxgl_coord_t y,
113  nxgl_coord_t width, nxgl_coord_t height,
114  CWidgetStyle *style)
115 : CButton(pWidgetControl, x, y, width, height, "", style)
116 {
117  // Force text to align left
118 
119  nxgl_coord_t glyphSpace = m_borderSize.left - 1;
120 
121  // Text x coordinate is width of cycle glyph plus a space plus width
122  // of the spacer line (2px) plus a space
123 
124  m_align.x = g_cycle.width + 2 + (glyphSpace << 1);
125 
128 }
129 
130 /**
131  * Add a new option to the widget.
132  *
133  * @param text The text of the option.
134  * @param value The value of the option.
135  */
136 
137 void CCycleButton::addOption(const CNxString &text, const uint32_t value)
138 {
139  m_options.addItem(new CListDataItem(text, value));
140 
141  // Select the option if this is the first option added
142 
143  if (m_options.getItemCount() == 1)
144  {
145  selectOption(0);
146  }
147 }
148 
149 /**
150  * Remove an option from the widget by its index.
151  *
152  * @param index The index of the option to remove.
153  */
154 
155 void CCycleButton::removeOption(const int index)
156 {
157  m_options.removeItem(index);
158 }
159 
160 /**
161  * Remove all options from the widget.
162  */
163 
165 {
167 }
168 
169 /**
170  * Select an option by its index.
171  * Redraws the widget and raises a value changed event.
172  *
173  * @param index The index of the option to select.
174  */
175 
176 void CCycleButton::selectOption(const int index)
177 {
178  m_options.setItemSelected(index, true);
179 }
180 
181 /**
182  * Get the selected index. Returns -1 if nothing is selected. If more than one
183  * option is selected, the index of the first selected option is returned.
184  *
185  * @return The selected index.
186  */
187 
188 const int CCycleButton::getSelectedIndex(void) const
189 {
190  return m_options.getSelectedIndex();
191 }
192 
193 /**
194  * Sets the selected index. Specify -1 to select nothing. Resets any
195  * other selected options to deselected.
196  * Redraws the widget and raises a value changed event.
197  *
198  * @param index The selected index.
199  */
200 
201 void CCycleButton::setSelectedIndex(const int index)
202 {
203  m_options.setItemSelected(index, true);
204 }
205 
206 /**
207  * Get the selected option. Returns NULL if nothing is selected.
208  *
209  * @return The selected option.
210  */
211 
213 {
214  return m_options.getSelectedItem();
215 }
216 
217 /**
218  * Sort the options alphabetically by the text of the options.
219  */
220 
222 {
223  m_options.sort();
224 }
225 
226 /**
227  * Handles list data changed events.
228  *
229  * @param e Event arguments.
230  */
231 
233 {
234  redraw();
235 }
236 
237 /**
238  * Handles list selection changed events.
239  *
240  * @param e Event arguments.
241  */
242 
244 {
245  redraw();
247 }
248 
249 /**
250  * Insert the dimensions that this widget wants to have into the rect
251  * passed in as a parameter. All coordinates are relative to the widget's
252  * parent. Value is based on the length of the largest string in the
253  * set of options.
254  *
255  * @param rect Reference to a rect to populate with data.
256  */
257 
259 {
260  nxgl_coord_t width = 0;
261  nxgl_coord_t height = getFont()->getHeight();
262 
263  // Locate longest string in options
264 
265  for (int i = 0; i < m_options.getItemCount(); ++i)
266  {
267  nxgl_coord_t optionWidth =
269 
270  if (optionWidth > width)
271  {
272  width = optionWidth;
273  }
274  }
275 
276  // Add the border width
277 
278  if (!m_flags.borderless)
279  {
280  width += (m_borderSize.left + m_borderSize.right);
281  height += (m_borderSize.top + m_borderSize.bottom);
282  }
283 
284  // Add text alignment
285 
286  width += m_align.x;
287  height += m_align.y;
288 
289  // And returned this preferred size
290 
291  rect.setX(m_rect.getX());
292  rect.setY(m_rect.getY());
293  rect.setWidth(width);
294  rect.setHeight(height);
295 }
296 
297 /**
298  * Draw the area of this widget that falls within the clipping region.
299  * Called by the redraw() function to draw all visible regions.
300  *
301  * @param port The CGraphicsPort to draw to.
302  * @see redraw()
303  */
304 
306 {
307  // Get the drawing region (excluding any border)
308 
309  CRect rect;
310  getRect(rect);
311 
312  nxgl_coord_t glyphYOffset = (rect.getHeight() - g_cycle.height) >> 1;
313 
314  nxwidget_pixel_t textColor;
315 
316  if (!isEnabled())
317  {
318  textColor = getDisabledTextColor();
319  }
320  else if (!isClicked())
321  {
322  textColor = getEnabledTextColor();
323  }
324  else
325  {
326  textColor = getSelectedTextColor();
327  }
328 
329  // Draw cycle glyph
330 
331  port->drawBitmap(rect.getX(), rect.getY() + glyphYOffset,
333  0, 0, CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
334 
335  // Only draw text if option is selected
336 
337  if (m_options.getSelectedItem() != NULL)
338  {
339  struct nxgl_point_s pos;
340  pos.x = getX() + m_align.x;
341  pos.y = getY() + m_align.y;
342 
343  port->drawText(&pos, &rect, getFont(),
346  textColor);
347  }
348 }
349 
350 /**
351  * Draw the area of this widget that falls within the clipping region.
352  * Called by the redraw() function to draw all visible regions.
353  *
354  * @param port The CGraphicsPort to draw to.
355  * @see redraw()
356  */
357 
359 {
360  // Determine the background color
361 
362  nxwidget_pixel_t backColor;
363 
364  if (isClicked() || m_highlighted)
365  {
366  backColor = getSelectedBackgroundColor();
367  }
368  else
369  {
370  backColor = getBackgroundColor();
371  }
372 
373  // Draw the background (excluding the border)
374 
375  port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), backColor);
376 
377  // Then add the border.
378 
379  drawOutline(port);
380 }
381 
382 /**
383  * Draws the outline of the button.
384  *
385  * @param port Graphics port to draw to.
386  */
387 
389 {
390  // Stop drawing if the widget indicates it should not have an outline
391 
392  if (isBorderless())
393  {
394  return;
395  }
396 
397  // Work out which colors to use
398 
399  nxgl_coord_t color1;
400  nxgl_coord_t color2;
401 
402  if (isClicked())
403  {
404  // Bevelled into the screen
405 
406  color1 = getShadowEdgeColor();
407  color2 = getShineEdgeColor();
408  }
409  else
410  {
411  // Bevelled out of the screen
412 
413  color1 = getShineEdgeColor();
414  color2 = getShadowEdgeColor();
415  }
416 
417  port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), color1, color2);
418 }
419 
420 /**
421  * Selects the next option in the list and redraws the button.
422  *
423  * @param x The x coordinate of the mouse.
424  * @param y The y coordinate of the mouse.
425  */
426 
427 void CCycleButton::onPreRelease(nxgl_coord_t x, nxgl_coord_t y)
428 {
429  // Choose next option
430 
431  if (m_options.getItemCount() > 1)
432  {
433  int selectedIndex = m_options.getSelectedIndex();
434 
435  if (selectedIndex < m_options.getItemCount() - 1)
436  {
437  // Move to next option
438 
439  selectOption(selectedIndex + 1);
440  }
441  else
442  {
443  // Wrap around as there are no more options
444 
445  selectOption(0);
446  }
447  }
448 
449  redraw();
450 
451  CButton::onPreRelease(x, y);
452 }
453 
454 /**
455  * Redraws the button.
456  *
457  * @param x The x coordinate of the mouse.
458  * @param y The y coordinate of the mouse.
459  */
460 
461 void CCycleButton::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y)
462 {
463  redraw();
464 }
465 
WidgetBorderSize m_borderSize
Definition: cnxwidget.hxx:208
bool isClicked(void) const
Definition: cnxwidget.hxx:560
bool isBorderless(void) const
Definition: cnxwidget.hxx:549
nxgl_mxpixel_t getShadowEdgeColor(void) const
Definition: cnxwidget.hxx:749
CCycleButton(const CCycleButton &cycleButton)
nxgl_coord_t getHeight(void) const
Definition: crect.hxx:204
virtual void getPreferredDimensions(CRect &rect) const
virtual const CListDataItem * getItem(const int index) const
Definition: clistdata.hxx:260
virtual void removeAllOptions(void)
void getRect(CRect &rect) const
Definition: cnxwidget.cxx:448
void drawBevelledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t shineColor, nxgl_mxpixel_t shadowColor)
nxgl_coord_t getX(void) const
Definition: crect.hxx:160
virtual void removeItem(const int index)
Definition: clistdata.cxx:159
virtual const CListDataItem * getSelectedOption(void) const
void drawBitmap(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, const struct SBitmap *bitmap, int bitmapX, int bitmapY)
nxgl_mxpixel_t getBackgroundColor(void) const
Definition: cnxwidget.hxx:716
void addOption(const CNxString &text, const uint32_t value)
const struct SBitmap g_cycle
Definition: glyphs.hxx:122
struct nxgl_point_s m_align
Definition: clabel.hxx:140
virtual void onPreRelease(nxgl_coord_t x, nxgl_coord_t y)
virtual const CListDataItem * getSelectedItem(void) const
Definition: clistdata.cxx:255
uint8_t nxwidget_pixel_t
Definition: nxconfig.hxx:442
bool isEnabled(void) const
Definition: cnxwidget.cxx:381
nxgl_coord_t getStringWidth(const CNxString &text) const
Definition: cnxfont.cxx:142
virtual void handleListDataSelectionChangedEvent(const CListDataEventArgs &e)
nxgl_mxpixel_t getEnabledTextColor(void) const
Definition: cnxwidget.hxx:782
virtual void sort(void)
Definition: clistdata.cxx:271
virtual void onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y)
nxgl_coord_t getHeight(void) const
Definition: cnxwidget.hxx:593
virtual void onPreRelease(nxgl_coord_t x, nxgl_coord_t y)
Definition: cbutton.cxx:284
virtual const int getSelectedIndex(void) const
virtual void removeOption(const int index)
void setHeight(nxgl_coord_t height)
Definition: crect.hxx:261
virtual const int getSelectedIndex(void) const
Definition: clistdata.cxx:222
virtual void sort(void)
void setX(nxgl_coord_t x)
Definition: crect.hxx:229
nxgl_mxpixel_t getSelectedBackgroundColor(void) const
Definition: cnxwidget.hxx:727
virtual const int getItemCount(void) const
Definition: clistdata.hxx:284
virtual void removeAllItems(void)
Definition: clistdata.cxx:202
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
CNxFont * getFont(void) const
Definition: cnxwidget.hxx:705
const CNxString & getText(void) const
nxgl_coord_t height
Definition: cbitmap.hxx:108
nxgl_mxpixel_t getShineEdgeColor(void) const
Definition: cnxwidget.hxx:738
void addListDataEventHandler(IListDataEventHandler *eventHandler)
Definition: clistdata.hxx:341
const uint8_t getHeight(void) const
Definition: cnxfont.hxx:229
virtual void handleListDataChangedEvent(const CListDataEventArgs &e)
CWidgetEventHandlerList * m_widgetEventHandlers
Definition: cnxwidget.hxx:191
const unsigned int getLength(void) const
Definition: cnxstring.hxx:325
nxgl_coord_t width
Definition: cbitmap.hxx:107
virtual void drawBorder(CGraphicsPort *port)
virtual void setAllowMultipleSelections(const bool allowMultipleSelections)
Definition: clistdata.hxx:249
nxgl_coord_t getY(void) const
Definition: cnxwidget.cxx:261
void setWidth(nxgl_coord_t width)
Definition: crect.hxx:250
nxgl_coord_t getWidth(void) const
Definition: cnxwidget.hxx:582
nxgl_coord_t getX(void) const
Definition: cnxwidget.cxx:245
virtual void selectOption(const int index)
nxgl_coord_t getY(void) const
Definition: crect.hxx:170
nxgl_mxpixel_t getDisabledTextColor(void) const
Definition: cnxwidget.hxx:771
virtual void setItemSelected(const int index, const bool selected)
Definition: clistdata.cxx:317
void setY(nxgl_coord_t y)
Definition: crect.hxx:240
void drawText(struct nxgl_point_s *pos, CRect *bound, CNxFont *font, const CNxString &string)
virtual void addItem(const CNxString &text, const uint32_t value)
Definition: clistdata.cxx:119
virtual void drawOutline(CGraphicsPort *port)
nxgl_mxpixel_t getSelectedTextColor(void) const
Definition: cnxwidget.hxx:793
virtual void setSelectedIndex(const int index)
virtual void drawContents(CGraphicsPort *port)