24 #include "../lout/msg.h" 25 #include "../lout/debug.hh" 26 #include "../lout/misc.hh" 35 bool Layout::LayoutImgRenderer::readyToDraw ()
40 void Layout::LayoutImgRenderer::getBgArea (
int *x,
int *y,
int *width,
44 getRefArea (x, y, width, height);
47 void Layout::LayoutImgRenderer::getRefArea (
int *xRef,
int *yRef,
int *widthRef,
52 *widthRef =
misc::max (layout->viewportWidth
53 - (layout->canvasHeightGreater ?
54 layout->vScrollbarThickness : 0),
56 *heightRef =
misc::max (layout->viewportHeight
57 - layout->hScrollbarThickness,
58 layout->canvasAscent + layout->canvasDescent);
63 return layout->bgImage;
68 return layout->bgRepeat;
72 Layout::LayoutImgRenderer::getBackgroundAttachment ()
74 return layout->bgAttachment;
79 return layout->bgPositionX;
84 return layout->bgPositionY;
87 void Layout::LayoutImgRenderer::draw (
int x,
int y,
int width,
int height)
89 layout->queueDraw (x, y, width, height);
94 void Layout::Receiver::canvasSizeChanged (
int width,
int ascent,
int descent)
101 int signalNo,
int argc,
107 case CANVAS_SIZE_CHANGED:
109 ((
Integer*)argv[1])->getValue (),
110 ((
Integer*)argv[2])->getValue ());
120 void Layout::Emitter::emitCanvasSizeChanged (
int width,
121 int ascent,
int descent)
123 Integer w (width), a (ascent), d (descent);
124 Object *argv[3] = { &w, &a, &d };
125 emitVoid (CANVAS_SIZE_CHANGED, 3, argv);
130 bool Layout::LinkReceiver::enter (
Widget *widget,
int link,
int img,
136 bool Layout::LinkReceiver::press (
Widget *widget,
int link,
int img,
142 bool Layout::LinkReceiver::release (
Widget *widget,
int link,
int img,
148 bool Layout::LinkReceiver::click (
Widget *widget,
int link,
int img,
157 int signalNo,
int argc,
165 ((
Integer*)argv[1])->getValue (),
166 ((
Integer*)argv[2])->getValue (),
167 ((
Integer*)argv[3])->getValue (),
168 ((
Integer*)argv[4])->getValue ());
172 ((
Integer*)argv[1])->getValue (),
173 ((
Integer*)argv[2])->getValue (),
174 ((
Integer*)argv[3])->getValue (),
175 ((
Integer*)argv[4])->getValue (),
180 ((
Integer*)argv[1])->getValue (),
181 ((
Integer*)argv[2])->getValue (),
182 ((
Integer*)argv[3])->getValue (),
183 ((
Integer*)argv[4])->getValue (),
188 ((
Integer*)argv[1])->getValue (),
189 ((
Integer*)argv[2])->getValue (),
190 ((
Integer*)argv[3])->getValue (),
191 ((
Integer*)argv[4])->getValue (),
200 bool Layout::LinkEmitter::emitEnter (
Widget *widget,
int link,
int img,
203 Integer ilink (link), iimg (img), ix (x), iy (y);
204 Object *argv[5] = { widget, &ilink, &iimg, &ix, &iy };
205 return emitBool (ENTER, 5, argv);
208 bool Layout::LinkEmitter::emitPress (
Widget *widget,
int link,
int img,
211 Integer ilink (link), iimg (img), ix (x), iy (y);
212 Object *argv[6] = { widget, &ilink, &iimg, &ix, &iy,
event };
213 return emitBool (PRESS, 6, argv);
216 bool Layout::LinkEmitter::emitRelease (
Widget *widget,
int link,
int img,
219 Integer ilink (link), iimg (img), ix (x), iy (y);
220 Object *argv[6] = { widget, &ilink, &iimg, &ix, &iy,
event };
221 return emitBool (RELEASE, 6, argv);
224 bool Layout::LinkEmitter::emitClick (
Widget *widget,
int link,
int img,
227 Integer ilink (link), iimg (img), ix (x), iy (y);
228 Object *argv[6] = { widget, &ilink, &iimg, &ix, &iy,
event };
229 return emitBool (CLICK, 6, argv);
234 Layout::Anchor::~Anchor ()
243 this->platform = platform;
246 widgetAtPoint = NULL;
254 canvasWidth = canvasAscent = canvasDescent = 0;
256 usesViewport =
false;
257 drawAfterScrollReq =
false;
258 scrollX = scrollY = 0;
259 viewportWidth = viewportHeight = 0;
260 hScrollbarThickness = vScrollbarThickness = 0;
262 requestedAnchor = NULL;
264 scrollIdleNotInterrupted =
false;
278 selectionState.setLayout(
this);
280 layoutImgRenderer = NULL;
285 widgetAtPoint = NULL;
287 if (layoutImgRenderer) {
289 bgImage->removeExternalImgRenderer (layoutImgRenderer);
290 delete layoutImgRenderer;
293 if (scrollIdleId != -1)
294 platform->removeIdle (scrollIdleId);
295 if (resizeIdleId != -1)
296 platform->removeIdle (resizeIdleId);
326 canvasHeightGreater =
false;
331 void Layout::removeWidget ()
337 widgetAtPoint = NULL;
338 canvasWidth = canvasAscent = canvasDescent = 0;
339 scrollX = scrollY = 0;
341 view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent);
342 if (view->usesViewport ())
343 view->setViewportSize (viewportWidth, viewportHeight, 0, 0);
344 view->queueDrawTotal ();
349 emitter.emitCanvasSizeChanged (canvasWidth, canvasAscent, canvasDescent);
351 findtextState.setWidget (NULL);
352 selectionState.reset ();
361 widgetAtPoint = NULL;
367 textZone->zoneFree ();
379 void Layout::attachView (
View *view)
382 MSG_ERR(
"attachView: Multiple views for layout!\n");
387 platform->attachView (view);
397 view->
setCanvasSize (canvasWidth, canvasAscent, canvasDescent);
403 hScrollbarThickness, vScrollbarThickness);
404 hScrollbarThickness =
misc::max (hScrollbarThickness,
406 vScrollbarThickness =
misc::max (vScrollbarThickness,
411 scrollX = scrollY = 0;
412 viewportWidth = viewportHeight = 100;
426 void Layout::detachView (
View *view)
428 if (this->view != view)
429 MSG_ERR(
"detachView: this->view: %p view %p\n", this->view, view);
432 platform->detachView (view);
444 if (view->usesViewport ())
453 int x,
int y,
int width,
int height)
455 scrollTo0 (hpos, vpos, x, y, width, height,
true);
459 int x,
int y,
int width,
int height,
460 bool scrollingInterrupted)
463 _MSG(
"scrollTo (%d, %d, %s)\n",
464 x, y, scrollingInterrupted ?
"true" :
"false");
466 scrollTargetHpos = hpos;
467 scrollTargetVpos = vpos;
470 scrollTargetWidth = width;
471 scrollTargetHeight = height;
473 if (scrollIdleId == -1) {
474 scrollIdleId = platform->addIdle (&Layout::scrollIdle);
475 scrollIdleNotInterrupted =
true;
478 scrollIdleNotInterrupted =
479 scrollIdleNotInterrupted || !scrollingInterrupted;
483 void Layout::scrollIdle ()
485 bool xChanged =
true;
486 switch (scrollTargetHpos) {
488 scrollX = scrollTargetX;
493 - (viewportWidth - currVScrollbarThickness() - scrollTargetWidth) / 2;
498 - (viewportWidth - currVScrollbarThickness() - scrollTargetWidth);
501 xChanged = calcScrollInto (scrollTargetX, scrollTargetWidth, &scrollX,
502 viewportWidth - currVScrollbarThickness());
509 bool yChanged =
true;
510 switch (scrollTargetVpos) {
512 scrollY = scrollTargetY;
517 - (viewportHeight - currHScrollbarThickness() - scrollTargetHeight)/2;
522 - (viewportHeight - currHScrollbarThickness() - scrollTargetHeight);
525 yChanged = calcScrollInto (scrollTargetY, scrollTargetHeight, &scrollY,
526 viewportHeight - currHScrollbarThickness());
533 if (xChanged || yChanged) {
535 view->scrollTo (scrollX, scrollY);
536 if (drawAfterScrollReq) {
537 drawAfterScrollReq =
false;
538 view->queueDrawTotal ();
545 void Layout::adjustScrollPos ()
548 canvasWidth - (viewportWidth - vScrollbarThickness));
552 canvasAscent + canvasDescent - (viewportHeight - hScrollbarThickness));
555 _MSG(
"adjustScrollPos: scrollX=%d scrollY=%d\n", scrollX, scrollY);
558 bool Layout::calcScrollInto (
int requestedValue,
int requestedSize,
559 int *value,
int viewportSize)
561 if (requestedSize > viewportSize) {
566 if (*value >= requestedValue &&
567 *value + viewportSize < requestedValue + requestedSize)
570 requestedSize = viewportSize;
573 if (requestedValue < *value) {
574 *value = requestedValue;
576 }
else if (requestedValue + requestedSize > *value + viewportSize) {
577 *value = requestedValue - viewportSize + requestedSize;
585 Rectangle widgetArea, intersection, widgetDrawArea;
589 if (bgImage != NULL && bgImage->getImgbufSrc() != NULL)
591 bgPositionX, bgPositionY,
597 - (canvasHeightGreater ?
598 vScrollbarThickness : 0),
601 - hScrollbarThickness,
602 canvasAscent + canvasDescent));
604 if (scrollIdleId != -1) {
606 drawAfterScrollReq =
true;
608 }
else if (topLevel) {
610 widgetArea.
x = topLevel->allocation.x;
611 widgetArea.
y = topLevel->allocation.y;
612 widgetArea.
width = topLevel->allocation.width;
613 widgetArea.
height = topLevel->getHeight ();
619 widgetDrawArea.
x = intersection.
x - topLevel->allocation.x;
620 widgetDrawArea.
y = intersection.
y - topLevel->allocation.y;
624 topLevel->draw (view, &widgetDrawArea);
631 int Layout::currHScrollbarThickness()
633 return (canvasWidth > viewportWidth) ? hScrollbarThickness : 0;
636 int Layout::currVScrollbarThickness()
638 return (canvasAscent + canvasDescent > viewportHeight) ?
639 vScrollbarThickness : 0;
645 void Layout::setAnchor (
const char *anchor)
647 _MSG(
"setAnchor (%s)\n", anchor);
650 free(requestedAnchor);
651 requestedAnchor = anchor ? strdup (anchor) : NULL;
658 char *Layout::addAnchor (
Widget *widget,
const char* name)
660 return addAnchor (widget, name, -1);
663 char *Layout::addAnchor (
Widget *widget,
const char* name,
int y)
666 if (anchorsTable->contains (&
key))
670 anchor->
name = strdup (name);
674 anchorsTable->put (
new String (name), anchor);
681 void Layout::changeAnchor (
Widget *widget,
char* name,
int y)
684 Anchor *anchor = anchorsTable->get (&
key);
686 assert (anchor->
widget == widget);
691 void Layout::removeAnchor (
Widget *widget,
char* name)
694 anchorsTable->remove (&
key);
697 void Layout::updateAnchor ()
700 if (requestedAnchor) {
702 anchor = anchorsTable->get (&
key);
706 if (anchor == NULL) {
708 if (scrollIdleId != -1 && !scrollIdleNotInterrupted) {
709 platform->removeIdle (scrollIdleId);
719 if (cursor != this->cursor) {
720 this->cursor = cursor;
721 view->setCursor (cursor);
725 void Layout::updateCursor ()
727 if (widgetAtPoint && widgetAtPoint->style)
728 setCursor (widgetAtPoint->style->cursor);
743 view->setBgColor (bgColor);
751 if (layoutImgRenderer && this->bgImage)
758 this->bgImage->
unref ();
760 this->bgImage = bgImage;
761 this->bgRepeat = bgRepeat;
762 this->bgAttachment = bgAttachment;
763 this->bgPositionX = bgPositionX;
764 this->bgPositionY = bgPositionY;
770 if (layoutImgRenderer == NULL)
777 void Layout::resizeIdle ()
782 assert (resizeIdleId != -1);
792 topLevel->sizeRequest (&requisition);
794 allocation.
x = allocation.
y = 0;
798 topLevel->sizeAllocate (&allocation);
800 canvasWidth = requisition.
width;
801 canvasAscent = requisition.
ascent;
802 canvasDescent = requisition.
descent;
804 emitter.emitCanvasSizeChanged (canvasWidth, canvasAscent, canvasDescent);
807 view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent);
811 int currHThickness = currHScrollbarThickness();
812 int currVThickness = currVScrollbarThickness();
814 if (!canvasHeightGreater &&
815 canvasAscent + canvasDescent
816 > viewportHeight - currHThickness) {
817 canvasHeightGreater =
true;
823 view->setViewportSize (viewportWidth, viewportHeight,
824 currHThickness, currVThickness);
834 void Layout::setSizeHints ()
837 topLevel->setWidth (viewportWidth
838 - (canvasHeightGreater ? vScrollbarThickness : 0));
839 topLevel->setAscent (viewportHeight - hScrollbarThickness);
840 topLevel->setDescent (0);
844 void Layout::queueDraw (
int x,
int y,
int width,
int height)
854 view->queueDraw (&area);
857 void Layout::queueDrawExcept (
int x,
int y,
int width,
int height,
858 int ex,
int ey,
int ewidth,
int eheight) {
860 if (x == ex && y == ey && width == ewidth && height == eheight)
871 int ix2 =
misc::min (x + width, ex + ewidth);
872 int iy2 =
misc::min (y + height, ey + eheight);
874 queueDraw (x, y, width, iy1 - y);
875 queueDraw (x, iy2, width, y + height - iy2);
876 queueDraw (x, iy1, ix1 - x, iy2 - iy1);
877 queueDraw (ix2, iy1, x + width - ix2, iy2 - iy1);
880 void Layout::queueResize ()
882 if (resizeIdleId == -1) {
883 view->cancelQueueDraw ();
885 resizeIdleId = platform->addIdle (&Layout::resizeIdle);
898 moveToWidgetAtPoint (x, y, state);
903 event.button = button;
904 event.numPressed = numPressed;
906 return processMouseEvent (&event, type);
919 moveToWidgetAtPoint (x, y, state);
925 return processMouseEvent (&event, MOTION_NOTIFY);
938 lastWidget = widgetAtPoint;
939 moveToWidgetAtPoint (x, y, state);
943 event.lastWidget = lastWidget;
944 event.currentWidget = widgetAtPoint;
960 lastWidget = widgetAtPoint;
961 moveOutOfView (state);
965 event.lastWidget = lastWidget;
966 event.currentWidget = widgetAtPoint;
970 moveOutOfView (state);
977 Widget *Layout::getWidgetAtPoint (
int x,
int y)
979 _MSG (
"------------------------------------------------------------\n");
980 _MSG (
"widget at (%d, %d)\n", x, y);
982 return topLevel->getWidgetAtPoint (x, y, 0);
996 int trackLen, i, i_a;
999 _MSG(
"moveToWidget: wap=%p nwap=%p\n",widgetAtPoint,newWidgetAtPoint);
1000 if (newWidgetAtPoint != widgetAtPoint) {
1002 if (newWidgetAtPoint && widgetAtPoint)
1005 else if (newWidgetAtPoint)
1014 for (w = widgetAtPoint; w != ancestor; w = w->
getParent ())
1017 if (newWidgetAtPoint)
1019 for (w = newWidgetAtPoint; w != ancestor; w = w->
getParent ())
1022 track =
new Widget* [trackLen];
1026 for (w = widgetAtPoint; w != ancestor; w = w->
getParent ())
1029 track[i++] = ancestor;
1030 if (newWidgetAtPoint) {
1033 for (w = newWidgetAtPoint; w != ancestor; w = w->
getParent ())
1037 MSG(
"Track: %s[ ", widgetAtPoint ?
"" :
"nil ");
1038 for (i = 0; i < trackLen; i++)
1039 MSG(
"%s%p ", i == i_a ?
">" :
"", track[i]);
1040 MSG(
"] %s\n", newWidgetAtPoint ?
"" :
"nil");
1044 for (i = 0; i < trackLen; i++) {
1045 crossingEvent.
state = state;
1050 }
else if (i == i_a) {
1054 if (i_a == trackLen-1 && !newWidgetAtPoint)
1056 else if ((i_a == 0 && !widgetAtPoint) ||
1057 (i_a == trackLen-1 && newWidgetAtPoint))
1066 widgetAtPoint = newWidgetAtPoint;
1088 event->xCanvas = scrollX;
1090 int maxX = scrollX + viewportWidth - currVScrollbarThickness() - 1;
1093 event->xCanvas = maxX;
1096 event->yCanvas = scrollY;
1098 int maxY =
misc::min(scrollY + viewportHeight -currHScrollbarThickness(),
1099 canvasAscent + canvasDescent) - 1;
1102 event->yCanvas = maxY;
1107 for (; widget; widget = widget->
getParent ()) {
1116 case BUTTON_RELEASE:
1127 if (type == BUTTON_PRESS)
1128 return emitLinkPress (NULL, -1, -1, -1, -1, (
EventButton*)event);
1129 else if (type == BUTTON_RELEASE)
1130 return emitLinkRelease(NULL, -1, -1, -1, -1, (
EventButton*)event);
1140 void Layout::scrollPosChanged (
View *view,
int x,
int y)
1142 if (x != scrollX || y != scrollY) {
1155 void Layout::viewportSizeChanged (
View *view,
int width,
int height)
1157 _MSG(
"Layout::viewportSizeChanged w=%d h=%d new_w=%d new_h=%d\n",
1158 viewportWidth, viewportHeight, width, height);
1162 if (usesViewport && width > viewportWidth)
1163 canvasHeightGreater =
false;
1167 if (viewportWidth != width || viewportHeight != height)
1170 viewportWidth = width;
1171 viewportHeight = height;