Dillo v3.1.1-111-gd4f56d0d
Loading...
Searching...
No Matches
ui.cc
Go to the documentation of this file.
1/*
2 * Dillo Widget
3 *
4 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org>
5 * Copyright 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
22
23#include "core.hh"
24#include "../lout/debug.hh"
25
26#include <stdio.h>
27
28namespace dw {
29namespace core {
30namespace ui {
31
32using namespace lout;
33using namespace lout::object;
34
35int Embed::CLASS_ID = -1;
36
38{
39 DBG_OBJ_CREATE ("dw::core::ui::Embed");
40 registerName ("dw::core::ui::Embed", &CLASS_ID);
41 this->resource = resource;
42 resource->setEmbed (this);
44}
45
47{
48 delete resource;
50}
51
53{
55 // TODO Correction should perhaps be left to the resouces.
57}
58
66
71
72int Embed::getAvailWidthOfChild (Widget *child, bool forceValue)
73{
74 return resource->getAvailWidthOfChild (child, forceValue);
75}
76
77int Embed::getAvailHeightOfChild (Widget *child, bool forceValue)
78{
79 return resource->getAvailHeightOfChild (child, forceValue);
80}
81
83 Requisition *requisition,
84 void (*splitHeightFun) (int, int*, int*),
85 bool allowDecreaseWidth,
86 bool allowDecreaseHeight)
87{
88 resource->correctRequisitionOfChild (child, requisition, splitHeightFun,
89 allowDecreaseWidth,
90 allowDecreaseHeight);
91}
92
94 bool useAdjustmentWidth)
95{
96 resource->correctExtremesOfChild (child, extremes, useAdjustmentWidth);
97}
98
100{
101 DBG_OBJ_ENTER0 ("resize", 0, "containerSizeChangedForChildren");
103 DBG_OBJ_LEAVE ();
104}
105
111
117
119{
120 bool handled;
121
122 if (event->button == 3) {
123 resource->emitClicked(event);
124 handled = true;
125 } else {
126 handled = false;
127 }
128 return handled;
129}
130
131void Embed::setDisplayed (bool displayed)
132{
133 resource->setDisplayed (displayed);
134}
135
136void Embed::setEnabled (bool enabled)
137{
138 resource->setEnabled (enabled);
139}
140
141void Embed::draw (View *view, Rectangle *area, DrawingContext *context)
142{
143 drawWidgetBox (view, area, false);
144 resource->draw (view, area, context);
145}
146
148{
149 return resource->iterator (mask, atEnd);
150}
151
157
158// ----------------------------------------------------------------------
159
161 *receiver,
162 int signalNo,
163 int argc, Object **argv)
164{
165 ActivateReceiver *ar = (ActivateReceiver*)receiver;
166 Resource *res = (Resource*)((Pointer*)argv[0])->getValue ();
167
168 switch (signalNo) {
169 case 0:
170 ar->activate (res);
171 break;
172 case 1:
173 ar->enter (res);
174 break;
175 case 2:
176 ar->leave (res);
177 break;
178 default:
180 }
181 return false;
182}
183
185{
186 Pointer p (resource);
187 Object *argv[1] = { &p };
188 emitVoid (0, 1, argv);
189}
190
192{
193 Pointer p (resource);
194 Object *argv[1] = { &p };
195 emitVoid (1, 1, argv);
196}
197
199{
200 Pointer p (resource);
201 Object *argv[1] = { &p };
202 emitVoid (2, 1, argv);
203}
204
205// ----------------------------------------------------------------------
206
211
213{
214 this->embed = embed;
215}
216
218{
219 DBG_OBJ_ENTER0 ("resize", 0, "getExtremes");
220
221 /* Simply return the requisition width */
222 Requisition requisition;
223 sizeRequest (&requisition);
224 extremes->minWidth = extremes->maxWidth = requisition.width;
225 extremes->minWidthIntrinsic = extremes->minWidth;
226 extremes->maxWidthIntrinsic = extremes->maxWidth;
227
228 DBG_OBJ_MSGF ("resize", 1, "result: %d / %d",
229 extremes->minWidth, extremes->maxWidth);
230 DBG_OBJ_LEAVE ();
231}
232
234{
235}
236
237int Resource::getAvailWidthOfChild (Widget *child, bool forceValue)
238{
239 // Only used when the resource contains other dillo widgets.
240 misc::notImplemented ("Resource::getAvailWidthOfChild");
241 return 0;
242}
243
244int Resource::getAvailHeightOfChild (Widget *child, bool forceValue)
245{
246 // Only used when the resource contains other dillo widgets.
247 misc::notImplemented ("Resource::getAvailHeightOfChild");
248 return 0;
249}
250
252 Requisition *requisition,
253 void (*splitHeightFun) (int, int*,
254 int*),
255 bool allowDecreaseWidth,
256 bool allowDecreaseHeight)
257{
258 // Only used when the resource contains other dillo widgets.
259 misc::notImplemented ("Resource::correctRequisitionOfChild");
260}
261
263 bool useAdjustmentWidth)
264{
265 // Only used when the resource contains other dillo widgets.
266 misc::notImplemented ("Resource::correctExtremesOfChild");
267}
268
270{
271 // No children by default.
272}
273
274void Resource::setDisplayed (bool displayed)
275{
276}
277
278void Resource::draw (View *view, Rectangle *area, DrawingContext *context)
279{
280}
281
283{
284}
285
287{
289}
290
292{
294}
295
297 int signalNo, int argc,
298 Object **argv)
299{
300 ((ClickedReceiver*)receiver)
301 ->clicked ((Resource*)((Pointer*)argv[0])->getValue (),
302 (EventButton*)((Pointer*)argv[1])->getValue());
303 return false;
304}
305
307 EventButton *event)
308{
309 Pointer p1 (resource);
310 Pointer p2 (event);
311 Object *argv[2] = { &p1, &p2 };
312 emitVoid (0, 2, argv);
313}
314
315// ----------------------------------------------------------------------
316
318{
320 // return new TextIterator (getEmbed (), mask, atEnd, getLabel ());
322 return new EmptyIterator (getEmbed (), mask, atEnd);
323}
324
325// ----------------------------------------------------------------------
326
328{
329 DBG_OBJ_ENTER ("resize", 0, "LayoutReceiver::resizeQueued", "%s",
330 extremesChanged ? "true" : "false");
331 resource->queueResize (extremesChanged);
332 DBG_OBJ_LEAVE ();
333}
334
336{
337 DBG_OBJ_CREATE ("dw::core::ui::ComplexButtonResource");
338 layout = NULL;
339 layoutReceiver.resource = this;
340 click_x = click_y = -1;
341}
342
344{
345 childWidget = widget;
346
347 /* FIXME: Buttons should not need a full Layout */
348 layout = new Layout (createPlatform (), false);
349 setLayout (layout);
351 layout->setWidget (widget);
352 layout->connect (&layoutReceiver);
353
354 if (getEmbed ())
355 childWidget->setQuasiParent (getEmbed ());
356}
357
359{
361
362 if (childWidget)
363 childWidget->setQuasiParent (getEmbed ());
364}
365
371
373{
374 DBG_OBJ_ENTER0 ("resize", 0, "sizeRequest");
375
376 Requisition widgetRequisition;
377 childWidget->sizeRequest (&widgetRequisition);
378 requisition->width = widgetRequisition.width + 2 * reliefXThickness ();
379 requisition->ascent = widgetRequisition.ascent + reliefYThickness ();
380 requisition->descent = widgetRequisition.descent + reliefYThickness ();
381
382 DBG_OBJ_MSGF ("resize", 1, "result: %d * (%d + %d)",
383 requisition->width, requisition->ascent, requisition->descent);
384 DBG_OBJ_LEAVE ();
385}
386
388{
389 DBG_OBJ_ENTER0 ("resize", 0, "getExtremes");
390
391 Extremes widgetExtremes;
392 childWidget->getExtremes (&widgetExtremes);
393 extremes->minWidth = widgetExtremes.minWidth + 2 * reliefXThickness ();
394 extremes->maxWidth = widgetExtremes.maxWidth + 2 * reliefXThickness ();
395 extremes->minWidthIntrinsic = extremes->minWidth;
396 extremes->maxWidthIntrinsic = extremes->maxWidth;
397
398 DBG_OBJ_MSGF ("resize", 1, "result: %d / %d",
399 extremes->minWidth, extremes->maxWidth);
400 DBG_OBJ_LEAVE ();
401}
402
406
408{
409 int embedWidth = getEmbed()->getAvailWidth (forceValue);
410 if (embedWidth == -1)
411 return -1;
412 else
413 return misc::max (embedWidth - 2 * reliefXThickness (), 0);
414}
415
417 bool forceValue)
418{
419 int embedHeight = getEmbed()->getAvailHeight (forceValue);
420 if (embedHeight == -1)
421 return -1;
422 else
423 return misc::max (embedHeight - 2 * reliefYThickness (), 0);
424}
425
427 Requisition *requisition,
428 void (*splitHeightFun)
429 (int, int*, int*),
430 bool allowDecreaseWidth,
431 bool allowDecreaseHeight)
432{
433 // Similar to Widget::correctRequisitionOfChild, but for percentage
434 // the relief has to be considered.
435
436 if (style::isPerLength (child->getStyle()->width)) {
437 /* FIXME: Typo for getAvailWidth()? */
438 int availWidth = getEmbed()->getAvailHeight (false);
439 if (availWidth != -1) {
440 int baseWidth = misc::max (availWidth
441 - getEmbed()->boxDiffWidth ()
442 - 2 * reliefXThickness (),
443 0);
444 int newWidth =
445 child->applyPerWidth (baseWidth, child->getStyle()->width);
446 requisition->width = allowDecreaseWidth ?
447 newWidth : misc::max (requisition->width, newWidth);
448 }
449 } else
450 getEmbed()->correctReqWidthOfChildNoRec (child, requisition,
451 allowDecreaseWidth);
452
453 // TODO Percentage heights are ignored again.
454 getEmbed()->correctReqHeightOfChildNoRec(child, requisition,
455 splitHeightFun, allowDecreaseWidth);
456
457}
458
460 Extremes *extremes,
461 bool useAdjustmentWidth)
462{
463 // Similar to Widget::correctExtremesOfChild, but for percentage
464 // the relief has to be considered.
465
466 if (style::isPerLength (child->getStyle()->width)) {
467 int availWidth = getEmbed()->getAvailHeight (false);
468 if (availWidth != -1) {
469 int baseWidth = misc::max (availWidth
470 - getEmbed()->boxDiffWidth ()
471 - 2 * reliefXThickness (),
472 0);
473 extremes->minWidth = extremes->maxWidth =
474 child->applyPerWidth (baseWidth, child->getStyle()->width);
475 }
476 } else
477 getEmbed()->correctExtremesOfChildNoRec (child, extremes,
478 useAdjustmentWidth);
479}
480
482{
483 layout->containerSizeChanged ();
484}
485
487{
492 return new EmptyIterator (getEmbed (), mask, atEnd);
493}
494
495// ----------------------------------------------------------------------
496
498{
499 // return new TextIterator (getEmbed (), mask, atEnd, getText ());
501 return new EmptyIterator (getEmbed (), mask, atEnd);
502}
503
504// ----------------------------------------------------------------------
505
507{
508 //return new TextIterator (getEmbed (), mask, atEnd,
509 // isActivated () ? "[X]" : "[ ]");
511 return new EmptyIterator (getEmbed (), mask, atEnd);
512}
513
514// ----------------------------------------------------------------------
515
519
521{
522 //return new TextIterator (getEmbed (), mask, atEnd,
523 // isActivated () ? "(*)" : "( )");
525 return new EmptyIterator (getEmbed (), mask, atEnd);
526}
527
528} // namespace ui
529} // namespace core
530} // namespace dw
531
Set at the top when drawing.
Definition types.hh:295
This implementation of dw::core::Iterator can be used by widgets with no contents.
Definition iterator.hh:97
Represents a button press or release event.
Definition events.hh:58
Represents a enter or leave notify event.
Definition events.hh:75
Iterators are used to iterate through the contents of a widget.
Definition iterator.hh:20
The central class for managing and drawing a widget tree.
Definition layout.hh:17
dw::core::Shape implemtation for simple rectangles.
Definition types.hh:70
An interface to encapsulate platform dependent drawing.
Definition view.hh:17
The base class of all dillo widgets.
Definition widget.hh:44
virtual void setStyle(style::Style *style)
Change the style of a widget.
Definition widget.cc:1316
virtual void leaveNotifyImpl(EventCrossing *event)
Definition widget.cc:2227
Extremes extremes
Analogue to dw::core::Widget::requisition.
Definition widget.hh:166
Allocation allocation
The current allocation: size and position, always relative to the canvas.
Definition widget.hh:204
int getAvailWidth(bool forceValue)
Return available width including margin/border/padding (extraSpace?), not only the content width.
Definition widget.cc:665
void drawWidgetBox(View *view, Rectangle *area, bool inverse)
Draw borders and background of a widget.
Definition widget.cc:1512
void correctRequisition(Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition widget.cc:820
style::Style * getStyle()
Definition widget.hh:482
Requisition requisition
Size_request() stores the result of the last call of size_request_impl().
Definition widget.hh:160
virtual void enterNotifyImpl(EventCrossing *event)
Definition widget.cc:2219
int getAvailHeight(bool forceValue)
Return available height including margin/border/padding (extraSpace?), not only the content height.
Definition widget.cc:705
style::Style * style
Definition widget.hh:150
virtual int applyPerWidth(int containerWidth, style::Length perWidth)
Definition widget.cc:1757
void correctExtremes(Extremes *extremes, bool useAdjustmentWidth)
Definition widget.cc:870
Iterator * iterator(Content::Type mask, bool atEnd)
Definition ui.cc:506
void resizeQueued(bool extremesChanged)
Definition ui.cc:327
void setEmbed(Embed *embed)
Definition ui.cc:358
int getAvailHeightOfChild(Widget *child, bool forceValue)
Definition ui.cc:416
void sizeRequest(Requisition *requisition)
Definition ui.cc:372
Iterator * iterator(Content::Type mask, bool atEnd)
Definition ui.cc:486
void sizeAllocate(Allocation *allocation)
Definition ui.cc:403
void correctRequisitionOfChild(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition ui.cc:426
void correctExtremesOfChild(Widget *child, Extremes *extremes, bool useAdjustmentWidth)
Definition ui.cc:459
void init(Widget *widget)
Definition ui.cc:343
void getExtremes(Extremes *extremes)
Definition ui.cc:387
int getAvailWidthOfChild(Widget *child, bool forceValue)
Definition ui.cc:407
A widget for embedding UI widgets.
Definition ui.hh:224
void correctRequisitionOfChild(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition ui.cc:82
void setEnabled(bool enabled)
Definition ui.cc:136
void correctExtremesOfChild(Widget *child, Extremes *extremes, bool useAdjustmentWidth)
Definition ui.cc:93
void leaveNotifyImpl(core::EventCrossing *event)
Definition ui.cc:112
void enterNotifyImpl(core::EventCrossing *event)
Definition ui.cc:106
void correctReqHeightOfChildNoRec(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseHeight)
Definition ui.hh:270
int getAvailHeightOfChild(Widget *child, bool forceValue)
Definition ui.cc:77
Resource * resource
Definition ui.hh:228
static int CLASS_ID
Definition ui.hh:252
void draw(View *view, Rectangle *area, DrawingContext *context)
Area is given in widget coordinates.
Definition ui.cc:141
void setDisplayed(bool displayed)
Definition ui.cc:131
Iterator * iterator(Content::Type mask, bool atEnd)
Return an iterator for this widget.
Definition ui.cc:147
int getAvailWidthOfChild(Widget *child, bool forceValue)
Computes the content width available of a child widget.
Definition ui.cc:72
void getExtremesSimpl(Extremes *extremes)
Simple variant, to be implemented by widgets with extremes not depending on positions.
Definition ui.cc:59
void correctReqWidthOfChildNoRec(Widget *child, Requisition *requisition, bool allowDecreaseWidth)
Definition ui.hh:265
void sizeAllocateImpl(Allocation *allocation)
See Sizes of Dillo Widgets.
Definition ui.cc:67
void sizeRequestSimpl(Requisition *requisition)
Simple variant, to be implemented by widgets with sizes not depending on positions.
Definition ui.cc:52
void containerSizeChangedForChildren()
Definition ui.cc:99
bool buttonPressImpl(core::EventButton *event)
Definition ui.cc:118
void setStyle(style::Style *style)
Change the style of a widget.
Definition ui.cc:152
virtual void correctExtremesOfChildNoRec(Widget *child, Extremes *extremes, bool useAdjustmentWidth)
Definition ui.hh:278
Embed(Resource *resource)
Definition ui.cc:37
Iterator * iterator(Content::Type mask, bool atEnd)
Definition ui.cc:317
Iterator * iterator(Content::Type mask, bool atEnd)
Definition ui.cc:520
bool emitToReceiver(lout::signal::Receiver *receiver, int signalNo, int argc, Object **argv)
A sub class must implement this for a call to a single receiver.
Definition ui.cc:160
void emitEnter(Resource *resource)
Definition ui.cc:191
void emitActivate(Resource *resource)
Definition ui.cc:184
void emitLeave(Resource *resource)
Definition ui.cc:198
Receiver interface for the "activate" signal.
Definition ui.hh:297
virtual void activate(Resource *resource)=0
virtual void leave(Resource *resource)=0
virtual void enter(Resource *resource)=0
bool emitToReceiver(lout::signal::Receiver *receiver, int signalNo, int argc, Object **argv)
A sub class must implement this for a call to a single receiver.
Definition ui.cc:296
void emitClicked(Resource *resource, EventButton *event)
Definition ui.cc:306
Receiver interface for the "clicked" signal.
Definition ui.hh:307
Basic interface for all resources.
Definition ui.hh:289
virtual ~Resource()
Definition ui.cc:207
virtual void setEnabled(bool enabled)=0
virtual Iterator * iterator(Content::Type mask, bool atEnd)=0
virtual void containerSizeChangedForChildren()
Definition ui.cc:269
virtual int getAvailWidthOfChild(Widget *child, bool forceValue)
Definition ui.cc:237
virtual int getAvailHeightOfChild(Widget *child, bool forceValue)
Definition ui.cc:244
virtual void sizeAllocate(Allocation *allocation)
Definition ui.cc:233
virtual void setEmbed(Embed *embed)
Definition ui.cc:212
virtual void setDisplayed(bool displayed)
Definition ui.cc:274
virtual void draw(View *view, Rectangle *area, DrawingContext *context)
Definition ui.cc:278
virtual void correctExtremesOfChild(Widget *child, Extremes *extremes, bool useAdjustmentWidth)
Definition ui.cc:262
void emitClicked(EventButton *event)
Definition ui.hh:353
virtual void setStyle(style::Style *style)
Definition ui.cc:282
virtual void correctRequisitionOfChild(Widget *child, Requisition *requisition, void(*splitHeightFun)(int, int *, int *), bool allowDecreaseWidth, bool allowDecreaseHeight)
Definition ui.cc:251
virtual void getExtremes(Extremes *extremes)
Definition ui.cc:217
virtual Embed * getEmbed()
Definition ui.hh:348
ActivateEmitter activateEmitter
Definition ui.hh:338
virtual void sizeRequest(Requisition *requisition)=0
Iterator * iterator(Content::Type mask, bool atEnd)
Definition ui.cc:497
void registerName(const char *className, int *classId)
This method must be called in the constructor for the sub class.
Definition identity.cc:83
This is the base class for many other classes, which defines very common virtual methods.
Definition object.hh:25
An object::Object wrapper for void pointers.
Definition object.hh:100
The base class for signal receiver base classes.
Definition signal.hh:254
#define DBG_OBJ_ENTER0(aspect, prio, funname)
#define DBG_OBJ_DELETE()
#define DBG_OBJ_CREATE(klass)
#define DBG_OBJ_MSGF(aspect, prio, fmt,...)
#define DBG_OBJ_ENTER(aspect, prio, funname, fmt,...)
#define DBG_OBJ_LEAVE()
#define DBG_OBJ_ASSOC_CHILD(child)
static Layout * layout
bool isPerLength(Length l)
Returns true if l is a percentage.
Definition style.hh:446
void splitHeightPreserveAscent(int height, int *ascent, int *descent)
Definition widget.cc:2244
Dw is in this namespace, or sub namespaces of this one.
T min(T a, T b)
Definition misc.hh:40
void notImplemented(const char *name)
Definition misc.hh:76
T max(T a, T b)
Definition misc.hh:41
void assertNotReached()
Definition misc.hh:56
Here, some common classes (or interfaces) are defined, to standardize the access to other classes.
Definition object.cc:30
Represents the allocation, i.e.
Definition types.hh:164