NXWidgets: cscrollingpanel.cxx Source File

NXWidgets 1.19

cscrollingpanel.cxx
Go to the documentation of this file.
1 /****************************************************************************
2 * NxWidgets/libnxwidgets/src/cscrollingpanel.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 <stdint.h>
77 #include <stdbool.h>
78 #include <debug.h>
79
80 #include "cwidgetcontrol.hxx"
81 #include "cscrollingpanel.hxx"
82 #include "cgraphicsport.hxx"
83 #include "singletons.hxx"
84
85 /****************************************************************************
86 * Pre-Processor Definitions
87 ****************************************************************************/
88
89 /****************************************************************************
90 * Method Implementations
91 ****************************************************************************/
92
93 using namespace NXWidgets;
94
95 /**
96 * Constructor.
97 *
98 * @param pWidgetControl The widget control for the display.
99 * @param x The x coordinate of the widget.
100 * @param y The y coordinate of the widget.
101 * @param width The width of the widget.
102 * @param height The height of the widget.
103 * @param flags The usual widget flags.
104 * @param style The style that the widget should use. If this is not
105 * specified, the widget will use the values stored in the global
106 * g_defaultWidgetStyle object. The widget will copy the properties of
107 * the style into its own internal style object.
108 */
109
110 CScrollingPanel::CScrollingPanel(CWidgetControl *pWidgetControl,
111 nxgl_coord_t x, nxgl_coord_t y,
112 nxgl_coord_t width, nxgl_coord_t height,
113 uint32_t flags, CWidgetStyle* style)
114 : CNxWidget(pWidgetControl, x, y, width, height, flags, style)
115 {
116 m_widgetControl = pWidgetControl;
117
118 // NOTE: CScrollingPanel is temporarily borderless because there was no
119 // easy way to redraw only the required part of the border.
120
121 m_flags.permeable = true;
122 m_flags.borderless = true;
123
124 CRect rect;
125 getClientRect(rect);
126
127 m_canvasWidth = rect.getWidth();
128 m_canvasHeight = rect.getHeight();
129 m_canvasX = 0;
130 m_canvasY = 0;
131
132 setAllowsVerticalScroll(true);
133 setAllowsHorizontalScroll(true);
134 setContentScrolled(true);
135 }
136
137 /**
138 * Scroll the panel by the specified amounts.
139 *
140 * @param dx The horizontal distance to scroll.
141 * @param dy The vertical distance to scroll.
142 */
143
144 void CScrollingPanel::scroll(int32_t dx, int32_t dy)
145 {
146 CRect rect;
147 getClientRect(rect);
148
149 // Prevent scrolling outside boundaries
150
151 if (m_canvasX + dx < -(m_canvasWidth - rect.getWidth()))
152 {
153 dx = -(m_canvasWidth - rect.getWidth()) - m_canvasX;
154 }
155 else if (m_canvasX + dx > 0)
156 {
157 dx = -m_canvasX;
158 }
159
160 if (m_canvasY + dy < -(m_canvasHeight - rect.getHeight()))
161 {
162 dy = -(m_canvasHeight - rect.getHeight()) - m_canvasY;
163 }
164 else if (m_canvasY + dy > 0)
165 {
166 dy = -m_canvasY;
167 }
168
169 // Prevent scrolling in disallowed planes
170
171 if (!allowsVerticalScroll())
172 {
173 dy = 0;
174 }
175
176 if (!allowsHorizontalScroll())
177 {
178 dx = 0;
179 }
180
181 // Perform scroll if necessary
182
183 if ((dx != 0) || (dy != 0))
184 {
185 // Only scroll if content scrolling is enabled
186
187 if (m_isContentScrolled)
188 {
189 // Perform scroll
190
191 TNxArray<CRect> revealedRects;
192 CGraphicsPort *port = m_widgetControl->getGraphicsPort();
193 port->move(getX(), getY(), dx, dy, rect.getWidth(), rect.getHeight());
194
195 if (dx > 0)
196 {
197 revealedRects.push_back(CRect(getX(), getY(), dx, rect.getHeight()));
198 }
199 else if (dx < 0)
200 {
201 revealedRects.push_back(CRect(getX() + rect.getWidth() + dx, getY(), -dx, rect.getHeight()));
202 }
203
204 if (dy > 0)
205 {
206 revealedRects.push_back(CRect(getX(), getY(), rect.getWidth(), dy));
207 }
208 else if (dy < 0)
209 {
210 revealedRects.push_back(CRect(getX(), getY() + rect.getHeight() + dy, rect.getWidth(), -dy));
211 }
212
213 // Adjust the scroll values
214
215 m_canvasY += dy;
216 m_canvasX += dx;
217
218 // Move children but do not redraw.
219
220 scrollChildren(dx, dy, false);
221
222 if (revealedRects.size() > 0)
223 {
224 // Draw background to revealed sections
225
226 for (int i = 0; i < revealedRects.size(); ++i)
227 {
228 CRect &rrect = revealedRects[i];
229
230 ginfo("Redrawing %d,%d,%d,%d after scroll\n",
231 rrect.getX(), rrect.getY(),
232 rrect.getWidth(), rrect.getHeight());
233
234 port->drawFilledRect(rrect.getX(), rrect.getY(),
235 rrect.getWidth(), rrect.getHeight(),
236 getBackgroundColor());
237
238 // Check if any children intersect this region.
239 // If it does, it should be redrawn.
240
241 for (int j = 0; j < m_children.size(); ++j)
242 {
243 CRect crect = m_children[j]->getBoundingBox();
244 if (crect.intersects(rrect))
245 {
246 m_children[j]->redraw();
247 }
248 }
249 }
250 }
251 }
252 else
253 {
254 // Adjust the scroll values
255
256 m_canvasY += dy;
257 m_canvasX += dx;
258
259 // Scroll all child widgets and redraw them
260
261 scrollChildren(dx, dy, true);
262 }
263
264 // Notify event handlers
265
266 m_widgetEventHandlers->raiseScrollEvent(dx, dy);
267 }
268 }
269
270 /**
271 * Reposition the panel's scrolling region to the specified coordinates.
272 *
273 * @param x The new x coordinate of the scrolling region.
274 * @param y The new y coordinate of the scrolling region.
275 */
276
277 void CScrollingPanel::jump(int32_t x, int32_t y)
278 {
279 // Calculate difference between jump value and current value and scroll
280
281 scroll(x - m_canvasX, y - m_canvasY);
282 }
283
284 /**
285 * Draw the area of this widget that falls within the clipping region.
286 * Called by the redraw() function to draw all visible regions.
287 *
288 * @param port The CGraphicsPort to draw to.
289 * @see redraw()
290 */
291
292 void CScrollingPanel::drawContents(CGraphicsPort *port)
293 {
294 port->drawFilledRect(getX(), getY(), getWidth(), getHeight(),
295 getBackgroundColor());
296 }
297
298 /**
299 * Draw the area of this widget that falls within the clipping region.
300 * Called by the redraw() function to draw all visible regions.
301 *
302 * @param port The CGraphicsPort to draw to.
303 * @see redraw()
304 */
305
306 void CScrollingPanel::drawBorder(CGraphicsPort *port)
307 {
308 // Stop drawing if the widget indicates it should not have an outline
309
310 if (!isBorderless())
311 {
312 port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(),
313 getShadowEdgeColor(), getShineEdgeColor());
314 }
315 }
316
317 /**
318 * Scrolls the panel to match the drag.
319 *
320 * @param x The x coordinate of the mouse.
321 * @param y The y coordinate of the mouse.
322 * @param vX The horizontal drag distance.
323 * @param vY The vertical drag distance.
324 */
325
326 void CScrollingPanel::onDrag(nxgl_coord_t x, nxgl_coord_t y,
327 nxgl_coord_t vX, nxgl_coord_t vY)
328 {
329 scroll(vX, vY);
330 }
331
332 /**
333 * Starts the dragging system.
334 *
335 * @param x The x coordinate of the click.
336 * @param y The y coordinate of the click.
337 */
338
339 void CScrollingPanel::onClick(nxgl_coord_t x, nxgl_coord_t y)
340 {
341 startDragging(x, y);
342 }
343
344 /**
345 * Scroll all child widgets by the specified amounts. Actually uses
346 * the widget's moveTo() function to reposition them.
347 *
348 * @param dx The horizontal distance to scroll.
349 * @param dy The vertical distance to scroll.
350 * @param do_redraw Redraw widgets after moving.
351 */
352
353 void CScrollingPanel::scrollChildren(int32_t dx, int32_t dy, bool do_redraw)
354 {
355 nxgl_coord_t widgetX = 0;
356 nxgl_coord_t widgetY = 0;
357 nxgl_coord_t thisX = getX();
358 nxgl_coord_t thisY = getY();
359 CNxWidget *widget = (CNxWidget *)NULL;
360
361 for (int32_t i = 0; i < m_children.size(); i++)
362 {
363 widget = m_children[i];
364 bool oldstate = widget->isDrawingEnabled();
365
366 if (!do_redraw)
367 {
368 widget->disableDrawing();
369 }
370
371 widgetX = (widget->getX() - thisX) + dx;
372 widgetY = (widget->getY() - thisY) + dy;
373 widget->moveTo(widgetX, widgetY);
374
375 if (!do_redraw && oldstate)
376 {
377 widget->enableDrawing();
378 }
379 }
380 }
NXWidgets::CNxWidget
Definition: cnxwidget.hxx:121
NXWidgets::CScrollingPanel::allowsVerticalScroll
bool allowsVerticalScroll(void) const
Definition: cscrollingpanel.hxx:236
NXWidgets::CScrollingPanel::drawBorder
virtual void drawBorder(CGraphicsPort *port)
Definition: cscrollingpanel.cxx:306
NXWidgets::CNxWidget::isBorderless
bool isBorderless(void) const
Definition: cnxwidget.hxx:549
NXWidgets::CWidgetEventHandlerList::raiseScrollEvent
void raiseScrollEvent(nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cwidgeteventhandlerlist.cxx:527
NXWidgets::CNxWidget::getShadowEdgeColor
nxgl_mxpixel_t getShadowEdgeColor(void) const
Definition: cnxwidget.hxx:749
NXWidgets::CWidgetStyle
Definition: cwidgetstyle.hxx:125
NXWidgets::CRect::getHeight
nxgl_coord_t getHeight(void) const
Definition: crect.hxx:204
NXWidgets::CWidgetControl::getGraphicsPort
CGraphicsPort * getGraphicsPort(void)
Definition: cwidgetcontrol.hxx:769
NXWidgets::CNxWidget::moveTo
bool moveTo(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:990
NXWidgets::CWidgetControl
Definition: cwidgetcontrol.hxx:95
singletons.hxx
NXWidgets::CNxWidget::disableDrawing
void disableDrawing(void)
Definition: cnxwidget.hxx:908
NXWidgets::CRect::getWidth
nxgl_coord_t getWidth(void) const
Definition: crect.hxx:181
NXWidgets::CGraphicsPort::drawBevelledRect
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)
Definition: cgraphicsport.cxx:323
NXWidgets::CRect::getX
nxgl_coord_t getX(void) const
Definition: crect.hxx:160
NXWidgets::CRect::intersects
bool intersects(const CRect &rect) const
Definition: crect.cxx:318
NXWidgets::CScrollingPanel::onClick
virtual void onClick(nxgl_coord_t x, nxgl_coord_t y)
Definition: cscrollingpanel.cxx:339
cgraphicsport.hxx
NXWidgets::CNxWidget::getBackgroundColor
nxgl_mxpixel_t getBackgroundColor(void) const
Definition: cnxwidget.hxx:716
NXWidgets::CScrollingPanel::setContentScrolled
void setContentScrolled(bool scrolled)
Definition: cscrollingpanel.hxx:329
cwidgetcontrol.hxx
NXWidgets::CScrollingPanel::m_canvasHeight
int32_t m_canvasHeight
Definition: cscrollingpanel.hxx:114
NXWidgets::CScrollingPanel::m_widgetControl
CWidgetControl * m_widgetControl
Definition: cscrollingpanel.hxx:108
NXWidgets::CScrollingPanel::allowsHorizontalScroll
bool allowsHorizontalScroll(void) const
Definition: cscrollingpanel.hxx:247
NXWidgets
Definition: cbgwindow.hxx:65
NXWidgets::CNxWidget::getHeight
nxgl_coord_t getHeight(void) const
Definition: cnxwidget.hxx:593
NXWidgets::CScrollingPanel::CScrollingPanel
CScrollingPanel(const CScrollingPanel &scrollingPanel)
Definition: cscrollingpanel.hxx:186
NXWidgets::CNxWidget::getClientRect
void getClientRect(CRect &rect) const
Definition: cnxwidget.cxx:421
NXWidgets::CScrollingPanel::drawContents
virtual void drawContents(CGraphicsPort *port)
Definition: cscrollingpanel.cxx:292
TNxArray
Definition: tnxarray.hxx:109
NXWidgets::CGraphicsPort::drawFilledRect
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
Definition: cgraphicsport.cxx:280
NXWidgets::CScrollingPanel::setAllowsHorizontalScroll
void setAllowsHorizontalScroll(bool allow)
Definition: cscrollingpanel.hxx:313
NXWidgets::CScrollingPanel::m_canvasWidth
int32_t m_canvasWidth
Definition: cscrollingpanel.hxx:113
NXWidgets::CScrollingPanel::scrollChildren
void scrollChildren(int32_t dx, int32_t dy, bool do_redraw)
Definition: cscrollingpanel.cxx:353
NXWidgets::CNxWidget::getShineEdgeColor
nxgl_mxpixel_t getShineEdgeColor(void) const
Definition: cnxwidget.hxx:738
TNxArray::push_back
void push_back(const T &value)
Definition: tnxarray.hxx:267
NXWidgets::CNxWidget::enableDrawing
void enableDrawing(void)
Definition: cnxwidget.hxx:917
NXWidgets::CNxWidget::m_widgetEventHandlers
CWidgetEventHandlerList * m_widgetEventHandlers
Definition: cnxwidget.hxx:191
NXWidgets::CRect
Definition: crect.hxx:101
NXWidgets::CScrollingPanel::scroll
virtual void scroll(int32_t dx, int32_t dy)
Definition: cscrollingpanel.cxx:144
NXWidgets::CNxWidget::getY
nxgl_coord_t getY(void) const
Definition: cnxwidget.cxx:261
NXWidgets::CScrollingPanel::setAllowsVerticalScroll
void setAllowsVerticalScroll(bool allow)
Definition: cscrollingpanel.hxx:302
NXWidgets::CNxWidget::getWidth
nxgl_coord_t getWidth(void) const
Definition: cnxwidget.hxx:582
NXWidgets::CNxWidget::getX
nxgl_coord_t getX(void) const
Definition: cnxwidget.cxx:245
NXWidgets::CGraphicsPort::move
void move(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t deltaX, nxgl_coord_t deltaY, nxgl_coord_t width, nxgl_coord_t height)
Definition: cgraphicsport.cxx:886
NXWidgets::CNxWidget::Flags::permeable
uint8_t permeable
Definition: cnxwidget.hxx:152
NXWidgets::CRect::getY
nxgl_coord_t getY(void) const
Definition: crect.hxx:170
NXWidgets::CScrollingPanel::m_canvasX
int32_t m_canvasX
Definition: cscrollingpanel.hxx:109
NXWidgets::CScrollingPanel::m_isContentScrolled
bool m_isContentScrolled
Definition: cscrollingpanel.hxx:119
TNxArray::size
const int size(void) const
Definition: tnxarray.hxx:261
NXWidgets::CNxWidget::Flags::borderless
uint8_t borderless
Definition: cnxwidget.hxx:148
cscrollingpanel.hxx
NXWidgets::CNxWidget::m_children
TNxArray< CNxWidget * > m_children
Definition: cnxwidget.hxx:204
NXWidgets::CNxWidget::isDrawingEnabled
bool isDrawingEnabled(void) const
Definition: cnxwidget.cxx:325
NXWidgets::CNxWidget::startDragging
void startDragging(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:1542
NXWidgets::CScrollingPanel::m_canvasY
int32_t m_canvasY
Definition: cscrollingpanel.hxx:111
NXWidgets::CScrollingPanel::jump
virtual void jump(int32_t x, int32_t y)
Definition: cscrollingpanel.cxx:277
NXWidgets::CScrollingPanel::onDrag
virtual void onDrag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cscrollingpanel.cxx:326
NXWidgets::CGraphicsPort
Definition: cgraphicsport.hxx:106
NXWidgets::CNxWidget::m_flags
Flags m_flags
Definition: cnxwidget.hxx:187