Dillo v3.1.1-14-g8f67d6e0
Loading...
Searching...
No Matches
widget.cc
Go to the documentation of this file.
1/*
2 * Dillo Widget
3 *
4 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
5 * Copyright 2023-2024 Rodrigo Arias Mallo <rodarima@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "core.hh"
22
23#include "../lout/msg.h"
24#include "../lout/debug.hh"
25
26using namespace lout;
27using namespace lout::object;
28using namespace lout::misc;
29
30namespace dw {
31namespace core {
32
33// ----------------------------------------------------------------------
34
39
40void Widget::WidgetImgRenderer::getBgArea (int *x, int *y, int *width,
41 int *height)
42{
43 widget->getPaddingArea (x, y, width, height);
44}
45
46void Widget::WidgetImgRenderer::getRefArea (int *xRef, int *yRef, int *widthRef,
47 int *heightRef)
48{
49 widget->getPaddingArea (xRef, yRef, widthRef, heightRef);
50}
51
53{
54 return widget->getStyle ();
55}
56
57void Widget::WidgetImgRenderer::draw (int x, int y, int width, int height)
58{
59 widget->queueDrawArea (x - widget->allocation.x, y - widget->allocation.y,
60 width, height);
61}
62
63// ----------------------------------------------------------------------
64
65bool Widget::adjustMinWidth = true;
66int Widget::CLASS_ID = -1;
67
69{
70 DBG_OBJ_CREATE ("dw::core::Widget");
71 registerName ("dw::core::Widget", &CLASS_ID);
72
75
78 setWidgetReference (NULL);
79 DBG_OBJ_SET_PTR ("container", container);
80
81 layout = NULL;
82
83 allocation.x = -1;
84 allocation.y = -1;
85 allocation.width = 1;
88
90
91 style = NULL;
92 bgColor = NULL;
93 buttonSensitive = true;
94 buttonSensitiveSet = false;
95
96 deleteCallbackData = NULL;
97 deleteCallbackFunc = NULL;
98
99 widgetImgRenderer = NULL;
100
101 stackingContextMgr = NULL;
102}
103
105{
108
109 if (widgetImgRenderer) {
112 delete widgetImgRenderer;
113 }
114
116 delete stackingContextMgr;
117
118 if (style)
119 style->unref ();
120
121 if (parent)
122 parent->removeChild (this);
123 else if (layout)
125
127}
128
129
139bool Widget::intersects (Widget *refWidget, Rectangle *area,
140 Rectangle *intersection)
141{
142 DBG_OBJ_ENTER ("draw", 0, "intersects", "%p, [%d, %d, %d * %d]",
143 refWidget, area->x, area->y, area->width, area->height);
144 bool r;
145
146 if (wasAllocated ()) {
147 *intersection = *area;
148 intersection->x += refWidget->allocation.x;
149 intersection->y += refWidget->allocation.y;
150
151 r = true;
152 // "RefWidget" is excluded; it is assumed that "area" its already within
153 // its allocation.
154 for (Widget *widget = this; r && widget != refWidget;
155 widget = widget->parent) {
156 assert (widget != NULL); // refWidget must be ancestor.
157
158 Rectangle widgetArea, newIntersection;
159 widgetArea.x = widget->allocation.x;
160 widgetArea.y = widget->allocation.y;
161 widgetArea.width = widget->allocation.width;
162 widgetArea.height = widget->getHeight ();
163
164 if (intersection->intersectsWith (&widgetArea, &newIntersection)) {
165 DBG_OBJ_MSGF ("draw", 1, "new intersection: %d, %d, %d * %d",
166 newIntersection.x, newIntersection.y,
167 newIntersection.width, newIntersection.height);
168 *intersection = newIntersection;
169 } else {
170 DBG_OBJ_MSG ("draw", 1, "no new intersection");
171 r = false;
172 }
173 }
174
175 if (r) {
176 intersection->x -= allocation.x;
177 intersection->y -= allocation.y;
178
179 DBG_OBJ_MSGF ("draw", 1, "final intersection: %d, %d, %d * %d",
180 intersection->x, intersection->y,
181 intersection->width, intersection->height);
182 }
183 } else {
184 r = false;
185 DBG_OBJ_MSG ("draw", 1, "not allocated");
186 }
187
188 if (r)
189 DBG_OBJ_LEAVE_VAL ("true: %d, %d, %d * %d",
190 intersection->x, intersection->y,
191 intersection->width, intersection->height);
192 else
193 DBG_OBJ_LEAVE_VAL0 ("false");
194
195 return r;
196}
197
202 DrawingContext *context)
203{
204 Rectangle thisArea;
205 if (intersects (layout->topLevel, context->getToplevelArea (), &thisArea))
206 draw (view, &thisArea, context);
207
208 context->addWidgetProcessedAsInterruption (this);
209}
210
213{
214 // Suitable for simple widgets, without children.
215
216 if (inAllocation (x, y))
217 return this;
218 else
219 return NULL;
220}
221
224 *context)
225{
226 Widget *widgetAtPoint = getWidgetAtPoint (x, y, context);
227 context->addWidgetProcessedAsInterruption (this);
228 return widgetAtPoint;
229}
230
232{
233 DBG_OBJ_ENTER ("construct", 0, "setParent", "%p", parent);
234
235 this->parent = parent;
237
240
242 //printf ("The %s %p becomes a child of the %s %p\n",
243 // getClassName(), this, parent->getClassName(), parent);
244
245 // Determine the container. Currently rather simple; will become
246 // more complicated when absolute and fixed positions are
247 // supported.
248 container = NULL;
249 for (Widget *widget = getParent (); widget != NULL && container == NULL;
250 widget = widget->getParent())
251 if (widget->isPossibleContainer ())
252 container = widget;
253 // If there is no possible container widget, there is
254 // (surprisingly!) also no container (i. e. the viewport is
255 // used). Does not occur in dillo, where the toplevel widget is a
256 // Textblock.
257 DBG_OBJ_SET_PTR ("container", container);
258
259 // If at all, stackingContextMgr should have set *before*, see also
260 // Widget::setStyle() and Layout::addWidget().
261 if (stackingContextMgr) {
263 while (stackingContextWidget &&
266 assert (stackingContextWidget);
268 } else
270
272
273 DBG_OBJ_LEAVE ();
274}
275
277{
278 this->quasiParent = quasiParent;
279
280 // More to do? Compare with setParent().
281
282 DBG_OBJ_SET_PTR ("quasiParent", quasiParent);
283}
284
285void Widget::queueDrawArea (int x, int y, int width, int height)
286{
289 DBG_OBJ_ENTER ("draw", 0, "queueDrawArea", "%d, %d, %d, %d",
290 x, y, width, height);
291
292 _MSG("Widget::queueDrawArea alloc(%d %d %d %d) wid(%d %d %d %d)\n",
295 x, y, width, height);
296 if (layout)
297 layout->queueDraw (x + allocation.x, y + allocation.y, width, height);
298
299 DBG_OBJ_LEAVE ();
300}
301
309void Widget::queueResize (int ref, bool extremesChanged, bool fast)
310{
311 DBG_OBJ_ENTER ("resize", 0, "queueResize", "%d, %s, %s",
312 ref, extremesChanged ? "true" : "false",
313 fast ? "true" : "false");
314
316
317 Widget *widget2, *child;
318
319 Flags resizeFlag, extremesFlag, totalFlags;
320
321 if (layout) {
322 // If RESIZE_QUEUED is set, this widget is already in the list.
323 if (!resizeQueued ())
324 layout->queueResizeList->put (this);
325
326 resizeFlag = RESIZE_QUEUED;
327 extremesFlag = EXTREMES_QUEUED;
328 } else {
329 resizeFlag = NEEDS_RESIZE;
330 extremesFlag = EXTREMES_CHANGED;
331 }
332
333 setFlags (resizeFlag);
335 markSizeChange (ref);
336
337 totalFlags = resizeFlag;
338
339 if (extremesChanged) {
340 totalFlags = (Flags)(totalFlags | extremesFlag);
341
342 setFlags (extremesFlag);
343 markExtremesChange (ref);
344 }
345
346 if (fast) {
347 if (parent) {
348 // In this case, queueResize is called from top (may be a
349 // random entry point) to bottom, so markSizeChange and
350 // markExtremesChange have to be called explicitly for the
351 // parent. The tests (needsResize etc.) are uses to check
352 // whether queueResize has been called for the parent, or
353 // whether this widget is the entry point.
354 if (parent->needsResize () || parent->resizeQueued ())
358 }
359 } else {
360 for (widget2 = parent, child = this; widget2;
361 child = widget2, widget2 = widget2->parent) {
362 if (layout && !widget2->resizeQueued ())
363 layout->queueResizeList->put (widget2);
364
365 DBG_OBJ_MSGF ("resize", 2, "setting %s and ALLOCATE_QUEUED for %p",
366 resizeFlag == RESIZE_QUEUED ?
367 "RESIZE_QUEUED" : "NEEDS_RESIZE",
368 widget2);
369
370 widget2->setFlags (resizeFlag);
371 widget2->markSizeChange (child->parentRef);
372 widget2->setFlags (ALLOCATE_QUEUED);
373
374 if (extremesChanged) {
375 widget2->setFlags (extremesFlag);
376 widget2->markExtremesChange (child->parentRef);
377 }
378
380 if (widget2->parent)
381 DBG_OBJ_MSGF ("resize", 2,
382 "checking parent %p: (%d & %d) [= %d] == %d?",
383 widget2->parent, widget2->parent->flags,
384 totalFlags, widget2->parent->flags & totalFlags,
385 totalFlags);
386 }
387
388 if (widget2->parent &&
389 (widget2->parent->flags & totalFlags) == totalFlags) {
390 widget2->parent->markSizeChange (widget2->parentRef);
391 if (extremesChanged) {
392 widget2->parent->markExtremesChange (widget2->parentRef);
393 }
394
395 break;
396 }
397 }
398
399 if (layout)
401 }
402
404
405 DBG_OBJ_LEAVE ();
406}
407
409{
410 DBG_OBJ_ENTER0 ("resize", 0, "containerSizeChanged");
411
412 // If there is a container widget (not the viewport), which has not
413 // changed its size (which can be determined by the respective
414 // flags: this method is called recursively), this widget will
415 // neither change its size. Also, the recursive iteration can be
416 // stopped, since the children of this widget will
417 if (container == NULL ||
420 // Viewport (container == NULL) or container widget has changed
421 // its size.
423 queueResizeFast (0, true);
424
425 // Even if *this* widget is not affected, children may be, so
426 // iterate over children.
428 }
429
430 DBG_OBJ_LEAVE ();
431}
432
434{
435 DBG_OBJ_ENTER0 ("resize", 0, "affectedByContainerSizeChange");
436
437 bool ret;
438
439 // This standard implementation is suitable for all widgets which
440 // call correctRequisition() and correctExtremes(), even in the way
441 // how Textblock and Image do (see comments there). Has to be kept
442 // in sync.
443
444 if (container == NULL) {
445 if (style::isAbsLength (getStyle()->width) &&
446 style::isAbsLength (getStyle()->height))
447 // Both absolute, i. e. fixed: no dependency.
448 ret = false;
449 else if (style::isPerLength (getStyle()->width) ||
450 style::isPerLength (getStyle()->height)) {
451 // Any percentage: certainly dependenant.
452 ret = true;
453 } else
454 // One or both is "auto": depends ...
455 ret =
457 usesAvailWidth () : false) ||
459 usesAvailHeight () : false);
460 } else
462
463 DBG_OBJ_LEAVE_VAL ("%s", boolToStr(ret));
464 return ret;
465}
466
468{
469 DBG_OBJ_ENTER ("resize", 0, "affectsSizeChangeContainerChild", "%p", child);
470
471 bool ret;
472
473 // From the point of view of the container. This standard
474 // implementation should be suitable for most (if not all)
475 // containers.
476
477 if (style::isAbsLength (child->getStyle()->width) &&
479 // Both absolute, i. e. fixed: no dependency.
480 ret = false;
481 else if (style::isPerLength (child->getStyle()->width) ||
482 style::isPerLength (child->getStyle()->height)) {
483 // Any percentage: certainly dependenant.
484 ret = true;
485 } else
486 // One or both is "auto": depends ...
487 ret =
488 (child->getStyle()->width == style::LENGTH_AUTO ?
489 child->usesAvailWidth () : false) ||
490 (child->getStyle()->height == style::LENGTH_AUTO ?
491 child->usesAvailHeight () : false);
492
493 DBG_OBJ_LEAVE_VAL ("%s", boolToStr(ret));
494 return ret;
495}
496
498{
499 DBG_OBJ_ENTER0 ("resize", 0, "containerSizeChangedForChildren");
500
501 // Working, but inefficient standard implementation.
504 false);
505 while (it->next ())
507 it->unref ();
508
509 DBG_OBJ_LEAVE ();
510}
511
517{
518 return false;
519}
520
526{
527 return false;
528}
529
535 Widget **references, int *x, int *y)
536{
537 assert (!queueResizeEntered ());
538
539 DBG_OBJ_ENTER ("resize", 0, "sizeRequest", "%d, ...", numPos);
540
543 for(int i = 0; i < numPos; i++)
544 DBG_OBJ_MSGF ("resize", 1, "ref #%d: %p, %d, %d",
545 i, references[i], x[i], y[i]);
547 }
548
550
551 if (resizeQueued ()) {
552 // This method is called outside of Layout::resizeIdle.
555 // The widget is not taken out of Layout::queueResizeList, since
556 // other *_QUEUED flags may still be set and processed in
557 // Layout::resizeIdle.
558 }
559
560 SizeParams newRequisitionParams (numPos, references, x, y);
561 DBG_OBJ_ASSOC_CHILD (&newRequisitionParams);
562
563 bool callImpl;
564 if (needsResize ())
565 callImpl = true;
566 else {
567 // Even if RESIZE_QUEUED / NEEDS_RESIZE is not set, calling
568 // sizeRequestImpl is necessary when the relavive positions passed here
569 // have changed.
570 callImpl = !newRequisitionParams.isEquivalent (&requisitionParams);
571 }
572
573 DBG_OBJ_MSGF ("resize", 1, "callImpl = %s", boolToStr (callImpl));
574
575 requisitionParams = newRequisitionParams;
576
577 if (callImpl) {
578 calcExtraSpace (numPos, references, x, y);
580 sizeRequestImpl (requisition, numPos, references, x, y);
581 this->requisition = *requisition;
583
584 DBG_OBJ_SET_NUM ("requisition.width", requisition->width);
585 DBG_OBJ_SET_NUM ("requisition.ascent", requisition->ascent);
586 DBG_OBJ_SET_NUM ("requisition.descent", requisition->descent);
587 } else
588 *requisition = this->requisition;
589
591
592 DBG_OBJ_LEAVE ();
593}
594
604int Widget::getMinWidth (Extremes *extremes, bool forceValue)
605{
607 if (extremes)
608 DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "[%d (%d) / %d (%d)], %s",
611 forceValue ? "true" : "false");
612 else
613 DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "(nil), %s",
614 forceValue ? "true" : "false");
615 }
616
617 int minWidth;
618
619 if (getAdjustMinWidth ()) {
620 Extremes extremes2;
621 if (extremes == NULL) {
622 if (forceValue) {
623 getExtremes (&extremes2);
624 extremes = &extremes2;
625 }
626 }
627
628 // TODO Not completely clear whether this is feasable: Within
629 // the context of getAvailWidth(false) etc., getExtremes may not
630 // be called. We ignore the minimal width then.
631 if (extremes)
632 minWidth = extremes->adjustmentWidth;
633 else
634 minWidth = 0;
635 } else
636 minWidth = 0;
637
638 DBG_OBJ_LEAVE_VAL ("%d", minWidth);
639 return minWidth;
640}
641
649int Widget::getAvailWidth (bool forceValue)
650{
651 DBG_OBJ_ENTER ("resize", 0, "getAvailWidth", "%s",
652 forceValue ? "true" : "false");
653
654 int width;
655
656 if (parent == NULL && quasiParent == NULL) {
657 DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
659
660 // TODO Consider nested layouts (e. g. <button>).
661
662 int viewportWidth =
665 width = -1;
666 calcFinalWidth (getStyle (), viewportWidth, NULL, 0, forceValue, &width);
667 if (width == -1)
668 width = viewportWidth;
669
671 } else if (parent) {
672 DBG_OBJ_MSG ("resize", 1, "delegated to parent");
674 width = parent->getAvailWidthOfChild (this, forceValue);
676 } else /* if (quasiParent) */ {
677 DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent");
679 width = quasiParent->getAvailWidthOfChild (this, forceValue);
681 }
682
683 DBG_OBJ_LEAVE_VAL ("%d", width);
684 return width;
685}
686
691int Widget::getAvailHeight (bool forceValue)
692{
693 // TODO Correct by ... not extremes, but ...? (Height extremes?)
694
695 // TODO Consider 'min-height' and 'max-height'. (Minor priority, as long as
696 // "getAvailHeight (true)" is not used.
697
698 DBG_OBJ_ENTER ("resize", 0, "getAvailHeight", "%s",
699 forceValue ? "true" : "false");
700
701 int height;
702
703 if (parent == NULL && quasiParent == NULL) {
704 DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
706
707 // TODO Consider nested layouts (e. g. <button>).
708 if (style::isAbsLength (getStyle()->height)) {
709 DBG_OBJ_MSGF ("resize", 1, "absolute height: %dpx",
710 style::absLengthVal (getStyle()->height));
711 height = style::absLengthVal (getStyle()->height) + boxDiffHeight ();
712 } else if (style::isPerLength (getStyle()->height)) {
713 DBG_OBJ_MSGF ("resize", 1, "percentage height: %g%%",
715 (getStyle()->height));
716 // Notice that here -- unlike getAvailWidth() --
717 // layout->hScrollbarThickness is not considered here;
718 // something like canvasWidthGreater (analogue to
719 // canvasHeightGreater) would be complicated and lead to
720 // possibly contradictory self-references.
721 height = applyPerHeight (layout->viewportHeight, getStyle()->height);
722 } else {
723 DBG_OBJ_MSG ("resize", 1, "no specification");
724 height = layout->viewportHeight;
725 }
726
728 } else if (parent) {
729 DBG_OBJ_MSG ("resize", 1, "delegated to parent");
731 height = parent->getAvailHeightOfChild (this, forceValue);
733 } else /* if (quasiParent) */ {
734 DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent");
736 height = quasiParent->getAvailHeightOfChild (this, forceValue);
738 }
739
740 DBG_OBJ_LEAVE_VAL ("%d", height);
741 return height;
742}
743
745 void (*splitHeightFun) (int, int *, int *),
746 bool allowDecreaseWidth,
747 bool allowDecreaseHeight)
748{
749 // TODO Correct height by ... not extremes, but ...? (Height extremes?)
750
751 DBG_OBJ_ENTER ("resize", 0, "correctRequisition",
752 "%d * (%d + %d), ..., %s, %s",
754 requisition->descent, misc::boolToStr (allowDecreaseWidth),
755 misc::boolToStr (allowDecreaseHeight));
756
757 if (parent == NULL && quasiParent == NULL) {
758 DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
760
761 int limitMinWidth = getMinWidth (NULL, true);
762 if (!allowDecreaseWidth && limitMinWidth < requisition->width)
763 limitMinWidth = requisition->width;
764
765 int viewportWidth =
768 calcFinalWidth (getStyle (), viewportWidth, NULL, limitMinWidth, false,
770
771 // For layout->viewportHeight, see comment in getAvailHeight().
772 int height = calcHeight (getStyle()->height, false,
773 layout->viewportHeight, NULL, false);
774 adjustHeight (&height, allowDecreaseHeight, requisition->ascent,
776
777 int minHeight = calcHeight (getStyle()->minHeight, false,
778 layout->viewportHeight, NULL, false);
779 adjustHeight (&minHeight, allowDecreaseHeight, requisition->ascent,
781
782 int maxHeight = calcHeight (getStyle()->maxHeight, false,
783 layout->viewportHeight, NULL, false);
784 adjustHeight (&maxHeight, allowDecreaseHeight, requisition->ascent,
786
787 // TODO Perhaps split first, then add box ascent and descent.
788 if (height != -1)
789 splitHeightFun (height, &requisition->ascent, &requisition->descent);
790 if (minHeight != -1 &&
791 requisition->ascent + requisition->descent < minHeight)
792 splitHeightFun (minHeight, &requisition->ascent,
794 if (maxHeight != -1 &&
795 requisition->ascent + requisition->descent > maxHeight)
796 splitHeightFun (maxHeight, &requisition->ascent,
798
800 } else if (parent) {
801 DBG_OBJ_MSG ("resize", 1, "delegated to parent");
803 parent->correctRequisitionOfChild (this, requisition, splitHeightFun,
804 allowDecreaseWidth,
805 allowDecreaseHeight);
807 } else /* if (quasiParent) */ {
808 DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent");
811 splitHeightFun,
812 allowDecreaseWidth,
813 allowDecreaseHeight);
815 }
816
819}
820
821void Widget::correctExtremes (Extremes *extremes, bool useAdjustmentWidth)
822{
823 DBG_OBJ_ENTER ("resize", 0, "correctExtremes", "%d (%d) / %d (%d)",
826
827 if (container == NULL && quasiParent == NULL) {
828 DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
830
831 int limitMinWidth =
832 useAdjustmentWidth ? getMinWidth (extremes, false) : 0;
833 int viewportWidth =
836
837 int width = calcWidth (getStyle()->width, viewportWidth, NULL,
838 limitMinWidth, false);
839 int minWidth = calcWidth (getStyle()->minWidth, viewportWidth, NULL,
840 limitMinWidth, false);
841 int maxWidth = calcWidth (getStyle()->maxWidth, viewportWidth, NULL,
842 limitMinWidth, false);
843
844 DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d",
845 width, minWidth, maxWidth);
846
847 if (width != -1)
849 if (minWidth != -1)
850 extremes->minWidth = minWidth;
851 if (maxWidth != -1)
852 extremes->maxWidth = maxWidth;
853
855 } else if (parent) {
856 DBG_OBJ_MSG ("resize", 1, "delegated to parent");
858 parent->correctExtremesOfChild (this, extremes, useAdjustmentWidth);
860 } else /* if (quasiParent) */ {
861 DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent");
863 quasiParent->correctExtremesOfChild (this, extremes, useAdjustmentWidth);
865 }
866
869
871}
872
883int Widget::calcWidth (style::Length cssValue, int refWidth, Widget *refWidget,
884 int limitMinWidth, bool forceValue)
885{
886 DBG_OBJ_ENTER ("resize", 0, "calcWidth", "0x%x, %d, %p, %d",
887 cssValue, refWidth, refWidget, limitMinWidth);
888
889 assert (refWidth != -1 || refWidget != NULL);
890
891 int width;
892
893 if (style::isAbsLength (cssValue)) {
894 DBG_OBJ_MSGF ("resize", 1, "absolute width: %dpx",
895 style::absLengthVal (cssValue));
896 width = misc::max (style::absLengthVal (cssValue) + boxDiffWidth (),
897 limitMinWidth);
898 } else if (style::isPerLength (cssValue)) {
899 DBG_OBJ_MSGF ("resize", 1, "percentage width: %g%%",
901 (cssValue));
902 if (refWidth != -1)
903 width = misc::max (applyPerWidth (refWidth, cssValue), limitMinWidth);
904 else {
905 int availWidth = refWidget->getAvailWidth (forceValue);
906 if (availWidth != -1) {
907 int containerWidth = availWidth - refWidget->boxDiffWidth ();
908 width = misc::max (applyPerWidth (containerWidth, cssValue),
909 limitMinWidth);
910 } else
911 width = -1;
912 }
913 } else {
914 DBG_OBJ_MSG ("resize", 1, "not specified");
915 width = -1;
916 }
917
918 DBG_OBJ_LEAVE_VAL ("%d", width);
919 return width;
920}
921
922// *finalWidth may be -1.
923/*
924 * If style has minWidth or maxWidth set, the returned value in
925 * *finalWidth is constrained to not exceed any of the set limits.
926 * */
928 Widget *refWidget, int limitMinWidth,
929 bool forceValue, int *finalWidth)
930{
931 DBG_OBJ_ENTER ("resize", 0, "calcFinalWidth", "..., %d, %p, %d, [%d]",
932 refWidth, refWidget, limitMinWidth, *finalWidth);
933
934 int width = calcWidth (style->width, refWidth, refWidget, limitMinWidth,
935 forceValue);
936 int minWidth = calcWidth (style->minWidth, refWidth, refWidget,
937 limitMinWidth, forceValue);
938 int maxWidth = calcWidth (style->maxWidth, refWidth, refWidget,
939 limitMinWidth, forceValue);
940
941 DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d",
942 width, minWidth, maxWidth);
943
944 if (width != -1)
945 *finalWidth = width;
946
947 /* Set the width if the min or max value is set and finalWidth is
948 * still -1 or exceeds the limit. Start by maxWidth so it defaults to
949 * the maximum available size. */
950 if (maxWidth != -1 && (*finalWidth == -1 || *finalWidth > maxWidth))
951 *finalWidth = maxWidth;
952 if (minWidth != -1 && (*finalWidth == -1 || *finalWidth < minWidth))
953 *finalWidth = minWidth;
954
955 DBG_OBJ_LEAVE_VAL ("%d", *finalWidth);
956}
957
958int Widget::calcHeight (style::Length cssValue, bool usePercentage,
959 int refHeight, Widget *refWidget, bool forceValue)
960{
961 // TODO Search for usage of this method and check the value of
962 // "usePercentage"; this has to be clarified.
963
964 DBG_OBJ_ENTER ("resize", 0, "calcHeight", "0x%x, %s, %d, %p",
965 cssValue, usePercentage ? "true" : "false", refHeight,
966 refWidget);
967
968 assert (refHeight != -1 || refWidget != NULL);
969
970 int height;
971
972 if (style::isAbsLength (cssValue)) {
973 DBG_OBJ_MSGF ("resize", 1, "absolute height: %dpx",
974 style::absLengthVal (cssValue));
975 height =
976 misc::max (style::absLengthVal (cssValue) + boxDiffHeight (), 0);
977 } else if (style::isPerLength (cssValue)) {
978 DBG_OBJ_MSGF ("resize", 1, "percentage height: %g%%",
979 100 *
981 if (usePercentage) {
982 if (refHeight != -1)
983 height = misc::max (applyPerHeight (refHeight, cssValue), 0);
984 else {
985 int availHeight = refWidget->getAvailHeight (forceValue);
986 if (availHeight != -1) {
987 int containerHeight = availHeight - refWidget->boxDiffHeight ();
988 height =
989 misc::max (applyPerHeight (containerHeight, cssValue), 0);
990 } else
991 height = -1;
992 }
993 } else
994 height = -1;
995 } else {
996 DBG_OBJ_MSG ("resize", 1, "not specified");
997 height = -1;
998 }
999
1000 DBG_OBJ_LEAVE_VAL ("%d", height);
1001 return height;
1002}
1003
1004void Widget::adjustHeight (int *height, bool allowDecreaseHeight, int ascent,
1005 int descent)
1006{
1007 if (!allowDecreaseHeight && *height != -1 && *height < ascent + descent)
1008 *height = ascent + descent;
1009}
1010
1014void Widget::getExtremes (Extremes *extremes, int numPos, Widget **references,
1015 int *x, int *y)
1016{
1017 assert (!queueResizeEntered ());
1018
1019 DBG_OBJ_ENTER ("resize", 0, "getExtremes", "%d, ...", numPos);
1020
1022
1023 if (extremesQueued ()) {
1024 // This method is called outside of Layout::resizeIdle.
1027 // The widget is not taken out of Layout::queueResizeList, since
1028 // other *_QUEUED flags may still be set and processed in
1029 // Layout::resizeIdle.
1030 }
1031
1032 bool callImpl;
1033 if (extremesChanged ())
1034 callImpl = true;
1035 else {
1036 // Even if EXTREMES_QUEUED / EXTREMES_CHANGED is not set, calling
1037 // getExtremesImpl is necessary when the relavive positions passed here
1038 // have changed.
1039 SizeParams newParams (numPos, references, x, y);
1040 DBG_OBJ_ASSOC_CHILD (&newParams);
1041 if (newParams.isEquivalent (&extremesParams))
1042 callImpl = false;
1043 else {
1044 callImpl = true;
1045 extremesParams = newParams;
1046 }
1047 }
1048
1049 if (callImpl) {
1050 // For backward compatibility (part 1/2):
1052
1053 getExtremesImpl (extremes, numPos, references, x, y);
1054
1055 // For backward compatibility (part 2/2):
1056 if (extremes->minWidthIntrinsic == -1)
1058 if (extremes->maxWidthIntrinsic == -1)
1060
1061 this->extremes = *extremes;
1063
1064 DBG_OBJ_SET_NUM ("extremes.minWidth", extremes->minWidth);
1065 DBG_OBJ_SET_NUM ("extremes.minWidthIntrinsic",
1067 DBG_OBJ_SET_NUM ("extremes.maxWidth", extremes->maxWidth);
1068 DBG_OBJ_SET_NUM ("extremes.maxWidthIntrinsic",
1070 DBG_OBJ_SET_NUM ("extremes.adjustmentWidth", extremes->adjustmentWidth);
1071 } else
1072 *extremes = this->extremes;
1073
1075
1076 DBG_OBJ_LEAVE ();
1077}
1078
1085void Widget::calcExtraSpace (int numPos, Widget **references, int *x, int *y)
1086{
1087 DBG_OBJ_ENTER0 ("resize", 0, "calcExtraSpace");
1088
1090 calcExtraSpaceImpl (numPos, references, x, y);
1091
1092 DBG_OBJ_SET_NUM ("extraSpace.top", extraSpace.top);
1093 DBG_OBJ_SET_NUM ("extraSpace.bottom", extraSpace.bottom);
1094 DBG_OBJ_SET_NUM ("extraSpace.left", extraSpace.left);
1095 DBG_OBJ_SET_NUM ("extraSpace.right", extraSpace.right);
1096
1097 DBG_OBJ_LEAVE ();
1098}
1099
1101{
1102 return 0;
1103}
1104
1106{
1107 misc::notImplemented ("Widget::sizeRequestReference");
1108 return NULL;
1109}
1110
1112{
1113 return 0;
1114}
1115
1117{
1118 misc::notImplemented ("Widget::getExtremesReference");
1119 return NULL;
1120}
1121
1127{
1128 assert (!queueResizeEntered ());
1129 assert (!sizeRequestEntered ());
1130 assert (!getExtremesEntered ());
1131 assert (resizeIdleEntered ());
1132
1133 DBG_OBJ_ENTER ("resize", 0, "sizeAllocate", "%d, %d; %d * (%d + %d)",
1136
1137 DBG_OBJ_MSGF ("resize", 1,
1138 "old allocation (%d, %d; %d * (%d + %d)); needsAllocate: %s",
1139 this->allocation.x, this->allocation.y, this->allocation.width,
1140 this->allocation.ascent, this->allocation.descent,
1141 needsAllocate () ? "true" : "false");
1142
1144
1145 /*printf ("The %stop-level %s %p is allocated:\n",
1146 parent ? "non-" : "", getClassName(), this);
1147 printf (" old = (%d, %d, %d + (%d + %d))\n",
1148 this->allocation.x, this->allocation.y, this->allocation.width,
1149 this->allocation.ascent, this->allocation.descent);
1150 printf (" new = (%d, %d, %d + (%d + %d))\n",
1151 allocation->x, allocation->y, allocation->width, allocation->ascent,
1152 allocation->descent);
1153 printf (" NEEDS_ALLOCATE = %s\n", needsAllocate () ? "true" : "false");*/
1154
1155 if (needsAllocate () ||
1156 allocation->x != this->allocation.x ||
1157 allocation->y != this->allocation.y ||
1158 allocation->width != this->allocation.width ||
1159 allocation->ascent != this->allocation.ascent ||
1160 allocation->descent != this->allocation.descent) {
1161
1162 if (wasAllocated ()) {
1164 this->allocation.x,
1165 this->allocation.y,
1166 this->allocation.width,
1167 this->allocation.ascent + this->allocation.descent,
1168 allocation->x,
1169 allocation->y,
1172 }
1173
1175
1176 //DEBUG_MSG (DEBUG_ALLOC, "... to %d, %d, %d x %d x %d\n",
1177 // widget->allocation.x, widget->allocation.y,
1178 // widget->allocation.width, widget->allocation.ascent,
1179 // widget->allocation.descent);
1180
1181 this->allocation = *allocation;
1184
1185 resizeDrawImpl ();
1186
1187 DBG_OBJ_SET_NUM ("allocation.x", this->allocation.x);
1188 DBG_OBJ_SET_NUM ("allocation.y", this->allocation.y);
1189 DBG_OBJ_SET_NUM ("allocation.width", this->allocation.width);
1190 DBG_OBJ_SET_NUM ("allocation.ascent", this->allocation.ascent);
1191 DBG_OBJ_SET_NUM ("allocation.descent", this->allocation.descent);
1192 }
1193
1194 /*unsetFlags (NEEDS_RESIZE);*/
1195
1197
1198 DBG_OBJ_LEAVE ();
1199}
1200
1202{
1203 return buttonPressImpl (event);
1204}
1205
1207{
1208 return buttonReleaseImpl (event);
1209}
1210
1212{
1213 return motionNotifyImpl (event);
1214}
1215
1217{
1218 enterNotifyImpl (event);
1219}
1220
1222{
1223 leaveNotifyImpl (event);
1224}
1225
1234{
1235 bool sizeChanged;
1236
1237 if (widgetImgRenderer && this->style && this->style->backgroundImage)
1240
1241 style->ref ();
1242
1243 if (this->style) {
1244 sizeChanged = this->style->sizeDiffs (style);
1245 this->style->unref ();
1246 } else
1247 sizeChanged = true;
1248
1249 this->style = style;
1250
1252
1253 if (style && style->backgroundImage) {
1254 // Create instance of WidgetImgRenderer when needed. Until this
1255 // widget is deleted, "widgetImgRenderer" will be kept, since it
1256 // is not specific to the style, but only to this widget.
1257 if (widgetImgRenderer == NULL)
1260 }
1261
1262 if (layout != NULL) {
1263 layout->updateCursor ();
1264 }
1265
1266 // After Layout::addWidget() (as toplevel widget) or Widget::setParent()
1267 // (which also sets layout), changes of the style cannot be considered
1268 // anymore. (Should print a warning?)
1269 if (layout == NULL &&
1273 stackingContextWidget = this;
1274 }
1275
1276 if (sizeChanged)
1277 queueResize (0, true);
1278 else
1279 queueDraw ();
1280
1281 // These should better be attributed to the style itself, and a
1282 // script processing RTFL messages could transfer it to something
1283 // equivalent:
1284
1285 DBG_OBJ_SET_NUM ("style.margin.top", style->margin.top);
1286 DBG_OBJ_SET_NUM ("style.margin.bottom", style->margin.bottom);
1287 DBG_OBJ_SET_NUM ("style.margin.left", style->margin.left);
1288 DBG_OBJ_SET_NUM ("style.margin.right", style->margin.right);
1289
1290 DBG_OBJ_SET_NUM ("style.border-width.top", style->borderWidth.top);
1291 DBG_OBJ_SET_NUM ("style.border-width.bottom", style->borderWidth.bottom);
1292 DBG_OBJ_SET_NUM ("style.border-width.left", style->borderWidth.left);
1293 DBG_OBJ_SET_NUM ("style.border-width.right", style->borderWidth.right);
1294
1295 DBG_OBJ_SET_NUM ("style.padding.top", style->padding.top);
1296 DBG_OBJ_SET_NUM ("style.padding.bottom", style->padding.bottom);
1297 DBG_OBJ_SET_NUM ("style.padding.left", style->padding.left);
1298 DBG_OBJ_SET_NUM ("style.padding.right", style->padding.right);
1299
1300 DBG_OBJ_SET_NUM ("style.border-spacing (h)", style->hBorderSpacing);
1301 DBG_OBJ_SET_NUM ("style.border-spacing (v)", style->vBorderSpacing);
1302
1303 DBG_OBJ_SET_SYM ("style.display",
1304 style->display == style::DISPLAY_BLOCK ? "block" :
1305 style->display == style::DISPLAY_INLINE ? "inline" :
1307 "inline-block" :
1308 style->display == style::DISPLAY_LIST_ITEM ? "list-item" :
1309 style->display == style::DISPLAY_NONE ? "none" :
1310 style->display == style::DISPLAY_TABLE ? "table" :
1312 "table-row-group" :
1314 "table-header-group" :
1316 "table-footer-group" :
1317 style->display == style::DISPLAY_TABLE_ROW ? "table-row" :
1318 style->display == style::DISPLAY_TABLE_CELL ? "table-cell" :
1319 "???");
1320
1321 DBG_OBJ_SET_NUM ("style.width (raw)", style->width);
1322 DBG_OBJ_SET_NUM ("style.min-width (raw)", style->minWidth);
1323 DBG_OBJ_SET_NUM ("style.max-width (raw)", style->maxWidth);
1324 DBG_OBJ_SET_NUM ("style.height (raw)", style->height);
1325 DBG_OBJ_SET_NUM ("style.min-height (raw)", style->minHeight);
1326 DBG_OBJ_SET_NUM ("style.max-height (raw)", style->maxHeight);
1327
1329 DBG_OBJ_SET_COL ("style.background-color",
1331 else
1332 DBG_OBJ_SET_SYM ("style.background-color", "transparent");
1333}
1334
1341{
1342 this->bgColor = bgColor;
1343}
1344
1349{
1350 Widget *widget = this;
1351
1352 while (widget != NULL) {
1353 if (widget->style->backgroundColor)
1354 return widget->style->backgroundColor;
1355 if (widget->bgColor)
1356 return widget->bgColor;
1357
1358 widget = widget->parent;
1359 }
1360
1361 return layout->getBgColor ();
1362}
1363
1364
1372 int x, int y, int width, int height, bool inverse)
1373{
1374 Rectangle canvasArea;
1375 canvasArea.x = area->x + allocation.x;
1376 canvasArea.y = area->y + allocation.y;
1377 canvasArea.width = area->width;
1378 canvasArea.height = area->height;
1379
1380 style::drawBorder (view, layout, &canvasArea,
1381 allocation.x + x, allocation.y + y,
1382 width, height, style, inverse);
1383
1384 // This method is used for inline elements, where the CSS 2 specification
1385 // does not define what here is called "reference area". To make it look
1386 // smoothly, the widget padding box is used.
1387
1388 // TODO Handle inverse drawing the same way as in drawWidgetBox?
1389 // Maybe this method (drawBox) is anyway obsolete when extraSpace
1390 // is fully supported (as here, in the "dillo_grows" repository).
1391
1392 int xPad, yPad, widthPad, heightPad;
1393 getPaddingArea (&xPad, &yPad, &widthPad, &heightPad);
1395 (view, layout, &canvasArea,
1400 height - style->margin.top - style->borderWidth.top
1402 xPad, yPad, widthPad, heightPad, style, style->backgroundColor,
1403 inverse, false);
1404}
1405
1412void Widget::drawWidgetBox (View *view, Rectangle *area, bool inverse)
1413{
1414 Rectangle canvasArea;
1415 canvasArea.x = area->x + allocation.x;
1416 canvasArea.y = area->y + allocation.y;
1417 canvasArea.width = area->width;
1418 canvasArea.height = area->height;
1419
1420 int xMar, yMar, widthMar, heightMar;
1421 getMarginArea (&xMar, &yMar, &widthMar, &heightMar);
1422 style::drawBorder (view, layout, &canvasArea, xMar, yMar, widthMar,
1423 heightMar, style, inverse);
1424
1425 int xPad, yPad, widthPad, heightPad;
1426 getPaddingArea (&xPad, &yPad, &widthPad, &heightPad);
1427
1429 if (inverse && style->backgroundColor == NULL) {
1430 // See style::drawBackground: for inverse drawing, we need a
1431 // defined background color. Search through ancestors.
1432 Widget *w = this;
1433 while (w != NULL && w->style->backgroundColor == NULL)
1434 w = w->parent;
1435
1436 if (w != NULL && w->style->backgroundColor != NULL)
1438 else
1440 } else
1442
1443 style::drawBackground (view, layout, &canvasArea,
1444 xPad, yPad, widthPad, heightPad,
1445 xPad, yPad, widthPad, heightPad,
1446 style, bgColor, inverse, parent == NULL);
1447}
1448
1449/*
1450 * This function is used by some widgets, when they are selected (as a whole).
1451 *
1452 * \todo This could be accelerated by using clipping bitmaps. Two important
1453 * issues:
1454 *
1455 * (i) There should always been a pixel in the upper-left corner of the
1456 * *widget*, so probably two different clipping bitmaps have to be
1457 * used (10/01 and 01/10).
1458 *
1459 * (ii) Should a new GC always be created?
1460 *
1461 * \bug Not implemented.
1462 */
1464{
1465}
1466
1467
1469{
1470 this->buttonSensitive = buttonSensitive;
1471 buttonSensitiveSet = true;
1472}
1473
1474
1479{
1480 Widget *widget = this;
1481
1482 while (widget->parent)
1483 widget = widget->parent;
1484
1485 return widget;
1486}
1487
1494{
1495 Widget *widget = this;
1496 int level = 0;
1497
1498 while (widget->parent) {
1499 level++;
1500 widget = widget->parent;
1501 }
1502
1503 return level;
1504}
1505
1513{
1514 Widget *widget = this;
1515 int level = 0;
1516
1517 while (widget->getGenerator ()) {
1518 level++;
1519 widget = widget->getGenerator ();
1520 }
1521
1522 return level;
1523}
1524
1530{
1531 Widget *widget1 = this, *widget2 = otherWidget;
1532 int level1 = widget1->getLevel (), level2 = widget2->getLevel();
1533
1534 /* Get both widgets onto the same level.*/
1535 while (level1 > level2) {
1536 widget1 = widget1->parent;
1537 level1--;
1538 }
1539
1540 while (level2 > level1) {
1541 widget2 = widget2->parent;
1542 level2--;
1543 }
1544
1545 /* Search upwards. */
1546 while (widget1 != widget2) {
1547 if (widget1->parent == NULL) {
1548 MSG_WARN("widgets in different trees\n");
1549 return NULL;
1550 }
1551
1552 widget1 = widget1->parent;
1553 widget2 = widget2->parent;
1554 }
1555
1556 return widget1;
1557}
1558
1560 int x, int y, int width, int height)
1561{
1562 layout->scrollTo (hpos, vpos,
1563 x + allocation.x, y + allocation.y, width, height);
1564}
1565
1566void Widget::getMarginArea (int *xMar, int *yMar, int *widthMar, int *heightMar)
1567{
1568 *xMar = allocation.x + extraSpace.left;
1569 *yMar = allocation.y + extraSpace.top;
1570 *widthMar = allocation.width - (extraSpace.left + extraSpace.right);
1571 *heightMar = getHeight () - (extraSpace.top + extraSpace.bottom);
1572}
1573
1574void Widget::getBorderArea (int *xBor, int *yBor, int *widthBor, int *heightBor)
1575{
1576 getMarginArea (xBor, yBor, widthBor, heightBor);
1577
1578 *xBor += style->margin.left;
1579 *yBor += style->margin.top;
1580 *widthBor -= style->margin.left + style->margin.right;
1581 *heightBor -= style->margin.top + style->margin.bottom;
1582}
1583
1590void Widget::getPaddingArea (int *xPad, int *yPad, int *widthPad,
1591 int *heightPad)
1592{
1593 getBorderArea (xPad, yPad, widthPad, heightPad);
1594
1595 *xPad += style->borderWidth.left;
1596 *yPad += style->borderWidth.top;
1597 *widthPad -= style->borderWidth.left + style->borderWidth.right;
1598 *heightPad -= style->borderWidth.top + style->borderWidth.bottom;
1599}
1600
1602 Widget **references, int *x, int *y)
1603{
1604 // Use the simple variant.
1605 DBG_OBJ_ENTER0 ("resize", 0, "Widget::sizeRequestImpl");
1607 DBG_OBJ_LEAVE ();
1608}
1609
1611{
1612 // Either variant should be implemented.
1613 misc::notImplemented ("Widget::sizeRequestSimpl");
1614}
1615
1617 Widget **references, int *x, int *y)
1618{
1619 // Use the simple variant.
1620 DBG_OBJ_ENTER0 ("resize", 0, "Widget::getExtremesImpl");
1622 DBG_OBJ_LEAVE ();
1623}
1624
1626{
1627 // Either variant should be implemented.
1628 misc::notImplemented ("Widget::getExtremesSimpl");
1629}
1630
1634
1644void Widget::calcExtraSpaceImpl (int numPos, Widget **references, int *x,
1645 int *y)
1646{
1647}
1648
1650{
1651}
1652
1654{
1655}
1656
1657int Widget::applyPerWidth (int containerWidth, style::Length perWidth)
1658{
1659 return style::multiplyWithPerLength (containerWidth, perWidth)
1660 + boxDiffWidth ();
1661}
1662
1663int Widget::applyPerHeight (int containerHeight, style::Length perHeight)
1664{
1665 return style::multiplyWithPerLength (containerHeight, perHeight)
1666 + boxDiffHeight ();
1667}
1668
1679int Widget::getAvailWidthOfChild (Widget *child, bool forceValue)
1680{
1681 // This is a halfway suitable implementation for all
1682 // containers. For simplification, this will be used during the
1683 // development; then, a differentiation could be possible.
1684
1685 DBG_OBJ_ENTER ("resize", 0, "getAvailWidthOfChild", "%p, %s",
1686 child, forceValue ? "true" : "false");
1687
1688 int width;
1689
1690 if (child->getStyle()->width == style::LENGTH_AUTO) {
1691 DBG_OBJ_MSG ("resize", 1, "no specification");
1692
1693 /* We only compute when forceValue is true */
1694 if (forceValue) {
1695 width = misc::max (getAvailWidth (true) - boxDiffWidth (), 0);
1696
1697 if (width != -1) {
1698 /* Clamp to min-width and max-width if given */
1699 int maxWidth = child->calcWidth (child->getStyle()->maxWidth,
1700 -1, this, -1, false);
1701 if (maxWidth != -1 && width > maxWidth)
1702 width = maxWidth;
1703
1704 int minWidth = child->calcWidth (child->getStyle()->minWidth,
1705 -1, this, -1, false);
1706 if (minWidth != -1 && width < minWidth)
1707 width = minWidth;
1708 }
1709
1710 } else {
1711 width = -1;
1712 }
1713 } else {
1714 // In most cases, the toplevel widget should be a container, so
1715 // the container is non-NULL when the parent is non-NULL. Just
1716 // in case, regard also parent. And quasiParent.
1717 Widget *effContainer = child->quasiParent ? child->quasiParent :
1718 (child->container ? child->container : child->parent);
1719
1720 if (effContainer == this) {
1721 width = -1;
1722 child->calcFinalWidth (child->getStyle(), -1, this, 0, forceValue,
1723 &width);
1724 } else {
1725 DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container");
1727 width = effContainer->getAvailWidthOfChild (child, forceValue);
1728 DBG_OBJ_MSG_END ();
1729 }
1730 }
1731
1732 DBG_OBJ_LEAVE_VAL ("%d", width);
1733 return width;
1734}
1735
1736int Widget::getAvailHeightOfChild (Widget *child, bool forceValue)
1737{
1738 // Again, a suitable implementation for all widgets (perhaps).
1739
1740 // TODO Consider 'min-height' and 'max-height'. (Minor priority, as long as
1741 // "getAvailHeight (true)" is not used.
1742
1743 DBG_OBJ_ENTER ("resize", 0, "getAvailHeightOfChild", "%p, %s",
1744 child, forceValue ? "true" : "false");
1745
1746 int height;
1747
1748 if (child->getStyle()->height == style::LENGTH_AUTO) {
1749 DBG_OBJ_MSG ("resize", 1, "no specification");
1750 if (forceValue)
1751 height = misc::max (getAvailHeight (true) - boxDiffHeight (), 0);
1752 else
1753 height = -1;
1754 } else {
1755 // See comment in Widget::getAvailWidthOfChild.
1756 Widget *effContainer = child->quasiParent ? child->quasiParent :
1757 (child->container ? child->container : child->parent);
1758
1759 if (effContainer == this) {
1760 if (style::isAbsLength (child->getStyle()->height)) {
1761 DBG_OBJ_MSGF ("resize", 1, "absolute height: %dpx",
1762 style::absLengthVal (child->getStyle()->height));
1763 height = misc::max (style::absLengthVal (child->getStyle()->height)
1764 + child->boxDiffHeight (), 0);
1765 } else {
1766 assert (style::isPerLength (child->getStyle()->height));
1767 DBG_OBJ_MSGF ("resize", 1, "percentage height: %g%%",
1769 (child->getStyle()->height));
1770
1771 int availHeight = getAvailHeight (forceValue);
1772 if (availHeight == -1)
1773 height = -1;
1774 else
1775 height =
1776 misc::max (child->applyPerHeight (availHeight -
1777 boxDiffHeight (),
1778 child->getStyle()->height),
1779 0);
1780 }
1781 } else {
1782 DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container");
1784 height = effContainer->getAvailHeightOfChild (child, forceValue);
1785 DBG_OBJ_MSG_END ();
1786 }
1787 }
1788
1789 DBG_OBJ_LEAVE_VAL ("%d", height);
1790 return height;
1791}
1792
1794 void (*splitHeightFun) (int, int*,
1795 int*),
1796 bool allowDecreaseWidth,
1797 bool allowDecreaseHeight)
1798{
1799 // Again, a suitable implementation for all widgets (perhaps).
1800
1801 DBG_OBJ_ENTER ("resize", 0, "correctRequisitionOfChild",
1802 "%p, %d * (%d + %d), ..., %s, %s", child, requisition->width,
1804 misc::boolToStr (allowDecreaseWidth),
1805 misc::boolToStr (allowDecreaseHeight));
1806
1807 // See comment in Widget::getAvailWidthOfChild.
1808 Widget *effContainer = child->quasiParent ? child->quasiParent :
1809 (child->container ? child->container : child->parent);
1810
1811 if (effContainer == this) {
1812 correctReqWidthOfChild (child, requisition, allowDecreaseWidth);
1813 correctReqHeightOfChild (child, requisition, splitHeightFun,
1814 allowDecreaseHeight);
1815 } else {
1816 DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container");
1818 effContainer->correctRequisitionOfChild (child, requisition,
1819 splitHeightFun,
1820 allowDecreaseWidth,
1821 allowDecreaseHeight);
1822 DBG_OBJ_MSG_END ();
1823 }
1824
1827}
1828
1830 bool allowDecreaseWidth)
1831{
1832 DBG_OBJ_ENTER ("resize", 0, "correctReqWidthOfChild",
1833 "%p, %d * (%d + %d), %s",
1835 requisition->descent, misc::boolToStr (allowDecreaseWidth));
1836
1837 assert (this == child->quasiParent || this == child->container);
1838
1839 int limitMinWidth = child->getMinWidth (NULL, true);
1840 if (!allowDecreaseWidth && limitMinWidth < requisition->width)
1841 limitMinWidth = requisition->width;
1842
1843 child->calcFinalWidth (child->getStyle(), -1, this, limitMinWidth, true,
1844 &requisition->width);
1845
1848}
1849
1851 void (*splitHeightFun) (int, int*, int*),
1852 bool allowDecreaseHeight)
1853{
1854 // TODO Correct height by extremes? (Height extemes?)
1855
1856 assert (this == child->quasiParent || this == child->container);
1857
1858 DBG_OBJ_ENTER ("resize", 0, "correctReqHeightOfChild",
1859 "%p, %d * (%d + %d), ..., %s", child, requisition->width,
1861 misc::boolToStr (allowDecreaseHeight));
1862
1863 int height = child->calcHeight (child->getStyle()->height, false, -1, this,
1864 false);
1865 adjustHeight (&height, allowDecreaseHeight, requisition->ascent,
1867
1868 int minHeight = child->calcHeight (child->getStyle()->minHeight, false, -1,
1869 this, false);
1870 adjustHeight (&minHeight, allowDecreaseHeight, requisition->ascent,
1872
1873 int maxHeight = child->calcHeight (child->getStyle()->maxHeight, false, -1,
1874 this, false);
1875 adjustHeight (&maxHeight, allowDecreaseHeight, requisition->ascent,
1877
1878 // TODO Perhaps split first, then add box ascent and descent.
1879 if (height != -1)
1880 splitHeightFun (height, &requisition->ascent, &requisition->descent);
1881 if (minHeight != -1 &&
1882 requisition->ascent + requisition->descent < minHeight)
1883 splitHeightFun (minHeight, &requisition->ascent,
1885 if (maxHeight != -1 &&
1886 requisition->ascent + requisition->descent > maxHeight)
1887 splitHeightFun (maxHeight, &requisition->ascent,
1889
1892}
1893
1895 bool useAdjustmentWidth)
1896{
1897 // See comment in correctRequisitionOfChild.
1898
1899 DBG_OBJ_ENTER ("resize", 0, "correctExtremesOfChild",
1900 "%p, %d (%d) / %d (%d)",
1903
1904 // See comment in Widget::getAvailWidthOfChild.
1905 Widget *effContainer = child->quasiParent ? child->quasiParent :
1906 (child->container ? child->container : child->parent);
1907
1908 if (effContainer == this) {
1909 int limitMinWidth =
1910 useAdjustmentWidth ? child->getMinWidth (extremes, false) : 0;
1911 int width = child->calcWidth (child->getStyle()->width, -1, this,
1912 limitMinWidth, false);
1913 int minWidth = child->calcWidth (child->getStyle()->minWidth, -1, this,
1914 limitMinWidth, false);
1915 int maxWidth = child->calcWidth (child->getStyle()->maxWidth, -1, this,
1916 limitMinWidth, false);
1917
1918 DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d",
1919 width, minWidth, maxWidth);
1920
1921 if (width != -1)
1922 extremes->minWidth = extremes->maxWidth = width;
1923 if (minWidth != -1)
1924 extremes->minWidth = minWidth;
1925 if (maxWidth != -1)
1926 extremes->maxWidth = maxWidth;
1927 } else {
1928 DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container");
1930 effContainer->correctExtremesOfChild (child, extremes,
1931 useAdjustmentWidth);
1932 DBG_OBJ_MSG_END ();
1933 }
1934
1935
1937}
1938
1948
1955{
1956}
1957
1959{
1960 // Most widgets are not block-level.
1961 return false;
1962}
1963
1965{
1966 // In most (all?) cases identical to:
1967 return isBlockLevel ();
1968}
1969
1971{
1972 return false;
1973}
1974
1976{
1977 return false;
1978}
1979
1981{
1982 return false;
1983}
1984
1986{
1987 style::Tooltip *tooltip = getStyle()->x_tooltip;
1988
1989 if (tooltip)
1990 tooltip->onEnter();
1991}
1992
1994{
1995 style::Tooltip *tooltip = getStyle()->x_tooltip;
1996
1997 if (tooltip)
1998 tooltip->onLeave();
1999}
2000
2001
2003{
2004 // Should be implemented.
2005 misc::notImplemented ("Widget::removeChild");
2006}
2007
2008// ----------------------------------------------------------------------
2009
2010void splitHeightPreserveAscent (int height, int *ascent, int *descent)
2011{
2012 DBG_OBJ_ENTER_S ("resize", 1, "splitHeightPreserveAscent", "%d, %d, %d",
2013 height, *ascent, *descent);
2014
2015 *descent = height - *ascent;
2016 if (*descent < 0) {
2017 *descent = 0;
2018 *ascent = height;
2019 }
2020
2021 DBG_OBJ_LEAVE_VAL_S ("%d, %d", *ascent, *descent);
2022}
2023
2024void splitHeightPreserveDescent (int height, int *ascent, int *descent)
2025{
2026 DBG_OBJ_ENTER_S ("resize", 1, "splitHeightPreserveDescent", "%d, %d, %d",
2027 height, *ascent, *descent);
2028
2029 *ascent = height - *descent;
2030 if (*ascent < 0) {
2031 *ascent = 0;
2032 *descent = height;
2033 }
2034
2035 DBG_OBJ_LEAVE_VAL_S ("%d, %d", *ascent, *descent);
2036}
2037
2038} // namespace core
2039} // namespace dw
#define _MSG(...)
Definition bookmarks.c:45
Set at the top when drawing.
Definition types.hh:295
Rectangle * getToplevelArea()
Definition types.hh:304
Represents a button press or release event.
Definition events.hh:58
Represents a enter or leave notify event.
Definition events.hh:75
Represents a mouse motion event.
Definition events.hh:68
Set at the top when getting the widget at the point.
Definition types.hh:313
Iterators are used to iterate through the contents of a widget.
Definition iterator.hh:20
virtual void unref()
Delete the iterator.
Definition iterator.cc:82
virtual bool next()=0
Move iterator forward and store content it.
Content * getContent()
Definition iterator.hh:37
void queueDraw(int x, int y, int width, int height)
Definition layout.cc:967
style::Color * getBgColor()
Definition layout.hh:442
void queueDrawExcept(int x, int y, int width, int height, int ex, int ey, int ewidth, int eheight)
Definition layout.cc:980
lout::container::typed::Vector< Widget > * queueResizeList
Definition layout.hh:158
int vScrollbarThickness
Definition layout.hh:173
void updateCursor()
Definition layout.cc:810
void removeWidget()
Definition layout.cc:404
Widget * topLevel
Definition layout.hh:157
void scrollTo(HPosition hpos, VPosition vpos, int x, int y, int width, int height)
Scrolls all viewports, so that the region [x, y, width, height] is seen, according to hpos and vpos.
Definition layout.cc:531
bool canvasHeightGreater
Definition layout.hh:172
void queueResize(bool extremesChanged)
Definition layout.cc:1003
dw::core::Shape implemtation for simple rectangles.
Definition types.hh:70
bool intersectsWith(Rectangle *otherRect, Rectangle *dest)
Return whether this rectangle and otherRect intersect.
Definition types.cc:53
Hold arguments passed to dw::core::Widget::sizeRequest and dw::core::Widget::getExtremes,...
Definition tools.hh:19
bool isEquivalent(SizeParams *other)
Compares two instances, but considers a change in the order of the reference widgets as equivalent.
Definition tools.cc:164
See Handling stacking contexts.
static bool isEstablishingStackingContext(Widget *widget)
void addChildSCWidget(Widget *widget)
void addWidgetProcessedAsInterruption(Widget *widget)
Definition types.hh:282
An interface to encapsulate platform dependent drawing.
Definition view.hh:17
Implementation which represents the whole widget.
Definition widget.hh:85
bool readyToDraw()
If this method returns false, nothing is done at all.
Definition widget.cc:35
style::Style * getStyle()
Return the style this background image is part of.
Definition widget.cc:52
void getBgArea(int *x, int *y, int *width, int *height)
Return the area covered by the background image.
Definition widget.cc:40
void getRefArea(int *xRef, int *yRef, int *widthRef, int *heightRef)
Return the "reference area".
Definition widget.cc:46
void draw(int x, int y, int width, int height)
Draw (or queue for drawing) an area, which is given in canvas coordinates.
Definition widget.cc:57
The base class of all dillo widgets.
Definition widget.hh:24
virtual void notifySetParent()
This method is called after a widget has been added to a parent.
Definition widget.cc:1954
virtual void setStyle(style::Style *style)
Change the style of a widget.
Definition widget.cc:1233
void leaveSizeRequest()
Definition widget.hh:418
WidgetImgRenderer * widgetImgRenderer
Definition widget.hh:99
virtual void leaveNotifyImpl(EventCrossing *event)
Definition widget.cc:1993
void sizeAllocate(Allocation *allocation)
Wrapper for Widget::sizeAllocateImpl, calls the latter only when needed.
Definition widget.cc:1126
bool queueResizeEntered()
Definition widget.hh:411
bool motionNotify(EventMotion *event)
Definition widget.cc:1211
void setWidgetReference(WidgetReference *widgetReference)
Definition widget.hh:560
Extremes extremes
Analogue to dw::core::Widget::requisition.
Definition widget.hh:146
Layout * layout
Definition widget.hh:189
Widget * container
The containing widget, equivalent to the "containing block" defined by CSS.
Definition widget.hh:126
void enterQueueResize()
Definition widget.hh:409
SizeParams requisitionParams
Definition widget.hh:141
virtual bool usesAvailWidth()
Must be implemengted by a method returning true, when getAvailWidth() is called.
Definition widget.cc:516
bool intersects(Widget *refWidget, Rectangle *area, Rectangle *intersection)
Calculates the intersection of the visible allocation (i.
Definition widget.cc:139
void setQuasiParent(Widget *quasiParent)
Definition widget.cc:276
Allocation allocation
The current allocation: size and position, always relative to the canvas.
Definition widget.hh:183
static void adjustHeight(int *height, bool allowDecreaseHeight, int ascent, int descent)
Definition widget.cc:1004
virtual bool affectedByContainerSizeChange()
Definition widget.cc:433
virtual Iterator * iterator(Content::Type mask, bool atEnd)=0
Return an iterator for this widget.
void leaveGetExtremes()
Definition widget.hh:422
virtual void draw(View *view, Rectangle *area, DrawingContext *context)=0
Area is given in widget coordinates.
void setButtonSensitive(bool buttonSensitive)
Definition widget.cc:1468
virtual void markExtremesChange(int ref)
See Sizes of Dillo Widgets.
Definition widget.cc:1653
@ NEEDS_ALLOCATE
Only used internally, set to enforce size allocation.
Definition widget.hh:56
@ WAS_ALLOCATED
Set, when a widget was already once allocated,.
Definition widget.hh:76
@ EXTREMES_CHANGED
Set, when dw::core::Widget::extremes is not up to date anymore.
Definition widget.hh:69
@ NEEDS_RESIZE
Set, when dw::core::Widget::requisition is not up to date anymore.
Definition widget.hh:45
virtual int getAvailWidthOfChild(Widget *child, bool forceValue)
Computes the content width available of a child widget.
Definition widget.cc:1679
virtual bool affectsSizeChangeContainerChild(Widget *child)
Definition widget.cc:467
void sizeRequest(Requisition *requisition, int numPos=0, Widget **references=NULL, int *x=NULL, int *y=NULL)
This method is a wrapper for Widget::sizeRequestImpl(); it calls the latter only when needed.
Definition widget.cc:534
Widget * getParent()
Definition widget.hh:552
int boxDiffWidth()
Definition widget.hh:461
int parentRef
This value is defined by the parent widget, and used for incremential resizing.
Definition widget.hh:175
int getAvailWidth(bool forceValue)
Return available width including margin/border/padding (extraSpace?), not only the content width.
Definition widget.cc:649
bool sizeRequestEntered()
Definition widget.hh:419
void enterNotify(EventCrossing *event)
Definition widget.cc:1216
void calcFinalWidth(style::Style *style, int refWidth, Widget *refWidget, int limitMinWidth, bool forceValue, int *finalWidth)
Definition widget.cc:927
void drawWidgetBox(View *view, Rectangle *area, bool inverse)
Draw borders and background of a widget.
Definition widget.cc:1412
bool needsAllocate()
Definition widget.hh:438
void correctRequisition(Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition widget.cc:744
void drawSelected(View *view, Rectangle *area)
Definition widget.cc:1463
void calcExtraSpace(int numPos, Widget **references, int *x, int *y)
Calculates dw::core::Widget::extraSpace.
Definition widget.cc:1085
virtual bool getAdjustMinWidth()
Definition widget.hh:498
style::Style * getStyle()
Definition widget.hh:448
int getLevel()
Get the level of the widget within the tree.
Definition widget.cc:1493
bool resizeQueued()
Definition widget.hh:435
virtual void removeChild(Widget *child)
Definition widget.cc:2002
virtual bool motionNotifyImpl(EventMotion *event)
Definition widget.cc:1980
bool buttonRelease(EventButton *event)
Definition widget.cc:1206
Widget * stackingContextWidget
The bottom-most ancestor (or this) for which stackingContextMgr is set.
Definition widget.hh:211
virtual void notifySetAsTopLevel()
This method is called after a widget has been set as the top of a widget tree.
Definition widget.cc:1945
style::Color * bgColor
See dw::core::Widget::setBgColor().
Definition widget.hh:152
StackingContextMgr * stackingContextMgr
Set iff this widget constitutes a stacking context, as defined by CSS.
Definition widget.hh:205
Requisition requisition
Size_request() stores the result of the last call of size_request_impl().
Definition widget.hh:140
Widget * getGenerator()
Definition widget.hh:565
Widget * getWidgetAtPointInterrupted(int x, int y, GettingWidgetAtPointContext *context)
Definition widget.cc:222
virtual void enterNotifyImpl(EventCrossing *event)
Definition widget.cc:1985
style::Box extraSpace
Space around the margin box.
Definition widget.hh:199
int calcWidth(style::Length cssValue, int refWidth, Widget *refWidget, int limitMinWidth, bool forceValue)
Computes a width value in pixels from cssValue.
Definition widget.cc:883
virtual void getExtremesSimpl(Extremes *extremes)
Simple variant, to be implemented by widgets with extremes not depending on positions.
Definition widget.cc:1625
void queueDrawArea(int x, int y, int width, int height)
Definition widget.cc:285
virtual int getAvailHeightOfChild(Widget *child, bool forceValue)
Definition widget.cc:1736
bool resizeIdleEntered()
Definition widget.hh:407
bool inAllocation(int x, int y)
Definition widget.hh:451
virtual void correctRequisitionOfChild(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition widget.cc:1793
Widget * getNearestCommonAncestor(Widget *otherWidget)
Get the widget with the highest level, which is a direct ancestor of widget1 and widget2.
Definition widget.cc:1529
virtual void sizeAllocateImpl(Allocation *allocation)
See Sizes of Dillo Widgets.
Definition widget.cc:1631
bool extremesQueued()
Definition widget.hh:436
bool extremesChanged()
Definition widget.hh:440
virtual void correctExtremesOfChild(Widget *child, Extremes *extremes, bool useAdjustmentWidth)
Definition widget.cc:1894
bool getExtremesEntered()
Definition widget.hh:423
Widget * generator
The generating widget, NULL for top-level widgets, or if not set; in the latter case,...
Definition widget.hh:119
virtual void sizeRequestSimpl(Requisition *requisition)
Simple variant, to be implemented by widgets with sizes not depending on positions.
Definition widget.cc:1610
void * deleteCallbackData
Definition widget.hh:399
int getMinWidth(Extremes *extremes, bool forceValue)
Used to evaluate Widget::adjustMinWidth.
Definition widget.cc:604
virtual void calcExtraSpaceImpl(int numPos, Widget **references, int *x, int *y)
The actual implementation for calculating dw::core::Widget::extraSpace.
Definition widget.cc:1644
virtual void resizeDrawImpl()
Called after sizeAllocateImpl() to redraw necessary areas.
Definition widget.hh:319
virtual bool buttonPressImpl(EventButton *event)
Definition widget.cc:1970
void setParent(Widget *parent)
Definition widget.cc:231
virtual bool isPossibleContainer()
Definition widget.cc:1964
DW_Callback_t deleteCallbackFunc
Definition widget.hh:400
virtual void getExtremesImpl(Extremes *extremes, int numPos, Widget **references, int *x, int *y)
See Sizes of Dillo Widgets.
Definition widget.cc:1616
void queueResizeFast(int ref, bool extremesChanged)
Definition widget.hh:165
bool needsResize()
Definition widget.hh:437
virtual void containerSizeChangedForChildren()
Definition widget.cc:497
void scrollTo(HPosition hpos, VPosition vpos, int x, int y, int width, int height)
Definition widget.cc:1559
void enterSizeAllocate()
Definition widget.hh:413
int calcHeight(style::Length cssValue, bool usePercentage, int refHeight, Widget *refWidget, bool forceValue)
Definition widget.cc:958
virtual Widget * getWidgetAtPoint(int x, int y, GettingWidgetAtPointContext *context)
Definition widget.cc:211
virtual int applyPerHeight(int containerHeight, style::Length perHeight)
Definition widget.cc:1663
void leaveNotify(EventCrossing *event)
Definition widget.cc:1221
void drawInterruption(View *view, Rectangle *area, DrawingContext *context)
See Interrupted drawing for details.
Definition widget.cc:201
virtual int numGetExtremesReferences()
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition widget.cc:1111
virtual Widget * sizeRequestReference(int index)
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition widget.cc:1105
Widget * parent
The parent widget, NULL for top-level widgets.
Definition widget.hh:107
int getAvailHeight(bool forceValue)
Return available height including margin/border/padding (extraSpace?), not only the content height.
Definition widget.cc:691
void leaveQueueResize()
Definition widget.hh:410
style::Style * style
Definition widget.hh:130
static bool adjustMinWidth
Definition widget.hh:102
void containerSizeChanged()
Definition widget.cc:408
int getGeneratorLevel()
Get the level of the widget within the tree, regarting the generators, not the parents.
Definition widget.cc:1512
void leaveSizeAllocate()
Definition widget.hh:414
void unsetFlags(Flags f)
Definition widget.hh:274
void queueResize(int ref, bool extremesChanged, bool fast)
This method should be called, when a widget changes its size.
Definition widget.cc:309
virtual void sizeRequestImpl(Requisition *requisition, int numPos, Widget **references, int *x, int *y)
See Sizes of Dillo Widgets.
Definition widget.cc:1601
bool buttonPress(EventButton *event)
Definition widget.cc:1201
void correctReqHeightOfChild(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseHeight)
Definition widget.cc:1850
virtual bool usesAvailHeight()
Must be implemengted by a method returning true, when getAvailHeight() is called.
Definition widget.cc:525
virtual void markSizeChange(int ref)
See Sizes of Dillo Widgets.
Definition widget.cc:1649
Widget * getTopLevel()
Get the widget at the root of the tree, this widget is part from.
Definition widget.cc:1478
style::Color * getBgColor()
Get the actual background of a widget.
Definition widget.cc:1348
bool wasAllocated()
Definition widget.hh:441
virtual int numSizeRequestReferences()
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition widget.cc:1100
virtual Widget * getExtremesReference(int index)
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition widget.cc:1116
void getBorderArea(int *xBor, int *yBor, int *widthBor, int *heightBor)
Definition widget.cc:1574
int boxDiffHeight()
Definition widget.hh:466
void setBgColor(style::Color *bgColor)
Set the background "behind" the widget, if it is not the background of the parent widget,...
Definition widget.cc:1340
void queueDraw()
Definition widget.hh:277
virtual int applyPerWidth(int containerWidth, style::Length perWidth)
Definition widget.cc:1657
void correctExtremes(Extremes *extremes, bool useAdjustmentWidth)
Definition widget.cc:821
void getMarginArea(int *xMar, int *yMar, int *widthMar, int *heightMar)
Definition widget.cc:1566
void getPaddingArea(int *xPad, int *yPad, int *widthPad, int *heightPad)
Return the padding area (content plus padding).
Definition widget.cc:1590
virtual bool buttonReleaseImpl(EventButton *event)
Definition widget.cc:1975
SizeParams extremesParams
Definition widget.hh:147
void setFlags(Flags f)
Definition widget.hh:272
void correctReqWidthOfChild(Widget *child, Requisition *requisition, bool allowDecreaseWidth)
Definition widget.cc:1829
bool buttonSensitiveSet
See dw::core::Widget::setButtonSensitive().
Definition widget.hh:162
void getExtremes(Extremes *extremes, int numPos=0, Widget **references=NULL, int *x=NULL, int *y=NULL)
Wrapper for Widget::getExtremesImpl().
Definition widget.cc:1014
void enterGetExtremes()
Definition widget.hh:421
void drawBox(View *view, style::Style *style, Rectangle *area, int x, int y, int width, int height, bool inverse)
Draw borders and background of a widget part, which allocation is given by (x, y, width,...
Definition widget.cc:1371
Widget * quasiParent
...
Definition widget.hh:112
static int CLASS_ID
Definition widget.hh:427
bool buttonSensitive
See dw::core::Widget::setButtonSensitive().
Definition widget.hh:157
void enterSizeRequest()
Definition widget.hh:417
virtual bool isBlockLevel()
Definition widget.cc:1958
StyleImage * backgroundImage
Definition style.hh:536
bool sizeDiffs(StyleAttrs *otherStyleAttrs)
This method returns whether something may change its size, when its style changes from this style to ...
Definition style.cc:149
void putExternalImgRenderer(ImgRenderer *ir)
Add an additional ImgRenderer, especially used for drawing.
Definition style.hh:890
void removeExternalImgRenderer(ImgRenderer *ir)
Remove a previously added additional ImgRenderer.
Definition style.hh:896
virtual void onLeave()
Definition style.hh:672
virtual void onEnter()
Definition style.hh:671
void registerName(const char *className, int *classId)
This method must be called in the constructor for the sub class.
Definition identity.cc:83
#define DBG_IF_RTFL
Definition debug.hh:73
#define DBG_OBJ_LEAVE_VAL_S(fmt,...)
Definition debug.hh:80
#define DBG_OBJ_ENTER_S(aspect, prio, funname, fmt,...)
Definition debug.hh:78
#define DBG_OBJ_ENTER0(aspect, prio, funname)
#define DBG_OBJ_DELETE()
#define DBG_OBJ_CREATE(klass)
#define DBG_OBJ_SET_COL(var, val)
#define DBG_OBJ_SET_SYM(var, val)
#define DBG_OBJ_MSG_END()
#define DBG_OBJ_MSGF(aspect, prio, fmt,...)
#define DBG_OBJ_SET_NUM(var, val)
#define DBG_OBJ_MSG(aspect, prio, msg)
#define DBG_OBJ_ENTER(aspect, prio, funname, fmt,...)
#define DBG_OBJ_LEAVE()
#define DBG_OBJ_MSG_START()
#define DBG_OBJ_ASSOC_PARENT(parent)
#define DBG_OBJ_ASSOC_CHILD(child)
#define DBG_OBJ_SET_PTR(var, val)
#define DBG_OBJ_LEAVE_VAL0(val)
#define DBG_OBJ_LEAVE_VAL(fmt,...)
#define MSG_WARN(...)
Definition msg.h:26
int multiplyWithPerLength(int x, Length l)
Multiply an int with a percentage length, returning int.
Definition style.hh:473
void drawBackground(View *view, Layout *layout, Rectangle *area, int x, int y, int width, int height, int xRef, int yRef, int widthRef, int heightRef, Style *style, Color *bgColor, bool inverse, bool atTop)
Draw the background (content plus padding) of a region in window, according to style.
Definition style.cc:1220
@ DISPLAY_TABLE_HEADER_GROUP
Definition style.hh:285
@ DISPLAY_TABLE_ROW_GROUP
Definition style.hh:284
@ DISPLAY_INLINE_BLOCK
Definition style.hh:280
@ DISPLAY_TABLE_FOOTER_GROUP
Definition style.hh:286
int Length
Type for representing all lengths within dw::core::style.
Definition style.hh:428
double perLengthVal_useThisOnlyForDebugging(Length l)
Returns the value of a percentage, relative to 1, as a double.
Definition style.hh:458
void drawBorder(View *view, Layout *layout, Rectangle *area, int x, int y, int width, int height, Style *style, bool inverse)
Draw the border of a region in window, according to style.
Definition style.cc:1155
bool isPerLength(Length l)
Returns true if l is a percentage.
Definition style.hh:445
bool isAbsLength(Length l)
Returns true if l is an absolute length.
Definition style.hh:442
int absLengthVal(Length l)
Returns the value of a length in pixels, as an integer.
Definition style.hh:451
@ LENGTH_AUTO
Represents "auto" lengths.
Definition style.hh:494
void splitHeightPreserveDescent(int height, int *ascent, int *descent)
Definition widget.cc:2024
VPosition
Definition types.hh:26
void splitHeightPreserveAscent(int height, int *ascent, int *descent)
Definition widget.cc:2010
HPosition
Definition types.hh:16
Dw is in this namespace, or sub namespaces of this one.
Miscellaneous stuff, which does not fit anywhere else.
Definition misc.cc:31
void notImplemented(const char *name)
Definition misc.hh:55
T max(T a, T b)
Definition misc.hh:20
const char * boolToStr(bool b)
Definition misc.hh:87
Here, some common classes (or interfaces) are defined, to standardize the access to other classes.
Definition object.cc:29
Represents the allocation, i.e.
Definition types.hh:164
@ WIDGET_IN_FLOW
widget in normal flow, so that this widget (containing this content) is both container (parent) and g...
Definition types.hh:207
@ WIDGET_OOF_CONT
widget out of flow (OOF); this widget (containing this content) is only the container (parent),...
Definition types.hh:212
Widget * widget
Definition types.hh:237