Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / area.c
blobb13ba32c87456217ac888c301b2533d888b43f15
1 /*
2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2011, The AROS Development Team.
4 All rights reserved.
6 $Id$
7 */
9 #include <stdlib.h>
10 #include <string.h>
11 #include <exec/types.h>
12 #include <graphics/gfxmacros.h>
13 #include <intuition/imageclass.h>
14 #include <libraries/gadtools.h>
16 #include <clib/alib_protos.h>
17 #include <proto/exec.h>
18 #include <proto/intuition.h>
19 #include <proto/graphics.h>
20 #include <proto/utility.h>
21 #include <proto/muimaster.h>
23 extern struct Library *MUIMasterBase;
24 #include "muimaster_intern.h"
26 #include "mui.h"
27 #include "support.h"
28 #include "imspec.h"
29 #include "menu.h"
30 #include "prefs.h"
31 #include "font.h"
32 #include "textengine.h"
33 #include "bubbleengine.h"
34 #include "datatypescache.h"
37 // #define MYDEBUG 1
38 #include "debug.h"
41 Area.mui/MUIA_Background done
42 Area.mui/MUIA_BottomEdge done
43 Area.mui/MUIA_ContextMenu done
44 Area.mui/MUIA_ContextMenuTrigger
45 Area.mui/MUIA_ControlChar done
46 Area.mui/MUIA_CycleChain done
47 Area.mui/MUIA_Disabled done
48 Area.mui/MUIA_Draggable done
49 Area.mui/MUIA_Dropable done
50 Area.mui/MUIA_ExportID
51 Area.mui/MUIA_FillArea done
52 Area.mui/MUIA_FixHeight done
53 Area.mui/MUIA_FixHeightTxt done
54 Area.mui/MUIA_FixWidth done
55 Area.mui/MUIA_FixWidthTxt done
56 Area.mui/MUIA_Font done
57 Area.mui/MUIA_Frame done
58 Area.mui/MUIA_FramePhantomHoriz done
59 Area.mui/MUIA_FrameTitle done
60 Area.mui/MUIA_Height done
61 Area.mui/MUIA_HorizDisappear
62 Area.mui/MUIA_HorizWeight done
63 Area.mui/MUIA_InnerBottom done
64 Area.mui/MUIA_InnerLeft done
65 Area.mui/MUIA_InnerRight done
66 Area.mui/MUIA_InnerTop done
67 Area.mui/MUIA_InputMode done
68 Area.mui/MUIA_LeftEdge done
69 Area.mui/MUIA_MaxHeight done
70 Area.mui/MUIA_MaxWidth done
71 Area.mui/MUIA_Pressed done
72 Area.mui/MUIA_RightEdge done
73 Area.mui/MUIA_Selected done
74 Area.mui/MUIA_ShortHelp done
75 Area.mui/MUIA_ShowMe done
76 Area.mui/MUIA_ShowSelState done (I only)
77 Area.mui/MUIA_Timer done
78 Area.mui/MUIA_TopEdge done
79 Area.mui/MUIA_VertDisappear
80 Area.mui/MUIA_VertWeight done
81 Area.mui/MUIA_Weight done
82 Area.mui/MUIA_Width done
83 Area.mui/MUIA_Window done
84 Area.mui/MUIA_WindowObject done
86 Area.mui/MUIM_AskMinMax done
87 Area.mui/MUIM_Cleanup done
88 Area.mui/MUIM_ContextMenuBuild done
89 Area.mui/MUIM_ContextMenuChoice done
90 Area.mui/MUIM_CreateBubble
91 Area.mui/MUIM_CreateShortHelp
92 Area.mui/MUIM_DeleteBubble
93 Area.mui/MUIM_DeleteShortHelp
94 Area.mui/MUIM_DragBegin
95 Area.mui/MUIM_DragDrop done
96 Area.mui/MUIM_DragFinish
97 Area.mui/MUIM_DragQuery done
98 Area.mui/MUIM_DragReport
99 Area.mui/MUIM_Draw done
100 Area.mui/MUIM_DrawBackground done
101 Area.mui/MUIM_HandleEvent done
102 Area.mui/MUIM_HandleInput
103 Area.mui/MUIM_Hide done
104 Area.mui/MUIM_Setup done
105 Area.mui/MUIM_Show done
108 static const int __version = 1;
109 static const int __revision = 1;
111 //#ifdef DEBUG
112 //static STRPTR zune_area_to_string (Object *area);
113 //#endif
115 static const struct MUI_FrameSpec_intern *get_intframe(Object *obj,
116 struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore);
117 static void set_inner_sizes(Object *obj, struct MUI_AreaData *data);
118 static void set_title_sizes(Object *obj, struct MUI_AreaData *data);
120 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
121 const struct MUI_FrameSpec_intern *frame,
122 const struct ZuneFrameGfx *zframe);
123 static void setup_control_char(struct MUI_AreaData *data, Object *obj,
124 struct IClass *cl);
125 static void cleanup_control_char(struct MUI_AreaData *data, Object *obj);
127 //static void setup_cycle_chain (struct MUI_AreaData *data, Object *obj);
128 //static void cleanup_cycle_chain (struct MUI_AreaData *data, Object *obj);
130 #define ZUNE_FOCUS_TYPE_ACTIVE_OBJ 0
131 #define ZUNE_FOCUS_TYPE_DROP_OBJ 1
133 static void _zune_focus_new(Object *obj, int type)
135 Object *parent;
136 struct RastPort *rp;
137 UWORD oldDrPt;
139 //bug("_zune_focus_new 1 %p\n", obj);
141 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
142 return;
144 parent = _parent(obj);
145 rp = _rp(obj);
146 oldDrPt = rp->LinePtrn;
148 int x1 = _left(obj);
149 int y1 = _top(obj);
150 int x2 = _left(obj) + _width(obj) - 1;
151 int y2 = _top(obj) + _height(obj) - 1;
153 if (!parent || parent == _win(obj))
154 return;
156 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], _pens(obj)[MPEN_SHADOW], JAM2);
158 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
160 SetDrPt(rp, 0xCCCC);
161 x1--;
162 y1--;
163 x2++;
164 y2++;
166 else
168 SetDrPt(rp, 0xF0F0);
171 Move(rp, x1, y1);
172 Draw(rp, x2, y1);
173 Draw(rp, x2, y2);
174 Draw(rp, x1, y2);
175 Draw(rp, x1, y1);
176 SetDrPt(rp, oldDrPt);
179 static void _zune_focus_destroy(Object *obj, int type)
181 Object *parent;
183 //bug("_zune_focus_destroy 1 %p\n", obj);
185 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
186 return;
188 parent = _parent(obj);
189 int x1 = _left(obj);
190 int y1 = _top(obj);
191 int x2 = _left(obj) + _width(obj) - 1;
192 int y2 = _top(obj) + _height(obj) - 1;
193 int width;
194 int height;
196 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
198 if (!parent || parent == _win(obj))
199 return;
201 x1--;
202 y1--;
203 x2++;
204 y2++;
205 width = x2 - x1 + 1;
206 height = y2 - y1 + 1;
208 DoMethod(parent, MUIM_DrawBackground, x1, y1, width, 1, x1, y1, 0);
209 DoMethod(parent, MUIM_DrawBackground, x2, y1, 1, height, x2, y1, 0);
210 DoMethod(parent, MUIM_DrawBackground, x1, y2, width, 1, x1, y2, 0);
211 DoMethod(parent, MUIM_DrawBackground, x1, y1, 1, height, x1, y1, 0);
213 else
215 struct Region *region;
216 struct Rectangle rect;
217 APTR clip = NULL;
219 region = NewRegion();
220 if (region)
222 rect.MinX = _left(obj);
223 rect.MinY = _top(obj);
224 rect.MaxX = _right(obj);
225 rect.MaxY = _top(obj);
227 OrRectRegion(region, &rect);
229 rect.MinX = _right(obj);
230 rect.MinY = _top(obj);
231 rect.MaxX = _right(obj);
232 rect.MaxY = _bottom(obj);
234 OrRectRegion(region, &rect);
236 rect.MinX = _left(obj);
237 rect.MinY = _bottom(obj);
238 rect.MaxX = _right(obj);
239 rect.MaxY = _bottom(obj);
241 OrRectRegion(region, &rect);
243 rect.MinX = _left(obj);
244 rect.MinY = _top(obj);
245 rect.MaxX = _left(obj);
246 rect.MaxY = _bottom(obj);
248 OrRectRegion(region, &rect);
250 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
254 MUI_Redraw(obj, MADF_DRAWOBJECT);
256 if (region)
258 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
264 /**************************************************************************
265 OM_NEW
266 **************************************************************************/
267 static IPTR Area__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
269 struct MUI_AreaData *data;
270 struct TagItem *tags, *tag;
272 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
273 if (!obj)
274 return FALSE;
276 /* Initial local instance data */
277 data = INST_DATA(cl, obj);
279 data->mad_Flags =
280 MADF_FILLAREA | MADF_SHOWME | MADF_SHOWSELSTATE | MADF_DROPABLE;
281 data->mad_HorizWeight = data->mad_VertWeight = 100;
282 data->mad_InputMode = MUIV_InputMode_None;
284 /* parse initial taglist */
286 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
288 switch (tag->ti_Tag)
290 case MUIA_Background:
292 data->mad_Flags |= MADF_OWNBG;
293 if (data->mad_BackgroundSpec)
295 zune_image_spec_free(data->mad_BackgroundSpec);
297 data->mad_BackgroundSpec =
298 zune_image_spec_duplicate(tag->ti_Data);
300 break;
302 case MUIA_ControlChar:
303 data->mad_ControlChar = tag->ti_Data;
304 break;
306 case MUIA_CycleChain:
307 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
308 MADF_CYCLECHAIN);
309 break;
311 case MUIA_Disabled:
312 case MUIA_NestedDisabled:
313 if (tag->ti_Data)
315 data->mad_DisableCount = 1;
317 break;
319 case MUIA_FillArea:
320 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
321 break;
323 case MUIA_Draggable:
324 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
325 break;
327 case MUIA_Dropable:
328 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
329 break;
331 case MUIA_FixHeight:
332 data->mad_Flags |= MADF_FIXHEIGHT;
333 data->mad_HardHeight = tag->ti_Data;
334 break;
336 case MUIA_FixHeightTxt:
337 data->mad_HardHeightTxt = (STRPTR) tag->ti_Data;
338 break;
340 case MUIA_FixWidth:
341 data->mad_Flags |= MADF_FIXWIDTH;
342 data->mad_HardWidth = tag->ti_Data;
343 break;
345 case MUIA_FixWidthTxt:
346 data->mad_HardWidthTxt = (STRPTR) tag->ti_Data;
347 break;
349 case MUIA_Font:
350 data->mad_FontPreset = tag->ti_Data;
351 break;
353 case MUIA_Frame:
354 data->mad_Frame = tag->ti_Data;
355 break;
357 case MUIA_FramePhantomHoriz:
358 data->mad_Flags |= MADF_FRAMEPHANTOM;
359 break;
361 case MUIA_FrameTitle:
362 data->mad_FrameTitle = (STRPTR) tag->ti_Data;
363 break;
365 case MUIA_HorizWeight:
366 data->mad_HorizWeight = tag->ti_Data;
367 break;
369 case MUIA_InnerBottom:
370 data->mad_Flags |= MADF_INNERBOTTOM;
371 data->mad_InnerBottom = CLAMP((IPTR) tag->ti_Data, 0, 32);
372 break;
374 case MUIA_InnerLeft:
375 data->mad_Flags |= MADF_INNERLEFT;
376 data->mad_InnerLeft = CLAMP((IPTR) tag->ti_Data, 0, 32);
377 break;
379 case MUIA_InnerRight:
380 data->mad_Flags |= MADF_INNERRIGHT;
381 data->mad_InnerRight = CLAMP((IPTR) tag->ti_Data, 0, 32);
382 break;
384 case MUIA_InnerTop:
385 data->mad_Flags |= MADF_INNERTOP;
386 data->mad_InnerTop = CLAMP((IPTR) tag->ti_Data, 0, 32);
387 break;
389 case MUIA_InputMode:
390 data->mad_InputMode = tag->ti_Data;
391 break;
393 case MUIA_MaxHeight:
394 data->mad_Flags |= MADF_MAXHEIGHT;
395 data->mad_HardHeight = tag->ti_Data;
396 break;
398 case MUIA_MaxWidth:
399 data->mad_Flags |= MADF_MAXWIDTH;
400 data->mad_HardWidth = tag->ti_Data;
401 break;
403 case MUIA_Selected:
404 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SELECTED);
405 break;
407 case MUIA_ShortHelp:
408 data->mad_ShortHelp = (STRPTR) tag->ti_Data;
409 break;
411 case MUIA_ShowMe:
412 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWME);
413 break;
415 case MUIA_ShowSelState:
416 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
417 MADF_SHOWSELSTATE);
418 break;
420 case MUIA_VertWeight:
421 data->mad_VertWeight = tag->ti_Data;
422 break;
424 case MUIA_Weight:
425 data->mad_HorizWeight = data->mad_VertWeight = tag->ti_Data;
426 break;
428 case MUIA_ContextMenu:
429 data->mad_ContextMenu = (Object *) tag->ti_Data;
430 break;
434 /* In Soliton MUIA_Selected was setted to MUIV_InputMode_RelVerify (=1)
435 ** for MUIA_Input_Mode MUIV_InputMode_RelVerify which is wrong of
436 ** course but MUI seems to filter this out so we have to do it also
438 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
440 if (data->mad_Flags & MADF_SELECTED)
441 D(bug("MUIA_Selected was set in OM_NEW, "
442 "although being in MUIV_InputMode_RelVerify\n"));
443 data->mad_Flags &= ~MADF_SELECTED;
446 data->mad_ehn.ehn_Events = 0; /* Will be filled on demand */
447 data->mad_ehn.ehn_Priority = -5;
449 /* Please also send mui key events to us, no idea if mui handles this
450 * like this */
451 data->mad_ehn.ehn_Flags = MUI_EHF_ALWAYSKEYS;
452 data->mad_ehn.ehn_Object = obj;
453 data->mad_ehn.ehn_Class = cl;
455 data->mad_hiehn.ehn_Events = 0;
456 data->mad_hiehn.ehn_Priority = -10;
457 data->mad_hiehn.ehn_Flags = MUI_EHF_HANDLEINPUT;
458 data->mad_hiehn.ehn_Object = obj;
459 data->mad_hiehn.ehn_Class = 0;
461 return (IPTR) obj;
464 /**************************************************************************
465 OM_DISPOSE
466 **************************************************************************/
467 static IPTR Area__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
469 struct MUI_AreaData *data = INST_DATA(cl, obj);
471 /* Safe to call this with NULL */
472 zune_image_spec_free(data->mad_BackgroundSpec);
474 return DoSuperMethodA(cl, obj, msg);
478 /**************************************************************************
479 OM_SET
480 **************************************************************************/
481 static IPTR Area__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
483 struct MUI_AreaData *data = INST_DATA(cl, obj);
484 struct TagItem *tags = msg->ops_AttrList;
485 struct TagItem *tag;
486 CONST_STRPTR old_backgroundspec;
488 int change_disable = 0; /* Has the disable state changed? */
490 while ((tag = NextTagItem(&tags)) != NULL)
492 switch (tag->ti_Tag)
494 case MUIA_Background:
495 old_backgroundspec = data->mad_BackgroundSpec;
496 data->mad_BackgroundSpec =
497 zune_image_spec_duplicate(tag->ti_Data);
498 if (!data->mad_BackgroundSpec)
500 /* Out of memory */
501 data->mad_BackgroundSpec = old_backgroundspec;
502 break;
505 data->mad_Flags |= MADF_OWNBG;
507 if (old_backgroundspec
508 && (strcmp(data->mad_BackgroundSpec,
509 old_backgroundspec) == 0))
511 /* New background does not differ from old one */
512 zune_image_spec_free(old_backgroundspec);
513 tag->ti_Tag = TAG_IGNORE;
514 break;
517 zune_image_spec_free(old_backgroundspec);
519 if (data->mad_Background)
521 if (_flags(obj) & MADF_CANDRAW)
523 zune_imspec_hide(data->mad_Background);
525 if (_flags(obj) & MADF_SETUP)
527 zune_imspec_cleanup(data->mad_Background);
528 data->mad_Background = NULL;
532 if (_flags(obj) & MADF_SETUP)
534 data->mad_Background =
535 zune_imspec_setup((IPTR) data->mad_BackgroundSpec,
536 muiRenderInfo(obj));
538 if (_flags(obj) & MADF_CANDRAW)
540 zune_imspec_show(data->mad_Background, obj);
542 MUI_Redraw(obj, MADF_DRAWOBJECT);
543 break;
545 case MUIA_FillArea:
546 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
547 break;
549 case MUIA_Frame:
550 /* this is not documented in MUI but it is possible,
551 and needed to suppress frame for external images */
552 data->mad_Frame = tag->ti_Data;
553 if (muiGlobalInfo(obj))
555 set_inner_sizes(obj, data);
556 set_title_sizes(obj, data);
558 break;
560 case MUIA_ControlChar:
561 if (_flags(obj) & MADF_SETUP)
562 cleanup_control_char(data, obj);
563 data->mad_ControlChar = tag->ti_Data;
564 if (_flags(obj) & MADF_SETUP)
565 setup_control_char(data, obj, cl);
566 break;
568 case MUIA_CycleChain:
569 // if (data->mad_InputMode == MUIV_InputMode_None)
570 // break;
572 if ((!(_flags(obj) & MADF_CYCLECHAIN) && tag->ti_Data)
573 || ((_flags(obj) & MADF_CYCLECHAIN) && !tag->ti_Data))
575 if (_flags(obj) & MADF_SETUP)
577 cleanup_control_char(data, obj);
578 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
579 MADF_CYCLECHAIN);
580 setup_control_char(data, obj, cl);
582 else
583 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
584 MADF_CYCLECHAIN);
586 break;
588 case MUIA_Disabled:
589 if (tag->ti_Data)
591 if (!data->mad_DisableCount)
593 data->mad_DisableCount = 1;
594 change_disable = 1;
597 else
599 if (data->mad_DisableCount)
601 data->mad_DisableCount = 0;
602 change_disable = 1;
605 break;
607 case MUIA_NestedDisabled:
608 if (tag->ti_Data)
610 if (!data->mad_DisableCount)
611 change_disable = 1;
612 data->mad_DisableCount++;
614 else
616 if (data->mad_DisableCount)
618 data->mad_DisableCount--;
619 if (!data->mad_DisableCount)
620 change_disable = 1;
623 break;
626 case MUIA_HorizWeight:
627 data->mad_HorizWeight = tag->ti_Data;
628 break;
630 case MUIA_Pressed:
631 if (tag->ti_Data)
632 data->mad_Flags |= MADF_PRESSED;
633 else
634 data->mad_Flags &= ~MADF_PRESSED;
635 break;
637 case MUIA_ShortHelp:
638 data->mad_ShortHelp = (STRPTR) tag->ti_Data;
639 break;
641 case MUIA_ShowMe:
643 ULONG oldflags = data->mad_Flags;
644 int recalc = 0;
646 if (tag->ti_Data)
647 data->mad_Flags |= MADF_SHOWME;
648 else
649 data->mad_Flags &= ~MADF_SHOWME;
651 if (oldflags != data->mad_Flags)
653 if (!tag->ti_Data)
655 /* Should be made invisible, so send a MUIM_Hide and
656 ** then a MUIM_Cleanup to the object if needed,
657 ** as objects with MUIA_ShowMe to false get neither
658 ** MUIM_Setup nor MUIM_Show */
659 if (_flags(obj) & MADF_CANDRAW)
661 DoHideMethod(obj);
662 recalc = 1;
664 #if 0 /* SHOWME affects only show/hide */
665 if (_flags(obj) & MADF_SETUP)
666 DoMethod(obj, MUIM_Cleanup);
667 #endif
669 else
671 Object *parent = _parent(obj);
672 /* Will be NULL if direct child of a window! */
674 if (parent)
676 #if 0 /* SHOWME affects only show/hide */
677 if (_flags(parent) & MADF_SETUP)
678 DoSetupMethod(obj, muiRenderInfo(parent));
679 #endif
680 if (_flags(parent) & MADF_CANDRAW)
682 DoShowMethod(obj);
683 recalc = 1;
686 else
688 /* Check if window is open... */
692 /* If renderinfo is NULL _win(obj) doesn't work (crash) */
693 if (recalc && muiRenderInfo(obj))
695 DoMethod(_win(obj), MUIM_Window_RecalcDisplay,
696 (IPTR) _parent(obj));
700 break;
702 case MUIA_Selected:
703 /* D(bug(" Area_Set(%p) :
704 MUIA_Selected val=%ld sss=%d\n", obj, tag->ti_Data,
705 !!(data->mad_Flags & MADF_SHOWSELSTATE)));
707 if (tag->ti_Data && !(data->mad_Flags & MADF_SELECTED))
709 data->mad_Flags |= MADF_SELECTED;
710 MUI_Redraw(obj, MADF_DRAWOBJECT);
712 else if (!tag->ti_Data && (data->mad_Flags & MADF_SELECTED))
714 data->mad_Flags &= ~MADF_SELECTED;
715 MUI_Redraw(obj, MADF_DRAWOBJECT);
717 else
719 tag->ti_Tag = TAG_IGNORE;
721 #if 0
722 if (data->mad_Flags & MADF_SHOWSELSTATE)
723 MUI_Redraw(obj, MADF_DRAWOBJECT);
724 else
725 MUI_Redraw(obj, MADF_DRAWUPDATE);
726 #endif
727 break;
729 case MUIA_Timer:
730 data->mad_Timeval = tag->ti_Data;
731 break;
733 case MUIA_VertWeight:
734 data->mad_VertWeight = tag->ti_Data;
735 break;
737 case MUIA_Draggable:
738 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
739 break;
741 case MUIA_Dropable:
742 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
743 break;
745 case MUIA_ContextMenu:
746 data->mad_ContextMenu = (Object *) tag->ti_Data;
747 break;
749 case MUIA_Font:
750 data->mad_FontPreset = tag->ti_Data;
751 break;
753 case MUIA_InputMode:
754 data->mad_InputMode = tag->ti_Data;
755 break;
760 if (change_disable)
762 MUI_Redraw(obj, MADF_DRAWOBJECT);
765 return DoSuperMethodA(cl, obj, (Msg) msg);
769 /**************************************************************************
770 OM_GET
771 **************************************************************************/
772 static IPTR Area__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
774 #define STORE *(msg->opg_Storage)
776 struct MUI_AreaData *data = INST_DATA(cl, obj);
778 switch (msg->opg_AttrID)
780 case MUIA_Background:
781 STORE = (IPTR) data->mad_Background;
782 return TRUE;
784 case MUIA_BottomEdge:
785 STORE = (IPTR) _bottom(obj);
786 return TRUE;
788 case MUIA_ControlChar:
789 STORE = data->mad_ControlChar;
790 return TRUE;
792 case MUIA_CycleChain:
793 STORE = ((data->mad_Flags & MADF_CYCLECHAIN) != 0);
794 return TRUE;
796 case MUIA_Disabled:
797 case MUIA_NestedDisabled:
798 STORE = ! !data->mad_DisableCount; /* BOOLEAN */
799 return TRUE;
801 case MUIA_Font:
802 STORE = (IPTR) data->mad_FontPreset;
803 return TRUE;
805 case MUIA_Height:
806 STORE = (IPTR) _height(obj);
807 return TRUE;
809 case MUIA_HorizWeight:
810 STORE = (IPTR) data->mad_HorizWeight;
811 return TRUE;
813 case MUIA_InnerBottom:
814 STORE = (IPTR) data->mad_InnerBottom;
815 return TRUE;
817 case MUIA_InnerLeft:
818 STORE = (IPTR) data->mad_InnerLeft;
819 return TRUE;
821 case MUIA_InnerRight:
822 STORE = (IPTR) data->mad_InnerRight;
823 return TRUE;
825 case MUIA_InnerTop:
826 STORE = (IPTR) data->mad_InnerTop;
827 return TRUE;
829 case MUIA_LeftEdge:
830 STORE = (IPTR) _left(obj);
831 return TRUE;
833 case MUIA_Pressed:
834 STORE = ! !(data->mad_Flags & MADF_PRESSED);
835 return TRUE;
837 case MUIA_RightEdge:
838 STORE = (IPTR) _right(obj);
839 return TRUE;
841 case MUIA_Selected:
842 STORE = ! !(data->mad_Flags & MADF_SELECTED);
843 return TRUE;
845 case MUIA_ShortHelp:
846 STORE = (IPTR) data->mad_ShortHelp;
847 return TRUE;
849 case MUIA_ShowMe:
850 STORE = ! !(data->mad_Flags & MADF_SHOWME);
851 return TRUE;
853 case MUIA_Timer:
854 return TRUE;
856 case MUIA_TopEdge:
857 STORE = (IPTR) _top(obj);
858 return TRUE;
860 case MUIA_VertWeight:
861 STORE = (IPTR) data->mad_VertWeight;
862 return TRUE;
864 case MUIA_Width:
865 STORE = (IPTR) _width(obj);
866 return TRUE;
868 case MUIA_Window:
869 if (muiAreaData(obj)->mad_RenderInfo)
870 STORE = (IPTR) _window(obj);
871 else
872 STORE = 0L;
873 return TRUE;
875 case MUIA_WindowObject:
876 if (muiAreaData(obj)->mad_RenderInfo)
877 STORE = (IPTR) _win(obj);
878 else
879 STORE = 0L;
880 return TRUE;
882 case MUIA_ContextMenu:
883 STORE = (IPTR) data->mad_ContextMenu;
884 return TRUE;
886 case MUIA_Frame:
887 STORE = (IPTR) data->mad_Frame;
888 return TRUE;
891 return (DoSuperMethodA(cl, obj, (Msg) msg));
892 #undef STORE
896 /**************************************************************************
897 MUIM_AskMinMax
898 **************************************************************************/
899 static IPTR Area__MUIM_AskMinMax(struct IClass *cl, Object *obj,
900 struct MUIP_AskMinMax *msg)
902 struct MUI_AreaData *data = INST_DATA(cl, obj);
903 const struct ZuneFrameGfx *zframe;
904 const struct MUI_FrameSpec_intern *frame;
905 struct MUI_FrameSpec_intern tempframe;
907 frame = get_intframe(obj, data, &tempframe);
908 zframe = zune_zframe_get(obj, frame);
910 area_update_msizes(obj, data, frame, zframe);
912 msg->MinMaxInfo->MinWidth = _subwidth(obj);
913 msg->MinMaxInfo->MinHeight = _subheight(obj);
915 msg->MinMaxInfo->MaxWidth = msg->MinMaxInfo->MinWidth;
916 msg->MinMaxInfo->MaxHeight = msg->MinMaxInfo->MinHeight;
917 msg->MinMaxInfo->DefWidth = msg->MinMaxInfo->MinWidth;
918 msg->MinMaxInfo->DefHeight = msg->MinMaxInfo->MinHeight;
920 /* D(bug("Area_AskMinMax 0x%lx (%s): Min=%ldx%ld Max=%ldx%ld Def=%ldx%ld\n",
921 obj, data->mad_FrameTitle, */
922 /* msg->MinMaxInfo->MinWidth, msg->MinMaxInfo->MinHeight, */
923 /* msg->MinMaxInfo->MaxWidth, msg->MinMaxInfo->MaxHeight, */
924 /* msg->MinMaxInfo->DefWidth, msg->MinMaxInfo->DefHeight)); */
926 return TRUE;
930 * Called after MUIM_AskMinMax, to handle fixed and max sizes.
932 void __area_finish_minmax(Object *obj, struct MUI_MinMax *MinMaxInfo)
934 struct MUI_AreaData *data = muiAreaData(obj);
936 if ((_flags(obj) & MADF_FIXHEIGHT) && data->mad_HardHeight)
938 int h = data->mad_HardHeight + data->mad_subheight;
940 MinMaxInfo->MinHeight =
941 MinMaxInfo->DefHeight =
942 MinMaxInfo->MaxHeight =
943 CLAMP(h, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
945 else if (data->mad_HardHeightTxt)
947 ZText *text;
949 if ((text =
950 zune_text_new(NULL, data->mad_HardHeightTxt, ZTEXT_ARG_NONE,
951 0)))
953 zune_text_get_bounds(text, obj);
955 MinMaxInfo->MinHeight =
956 MinMaxInfo->DefHeight =
957 MinMaxInfo->MaxHeight =
958 CLAMP(text->height + data->mad_subheight,
959 MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
961 zune_text_destroy(text);
965 else if (_flags(obj) & MADF_MAXHEIGHT)
967 MinMaxInfo->MaxHeight =
968 CLAMP(data->mad_HardHeight + data->mad_subheight,
969 MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
972 if ((_flags(obj) & MADF_FIXWIDTH) && data->mad_HardWidth)
974 int w = data->mad_HardWidth + data->mad_subwidth;
976 MinMaxInfo->MinWidth =
977 MinMaxInfo->DefWidth =
978 MinMaxInfo->MaxWidth =
979 CLAMP(w, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
981 else if (data->mad_HardWidthTxt)
983 ZText *text;
985 if ((text =
986 zune_text_new(NULL, data->mad_HardWidthTxt, ZTEXT_ARG_NONE,
987 0)))
989 zune_text_get_bounds(text, obj);
991 MinMaxInfo->MinWidth =
992 MinMaxInfo->DefWidth =
993 MinMaxInfo->MaxWidth =
994 CLAMP(text->width + data->mad_subwidth,
995 MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
997 zune_text_destroy(text);
1001 else if (_flags(obj) & MADF_MAXWIDTH)
1003 MinMaxInfo->MaxWidth =
1004 CLAMP(data->mad_HardWidth + data->mad_subwidth,
1005 MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
1008 /* Set minmax */
1009 _minwidth(obj) = MinMaxInfo->MinWidth;
1010 _minheight(obj) = MinMaxInfo->MinHeight;
1011 _maxwidth(obj) = MinMaxInfo->MaxWidth;
1012 _maxheight(obj) = MinMaxInfo->MaxHeight;
1013 _defwidth(obj) = MinMaxInfo->DefWidth;
1014 _defheight(obj) = MinMaxInfo->DefHeight;
1017 /* <-- _top(obj) (frame title position depends of _top(obj))
1018 * ==== Title === <-- frame_top (depends of title, if centered/above)
1019 * | | <-- bgtop (depends of frame, bg always begins under frame)
1020 * | |
1021 * | |
1022 * ============== <-- "bgbottom" and "frame_bottom" (frame overwrites bg (1))
1024 * (1) : needed for phantom frame objects, where no frame overwrites bg, thus bg
1025 * must go as far as theorical bottom frame border.
1029 * draw object background if MADF_FILLAREA.
1031 static void Area_Draw_handle_background(Object *obj,
1032 struct MUI_AreaData *data, ULONG flags,
1033 const struct ZuneFrameGfx *zframe)
1035 struct MUI_ImageSpec_intern *background;
1036 struct Rectangle r, r2, rects[4];
1037 int i, bgtop, bgleft, bgw, bgh, numrects;
1039 if (!(data->mad_Flags & MADF_SELECTED)
1040 || !(data->mad_Flags & MADF_SHOWSELSTATE))
1041 background = data->mad_Background;
1042 else
1043 background = data->mad_SelBack;
1045 if (zframe->customframe)
1047 bgtop = _top(obj) + data->mad_TitleHeightAbove;
1049 else
1051 bgtop = _top(obj) + data->mad_TitleHeightAbove + zframe->itop;
1054 bgleft = _left(obj);
1055 bgw = _width(obj);
1056 bgh = _height(obj) - bgtop + _top(obj);
1058 r.MinX = bgleft;
1059 r.MinY = bgtop;
1060 r.MaxX = bgleft + bgw - 1;
1061 r.MaxY = bgtop + bgh - 1;
1063 if (data->mad_Flags & MADF_FILLAREA)
1065 rects[0] = r;
1066 numrects = 1;
1068 else
1070 /* MADF_FILLAREA not set. Only draw frame outside of
1071 innerbox (_mleft, _mtop, _mright, _mbottom):
1073 .............
1074 .***********.
1075 .*#########*.
1076 .*#########*.
1077 .***********.
1078 .............
1080 # = innerbox
1081 * = frame outside of innerbox
1082 . = object frame
1085 r2.MinX = _mleft(obj);
1086 r2.MinY = _mtop(obj);
1087 r2.MaxX = _mright(obj);
1088 r2.MaxY = _mbottom(obj);
1090 numrects = SubtractRectFromRect(&r, &r2, rects);
1093 for (i = 0; i < numrects; i++)
1095 if (!background)
1097 /* This will do the rest, TODO: on MADF_DRAWALL we not really
1098 * need to draw this */
1099 /* D(bug(" Area_Draw(%p):%ld: MUIM_DrawBackground\n", obj,
1100 __LINE__)); */
1101 /* ATTENTION: This draws the clipped away regions of the area.
1102 * Comment out and check the result to see what I mean. */
1103 DoMethod(obj, MUIM_DrawBackground,
1104 rects[i].MinX, rects[i].MinY,
1105 rects[i].MaxX - rects[i].MinX + 1,
1106 rects[i].MaxY - rects[i].MinY + 1, rects[i].MinX,
1107 rects[i].MinY, data->mad_Flags);
1109 else
1111 /* D(bug(" Area_Draw(%p):%ld: zune_imspec_draw\n", obj,
1112 __LINE__)); */
1113 zune_imspec_draw(background, data->mad_RenderInfo,
1114 rects[i].MinX, rects[i].MinY,
1115 rects[i].MaxX - rects[i].MinX + 1,
1116 rects[i].MaxY - rects[i].MinY + 1, rects[i].MinX,
1117 rects[i].MinY, 0);
1121 if (muiGlobalInfo(obj)->mgi_Prefs->window_redraw ==
1122 WINDOW_REDRAW_WITHOUT_CLEAR)
1124 if (bgtop > _top(obj) && !(flags & MADF_DRAWALL))
1126 /* Fill in the gap produced by the title with the background
1127 * of the parent object but only if
1128 * the upper object hasn't drawn it already
1129 * (which is the case if MADF_DRAWALL is setted) */
1130 DoMethod(obj, MUIM_DrawParentBackground, bgleft, _top(obj), bgw,
1131 bgtop - _top(obj), bgleft, _top(obj), data->mad_Flags);
1138 * draw object frame + title if not MADF_FRAMEPHANTOM.
1140 static void Area_Draw_handle_frame(Object *obj, struct MUI_AreaData *data,
1141 const struct ZuneFrameGfx *zframe)
1143 APTR textdrawclip = (APTR) - 1;
1144 struct Region *region;
1145 int tx;
1146 int tw, frame_height, frame_top;
1147 int addtw;
1148 struct TextExtent te;
1149 int nchars;
1150 int maxtxtwidth;
1152 /* no frametitle, just draw frame and return */
1153 if (!data->mad_FrameTitle)
1155 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1156 _top(obj), _width(obj), _height(obj), _left(obj), _top(obj),
1157 _width(obj), _height(obj));
1158 return;
1161 /* set clipping so that frame is not drawn behind title */
1163 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_color)
1165 case GROUP_TITLE_COLOR_OUTLINE:
1166 addtw = 2;
1167 break;
1168 case GROUP_TITLE_COLOR_3D:
1169 addtw = 1;
1170 break;
1171 default:
1172 addtw = 0;
1175 maxtxtwidth =
1176 _width(obj) - zframe->ileft - zframe->iright - 2 * 5 - addtw;
1178 nchars = TextFit(_rp(obj), data->mad_FrameTitle,
1179 strlen(data->mad_FrameTitle),
1180 &te, NULL, 1, maxtxtwidth, _font(obj)->tf_YSize);
1182 tw = te.te_Width + addtw;
1183 tx = _left(obj) + (_width(obj) - tw) / 2;
1185 frame_top = _top(obj) + data->mad_TitleHeightAbove;
1186 frame_height = _height(obj) - frame_top + _top(obj);
1188 if ((region = NewRegion()))
1190 struct Rectangle rect;
1191 int hspace = _font(obj)->tf_YSize / 8;
1193 rect.MinX = tx - hspace;
1194 rect.MinY = _top(obj);
1195 rect.MaxX = tx + tw - 1 + hspace;
1196 rect.MaxY = _top(obj) + _font(obj)->tf_YSize - 1;
1197 // frame is not thick enough anyway
1198 OrRectRegion(region, &rect);
1200 rect.MinX = _left(obj);
1201 rect.MinY = _top(obj);
1202 rect.MaxX = _right(obj);
1203 rect.MaxY = _bottom(obj);
1204 XorRectRegion(region, &rect);
1206 textdrawclip = MUI_AddClipRegion(muiRenderInfo(obj), region);
1209 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1210 frame_top, _width(obj), frame_height, _left(obj), frame_top,
1211 _width(obj), frame_height);
1213 if (region && textdrawclip != (APTR) - 1)
1215 MUI_RemoveClipRegion(muiRenderInfo(obj), textdrawclip);
1216 /* DisposeRegion(region);*/ /* sba: DisposeRegion happens in MUI_RemoveClipRegion, this seems wrong to me */
1219 /* Title text drawing */
1220 SetDrMd(_rp(obj), JAM1);
1221 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1222 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1223 GROUP_TITLE_COLOR_3D)
1225 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline + 1);
1226 Text(_rp(obj), data->mad_FrameTitle, nchars);
1227 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1228 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1229 Text(_rp(obj), data->mad_FrameTitle, nchars);
1231 else if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1232 GROUP_TITLE_COLOR_OUTLINE)
1234 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1236 tx += addtw / 2;
1237 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline);
1238 Text(_rp(obj), data->mad_FrameTitle, nchars);
1239 Move(_rp(obj), tx - 1, _top(obj) + _font(obj)->tf_Baseline);
1240 Text(_rp(obj), data->mad_FrameTitle, nchars);
1241 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline + 1);
1242 Text(_rp(obj), data->mad_FrameTitle, nchars);
1243 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline - 1);
1244 Text(_rp(obj), data->mad_FrameTitle, nchars);
1246 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1247 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1248 Text(_rp(obj), data->mad_FrameTitle, nchars);
1250 else
1252 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1253 GROUP_TITLE_COLOR_HILITE)
1255 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1257 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1258 Text(_rp(obj), data->mad_FrameTitle, nchars);
1262 /**************************************************************************
1263 MUIM_Draw
1264 **************************************************************************/
1265 static IPTR Area__MUIM_Draw(struct IClass *cl, Object *obj,
1266 struct MUIP_Draw *msg)
1268 struct MUI_AreaData *data = INST_DATA(cl, obj);
1269 const struct ZuneFrameGfx *zframe;
1270 struct TextFont *obj_font = NULL;
1271 ULONG flags = data->mad_Flags & MADF_DRAWFLAGS;
1273 //APTR areaclip;
1275 /* D(bug("Area_Draw(0x%lx) %ldx%ldx%ldx%ld\n", obj, _left(obj),
1276 _top(obj),_right(obj),_bottom(obj))); */
1277 /* D(bug(" Area_Draw(%p) msg=0x%08lx flags=0x%08lx\n", obj, msg->flags,
1278 _flags(obj))); */
1280 if (flags & MADF_DRAWALL)
1281 flags |= MADF_DRAWOBJECT;
1283 msg->flags = flags;
1284 data->mad_Flags &= ~MADF_DRAWFLAGS;
1286 if (!(flags & MADF_DRAWOBJECT))
1288 /* dont draw bg/frame, let subclass redraw content only
1290 return 0;
1294 /* Background cant be drawn without knowing anything about frame, thus some
1295 * calculations are made before background and frame drawing.
1298 /* on selected state, will get the opposite frame */
1299 const struct MUI_FrameSpec_intern *frame;
1300 struct MUI_FrameSpec_intern tempframe;
1301 int state;
1303 frame = get_intframe(obj, data, &tempframe);
1304 state = frame->state;
1305 if ((data->mad_Flags & MADF_SELECTED)
1306 && (data->mad_Flags & MADF_SHOWSELSTATE))
1307 state ^= 1;
1309 zframe = zune_zframe_get_with_state(obj, frame, state);
1311 /* update innersizes as there are frames which have different inner
1312 * spacings in selected state */
1313 area_update_msizes(obj, data, frame, zframe);
1316 /* Background drawing */
1317 Area_Draw_handle_background(obj, data, msg->flags, zframe);
1319 obj_font = _font(obj);
1320 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1321 SetFont(_rp(obj), _font(obj));
1323 /* Frame and frametitle drawing */
1324 if (!(data->mad_Flags & MADF_FRAMEPHANTOM))
1326 Area_Draw_handle_frame(obj, data, zframe);
1329 _font(obj) = obj_font;
1330 SetFont(_rp(obj), _font(obj));
1332 /* MUI_RemoveClipping(muiRenderInfo(obj), areaclip);*/
1334 return TRUE;
1337 /**************************************************************************
1338 MUIM_DrawParentBackground
1339 **************************************************************************/
1340 static IPTR Area__MUIM_DrawParentBackground(struct IClass *cl, Object *obj,
1341 struct MUIP_DrawParentBackground *msg)
1343 struct MUI_AreaData *data = INST_DATA(cl, obj);
1344 Object *parent = NULL;
1346 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1347 return FALSE;
1349 get(obj, MUIA_Parent, &parent);
1350 if (parent)
1352 DoMethod(parent, MUIM_DrawBackground, msg->left, msg->top,
1353 msg->width, msg->height, msg->xoffset, msg->yoffset,
1354 msg->flags);
1356 else
1358 D(bug
1359 ("Area_DrawParentBackground(%p) : MUIM_Window_DrawBackground\n",
1360 obj));
1361 DoMethod(_win(obj), MUIM_Window_DrawBackground, msg->left, msg->top,
1362 msg->width, msg->height, msg->xoffset, msg->yoffset,
1363 msg->flags);
1365 return TRUE;
1368 /**************************************************************************
1369 MUIM_DrawBackground
1370 **************************************************************************/
1371 static IPTR Area__MUIM_DrawBackground(struct IClass *cl, Object *obj,
1372 struct MUIP_DrawBackground *msg)
1374 struct MUI_AreaData *data = INST_DATA(cl, obj);
1375 struct MUI_ImageSpec_intern *bg;
1376 LONG state;
1378 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1379 return FALSE;
1381 if ((msg->flags & MADF_SELECTED) && (msg->flags & MADF_SHOWSELSTATE)
1382 && data->mad_SelBack)
1384 /* D(bug("Area_DrawBackground(%p): selected bg\n", obj)); */
1385 bg = data->mad_SelBack;
1386 state = IDS_SELECTED;
1388 else
1390 /* D(bug("Area_DrawBackground(%p): normal bg\n", obj)); */
1391 bg = data->mad_Background;
1392 state = IDS_NORMAL;
1395 const struct ZuneFrameGfx *zframe;
1396 const struct MUI_FrameSpec_intern *frame;
1397 struct MUI_FrameSpec_intern tempframe;
1399 if (!bg)
1401 D(bug("Area_DrawBackground(%p) : MUIM_DrawParentBackground\n",
1402 obj));
1404 return DoMethod(obj, MUIM_DrawParentBackground, msg->left, msg->top,
1405 msg->width, msg->height, msg->xoffset, msg->yoffset,
1406 msg->flags);
1409 frame = get_intframe(obj, data, &tempframe);
1411 int xstate = frame->state;
1412 if ((data->mad_Flags & MADF_SELECTED)
1413 && (data->mad_Flags & MADF_SHOWSELSTATE))
1414 xstate ^= 1;
1416 zframe = zune_zframe_get_with_state(obj, frame, xstate);
1418 if (zframe->customframe == NULL)
1420 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1421 zune_imspec_draw(bg, data->mad_RenderInfo,
1422 msg->left, msg->top, msg->width, msg->height,
1423 msg->xoffset, msg->yoffset, state);
1425 // if (!data->mad_FrameTitle)
1426 // {
1429 else
1431 if (zframe->noalpha == FALSE)
1433 zune_imspec_draw(bg, data->mad_RenderInfo,
1434 msg->left, msg->top, msg->width, msg->height,
1435 msg->xoffset, msg->yoffset, state);
1440 if (zframe->customframe)
1442 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1443 _top(obj), _width(obj), _height(obj), msg->left, msg->top,
1444 msg->width, msg->height);
1447 return TRUE;
1450 static IPTR Area__MUIM_DrawBackgroundBuffered(struct IClass *cl,
1451 Object *obj, struct MUIP_DrawBackgroundBuffered *msg)
1453 struct MUI_AreaData *data = INST_DATA(cl, obj);
1454 struct MUI_ImageSpec_intern *bg;
1455 LONG state = 0;
1457 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1458 return FALSE;
1460 bg = data->mad_Background;
1462 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1463 zune_imspec_drawbuffered(bg, msg->rp, data->mad_RenderInfo,
1464 msg->left, msg->top, msg->width, msg->height,
1465 msg->xoffset + msg->left, msg->yoffset + msg->top, state, msg->left,
1466 msg->top, 1, _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));
1468 return TRUE;
1471 /* Perverting the EventHandlerNode structure to specify a shortcut.
1473 static void setup_control_char(struct MUI_AreaData *data, Object *obj,
1474 struct IClass *cl)
1476 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1478 data->mad_ccn.ehn_Events = data->mad_ControlChar;
1479 switch (data->mad_InputMode)
1481 case MUIV_InputMode_RelVerify:
1482 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1483 break;
1484 case MUIV_InputMode_Toggle:
1485 data->mad_ccn.ehn_Flags = MUIKEY_TOGGLE;
1486 break;
1487 case MUIV_InputMode_Immediate:
1488 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1489 break;
1491 data->mad_ccn.ehn_Priority = 0;
1492 data->mad_ccn.ehn_Object = obj;
1493 data->mad_ccn.ehn_Class = cl;
1494 DoMethod(_win(obj), MUIM_Window_AddControlCharHandler,
1495 (IPTR) & data->mad_ccn);
1500 static void cleanup_control_char(struct MUI_AreaData *data, Object *obj)
1502 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1504 DoMethod(_win(obj),
1505 MUIM_Window_RemControlCharHandler, (IPTR) & data->mad_ccn);
1509 static const struct MUI_FrameSpec_intern *get_intframe(Object *obj,
1510 struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore)
1512 if (data->mad_Frame > 100)
1514 /* Frame is spec in string format. Store it in tempstore and return
1515 a pointer to it. The caller should have such a temp variable on
1516 the stack. Don't want to add it to MUI_AreaData as that will
1517 increase mem usage of every object. */
1519 if (zune_frame_spec_to_intern((CONST_STRPTR) data->mad_Frame,
1520 tempstore))
1522 return tempstore;
1524 else
1526 return &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_None];
1529 else
1531 /* Frame is MUIV_Frame_<something> */
1532 return &muiGlobalInfo(obj)->mgi_Prefs->frames[data->mad_Frame];
1536 static void set_inner_sizes(Object *obj, struct MUI_AreaData *data)
1538 const struct MUI_FrameSpec_intern *frame;
1539 struct MUI_FrameSpec_intern tempframe;
1541 frame = get_intframe(obj, data, &tempframe);
1542 // Use frame inner spacing when not hardcoded
1543 if (!(data->mad_Flags & MADF_INNERLEFT))
1544 data->mad_InnerLeft = frame->innerLeft;
1545 if (!(data->mad_Flags & MADF_INNERTOP))
1546 data->mad_InnerTop = frame->innerTop;
1547 if (!(data->mad_Flags & MADF_INNERRIGHT))
1548 data->mad_InnerRight = frame->innerRight;
1549 if (!(data->mad_Flags & MADF_INNERBOTTOM))
1550 data->mad_InnerBottom = frame->innerBottom;
1554 static void set_title_sizes(Object *obj, struct MUI_AreaData *data)
1556 if (data->mad_FrameTitle)
1558 const struct ZuneFrameGfx *zframe;
1559 const struct MUI_FrameSpec_intern *frame;
1560 struct MUI_FrameSpec_intern tempframe;
1562 frame = get_intframe(obj, data, &tempframe);
1563 zframe = zune_zframe_get(obj, frame);
1565 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1567 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_position)
1569 case GROUP_TITLE_POSITION_ABOVE:
1570 data->mad_TitleHeightAbove = _font(obj)->tf_Baseline;
1571 break;
1572 case GROUP_TITLE_POSITION_CENTERED:
1573 data->mad_TitleHeightAbove = _font(obj)->tf_YSize / 2;
1574 break;
1577 data->mad_TitleHeightAdd =
1578 _font(obj)->tf_YSize - data->mad_InnerTop - zframe->itop;
1579 data->mad_TitleHeightBelow =
1580 data->mad_TitleHeightAdd - data->mad_TitleHeightAbove;
1585 /**************************************************************************
1586 First method to be called after an OM_NEW, it is the place
1587 for all initializations depending on the environment, but not
1588 on the gadget size/position. Matched by MUIM_Cleanup.
1589 **************************************************************************/
1590 static IPTR Area__MUIM_Setup(struct IClass *cl, Object *obj,
1591 struct MUIP_Setup *msg)
1593 struct MUI_AreaData *data = INST_DATA(cl, obj);
1594 const struct ZuneFrameGfx *zframe;
1595 const struct MUI_FrameSpec_intern *frame;
1596 struct MUI_FrameSpec_intern tempframe;
1598 muiRenderInfo(obj) = msg->RenderInfo;
1600 if (data->mad_Frame)
1602 /* no frame allowed for root object (see Area.doc) */
1603 Object *rootobj = NULL;
1604 get(_win(obj), MUIA_Window_RootObject, &rootobj);
1605 if (rootobj == obj)
1607 data->mad_Frame = MUIV_Frame_None;
1608 data->mad_FrameTitle = NULL;
1612 set_inner_sizes(obj, data);
1613 set_title_sizes(obj, data);
1615 frame = get_intframe(obj, data, &tempframe);
1616 zframe = zune_zframe_get(obj, frame);
1618 area_update_msizes(obj, data, frame, zframe);
1620 if (data->mad_Flags & MADF_OWNBG)
1622 data->mad_Background =
1623 zune_imspec_setup((IPTR) data->mad_BackgroundSpec,
1624 muiRenderInfo(obj));
1627 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1628 (data->mad_InputMode != MUIV_InputMode_None))
1630 data->mad_SelBack =
1631 zune_imspec_setup(MUII_SelectedBack, muiRenderInfo(obj));
1634 if (data->mad_InputMode != MUIV_InputMode_None || data->mad_ContextMenu)
1636 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1637 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1638 (IPTR) & data->mad_ehn);
1641 /* Those are filled by RequestIDCMP() */
1642 if (data->mad_hiehn.ehn_Events)
1643 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1644 (IPTR) & data->mad_hiehn);
1646 setup_control_char(data, obj, cl);
1647 // setup_cycle_chain (data, obj);
1649 if (data->mad_FontPreset == MUIV_Font_Inherit)
1651 if (_parent(obj) != NULL && _parent(obj) != _win(obj))
1652 data->mad_Font = _font(_parent(obj));
1653 else
1655 D(bug("Area_Setup %p: getting normal font\n", obj));
1656 data->mad_Font = zune_font_get(obj, MUIV_Font_Normal);
1657 D(bug("Area_Setup %p: got normal font %p\n", obj,
1658 data->mad_Font));
1661 else
1663 data->mad_Font = zune_font_get(obj, data->mad_FontPreset);
1666 _flags(obj) |= MADF_SETUP;
1668 data->mad_Timer.ihn_Flags = MUIIHNF_TIMER;
1669 data->mad_Timer.ihn_Method = MUIM_Timer;
1670 data->mad_Timer.ihn_Object = obj;
1672 return TRUE;
1676 /**************************************************************************
1677 Called to match a MUIM_Setup, when environment is no more available.
1678 **************************************************************************/
1679 static IPTR Area__MUIM_Cleanup(struct IClass *cl, Object *obj,
1680 struct MUIP_Cleanup *msg)
1682 struct MUI_AreaData *data = INST_DATA(cl, obj);
1684 _flags(obj) &= ~MADF_SETUP;
1686 // cleanup_cycle_chain (data, obj);
1687 cleanup_control_char(data, obj);
1689 if (data->mad_Timer.ihn_Millis)
1691 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
1692 (IPTR) & data->mad_Timer);
1693 data->mad_Timer.ihn_Millis = 0;
1696 /* Remove the handler if it is added */
1697 if (data->mad_hiehn.ehn_Events)
1698 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1699 (IPTR) & data->mad_hiehn);
1701 /* Remove the event handler if it has been added */
1702 if (data->mad_ehn.ehn_Events)
1703 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1704 (IPTR) & data->mad_ehn);
1706 D(bug("Area cleanup %p active=%p\n", obj,
1707 (Object *) XGET(_win(obj), MUIA_Window_ActiveObject)));
1708 if (obj == (Object *) XGET(_win(obj), MUIA_Window_ActiveObject))
1710 D(bug("we are active, unset us\n"));
1711 set(_win(obj), MUIA_Window_ActiveObject,
1712 MUIV_Window_ActiveObject_None);
1715 /* It's save to call the following function with NULL */
1716 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1717 (data->mad_InputMode != MUIV_InputMode_None))
1719 zune_imspec_cleanup(data->mad_SelBack);
1720 data->mad_SelBack = NULL;
1722 if (data->mad_Flags & MADF_OWNBG)
1724 zune_imspec_cleanup(data->mad_Background);
1725 data->mad_Background = NULL;
1728 muiRenderInfo(obj) = NULL;
1730 return TRUE;
1734 /**************************************************************************
1735 Called after the window is open and the area layouted, but before
1736 any drawing. Matched by one MUIM_Hide.
1737 Good place to init things depending on gadget size/position.
1738 **************************************************************************/
1739 static IPTR Area__MUIM_Show(struct IClass *cl, Object *obj,
1740 struct MUIP_Show *msg)
1742 struct MUI_AreaData *data = INST_DATA(cl, obj);
1744 zune_imspec_show(data->mad_Background, obj);
1746 if (data->mad_Flags & MADF_SHOWSELSTATE
1747 && data->mad_InputMode != MUIV_InputMode_None)
1749 zune_imspec_show(data->mad_SelBack, obj);
1752 return TRUE;
1755 /**************************************************************************
1756 Called when the window is about to be closed, to match MUIM_Show.
1757 **************************************************************************/
1758 static IPTR Area__MUIM_Hide(struct IClass *cl, Object *obj,
1759 struct MUIP_Hide *msg)
1761 struct MUI_AreaData *data = INST_DATA(cl, obj);
1763 zune_imspec_hide(data->mad_Background);
1764 if (data->mad_Flags & MADF_SHOWSELSTATE
1765 && data->mad_InputMode != MUIV_InputMode_None)
1767 zune_imspec_hide(data->mad_SelBack);
1770 if (data->mad_ContextZMenu)
1772 zune_close_menu(data->mad_ContextZMenu);
1773 data->mad_ContextZMenu = NULL;
1776 return TRUE;
1779 /**************************************************************************
1780 Called when gadget activated
1781 **************************************************************************/
1782 static IPTR Area__MUIM_GoActive(struct IClass *cl, Object *obj, Msg msg)
1784 //bug("Area_GoActive %p\n", obj);
1785 if (_flags(obj) & MADF_CANDRAW)
1786 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1787 return TRUE;
1790 /**************************************************************************
1791 Called when gadget deactivated
1792 **************************************************************************/
1793 static IPTR Area__MUIM_GoInactive(struct IClass *cl, Object *obj, Msg msg)
1795 //bug("Area_GoInactive %p\n", obj);
1796 if (_flags(obj) & MADF_CANDRAW)
1797 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1798 return TRUE;
1801 /**************************************************************************
1802 This one or derived methods wont be called if short help is
1803 not set in area instdata. So set this to a dummy val if overriding
1804 **************************************************************************/
1805 static IPTR Area__MUIM_CreateShortHelp(struct IClass *cl, Object *obj,
1806 struct MUIP_CreateShortHelp *msg)
1808 struct MUI_AreaData *data = INST_DATA(cl, obj);
1810 return (IPTR) data->mad_ShortHelp;
1813 /**************************************************************************
1815 **************************************************************************/
1816 static IPTR Area__MUIM_DeleteShortHelp(struct IClass *cl, Object *obj,
1817 struct MUIP_DeleteShortHelp *msg)
1819 return TRUE;
1822 /**************************************************************************
1824 **************************************************************************/
1825 static IPTR Area__MUIM_CreateBubble(struct IClass *cl, Object *obj,
1826 struct MUIP_CreateBubble *msg)
1828 return (IPTR) zune_bubble_create(obj, msg->x, msg->y, msg->txt,
1829 msg->flags);
1832 /**************************************************************************
1834 **************************************************************************/
1835 static IPTR Area__MUIM_DeleteBubble(struct IClass *cl, Object *obj,
1836 struct MUIP_DeleteBubble *msg)
1838 zune_bubble_delete(obj, msg->bubble);
1840 return TRUE;
1843 /* either lmb or press key */
1844 static void handle_press(struct IClass *cl, Object *obj)
1846 struct MUI_AreaData *data = INST_DATA(cl, obj);
1848 switch (data->mad_InputMode)
1850 case MUIV_InputMode_RelVerify:
1851 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
1852 if (!data->mad_Timer.ihn_Millis)
1854 data->mad_Timer.ihn_Millis = 300;
1855 DoMethod(_app(obj), MUIM_Application_AddInputHandler,
1856 (IPTR) & data->mad_Timer);
1858 SetAttrs(obj, MUIA_Selected, TRUE, MUIA_Pressed, TRUE, TAG_DONE);
1859 break;
1861 case MUIV_InputMode_Immediate:
1863 IPTR selected = FALSE;
1865 get(obj, MUIA_Selected, &selected);
1866 if (selected)
1868 /* D(bug("handle_press(%p) : nnset MUIA_Selected FALSE\n", obj)); */
1869 nnset(obj, MUIA_Selected, FALSE);
1871 /* D(bug("handle_press(%p) : set MUIA_Selected TRUE\n", obj)); */
1872 set(obj, MUIA_Selected, TRUE);
1873 /* D(bug("handle_press(%p) : done\n", obj)); */
1874 break;
1876 case MUIV_InputMode_Toggle:
1877 // although undocumented, MUI sets MUIA_Pressed too
1878 SetAttrs(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED),
1879 MUIA_Pressed, !(data->mad_Flags & MADF_PRESSED), TAG_DONE);
1880 break;
1884 /* either lmb or release key */
1885 static void handle_release(struct IClass *cl, Object *obj, int cancel)
1887 struct MUI_AreaData *data = INST_DATA(cl, obj);
1889 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1891 if (data->mad_Flags & MADF_SELECTED)
1893 if (cancel)
1894 nnset(obj, MUIA_Pressed, FALSE);
1895 else
1896 set(obj, MUIA_Pressed, FALSE);
1898 set(obj, MUIA_Selected, FALSE);
1902 if (data->mad_Timer.ihn_Millis)
1904 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
1905 (IPTR) & data->mad_Timer);
1906 data->mad_Timer.ihn_Millis = 0;
1911 static IPTR event_button(Class *cl, Object *obj,
1912 struct IntuiMessage *imsg)
1914 struct MUI_AreaData *data = INST_DATA(cl, obj);
1915 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1916 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1918 switch (imsg->Code)
1920 case SELECTDOWN:
1921 if (data->mad_InputMode == MUIV_InputMode_None)
1922 break;
1924 if (in)
1926 // set(_win(obj), MUIA_Window_ActiveObject, obj);
1927 data->mad_ClickX = imsg->MouseX;
1928 data->mad_ClickY = imsg->MouseY;
1930 if ((data->mad_InputMode != MUIV_InputMode_Toggle)
1931 && (data->mad_Flags & MADF_SELECTED))
1932 break;
1933 nnset(obj, MUIA_Timer, 0);
1934 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1936 if (data->mad_ehn.ehn_Events)
1937 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1938 (IPTR) & data->mad_ehn);
1939 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE | IDCMP_RAWKEY;
1940 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1941 (IPTR) & data->mad_ehn);
1943 handle_press(cl, obj);
1944 return MUI_EventHandlerRC_Eat;
1947 case SELECTUP:
1948 if (data->mad_InputMode == MUIV_InputMode_None)
1949 break;
1951 if (data->mad_ehn.ehn_Events != IDCMP_MOUSEBUTTONS)
1953 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1954 (IPTR) & data->mad_ehn);
1955 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1956 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1957 (IPTR) & data->mad_ehn);
1958 if (!in)
1959 nnset(obj, MUIA_Pressed, FALSE);
1960 handle_release(cl, obj, FALSE /*cancel */ );
1961 return MUI_EventHandlerRC_Eat;
1963 break;
1965 case MENUDOWN:
1966 if (in && data->mad_ContextMenu)
1968 Object *menuobj =
1969 (Object *) DoMethod(obj, MUIM_ContextMenuBuild,
1970 imsg->MouseX, imsg->MouseY);
1971 if (menuobj)
1973 struct NewMenu *newmenu = NULL;
1975 /* stegerg: HACKME, CHECKME! The menu/menu item objs should
1976 automatically be connected (parentobject setup) without
1977 need for this, but they aren't. Because of how family
1978 class is and is used by other classes, I think!? */
1979 DoMethod(menuobj, MUIM_ConnectParent, obj);
1981 get(menuobj, MUIA_Menuitem_NewMenu, &newmenu);
1982 if (newmenu)
1984 if (data->mad_ContextZMenu)
1985 zune_close_menu(data->mad_ContextZMenu);
1986 data->mad_ContextZMenu =
1987 zune_open_menu(_window(obj), newmenu);
1990 if (data->mad_ehn.ehn_Events)
1991 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1992 (IPTR) & data->mad_ehn);
1993 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE;
1994 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1995 (IPTR) & data->mad_ehn);
1997 return MUI_EventHandlerRC_Eat;
1999 break;
2001 case MENUUP:
2002 if (data->mad_ContextZMenu)
2004 struct MenuItem *item = zune_leave_menu(data->mad_ContextZMenu);
2006 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2007 (IPTR) & data->mad_ehn);
2008 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2009 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2010 (IPTR) & data->mad_ehn);
2012 if (item)
2014 Object *itemobj = (Object *) GTMENUITEM_USERDATA(item);
2016 /* CHECKME: MUIA_MenuItem_Trigger should probably be set inside
2017 MUIM_ContextMenuChoice!? But there I only know about
2018 itemobj, not MenuItem itself! */
2019 if (item->Flags & CHECKIT)
2021 set(itemobj, MUIA_Menuitem_Checked,
2022 ! !(item->Flags & CHECKED));
2026 set(itemobj, MUIA_Menuitem_Trigger, item);
2028 DoMethod(obj, MUIM_ContextMenuChoice, itemobj);
2032 zune_close_menu(data->mad_ContextZMenu);
2033 data->mad_ContextZMenu = NULL;
2035 return MUI_EventHandlerRC_Eat;
2038 break;
2041 return 0;
2044 static IPTR event_motion(Class *cl, Object *obj,
2045 struct IntuiMessage *imsg)
2047 struct MUI_AreaData *data = INST_DATA(cl, obj);
2049 if ((imsg->Qualifier & IEQUALIFIER_RBUTTON) && data->mad_ContextZMenu)
2051 zune_mouse_update(data->mad_ContextZMenu, 0);
2052 return MUI_EventHandlerRC_Eat;
2055 if (imsg->Qualifier & IEQUALIFIER_LEFTBUTTON)
2057 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
2058 && _between(_top(obj), imsg->MouseY, _bottom(obj));
2060 if (in)
2062 if ((data->mad_Flags & MADF_DRAGGABLE)
2063 && ((abs(data->mad_ClickX - imsg->MouseX) >= 3)
2064 || (abs(data->mad_ClickY - imsg->MouseY) >= 3)))
2065 /* should be user configurable */
2067 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
2068 set(obj, MUIA_Selected, FALSE);
2069 nnset(obj, MUIA_Pressed, FALSE);
2071 if (data->mad_ehn.ehn_Events)
2072 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2073 (IPTR) & data->mad_ehn);
2074 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2075 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2076 (IPTR) & data->mad_ehn);
2077 if (data->mad_Timer.ihn_Millis)
2079 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
2080 (IPTR) & data->mad_Timer);
2081 data->mad_Timer.ihn_Millis = 0;
2084 DoMethod(obj, MUIM_DoDrag, data->mad_ClickX - _left(obj),
2085 data->mad_ClickY - _top(obj), 0);
2086 return MUI_EventHandlerRC_Eat;
2090 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
2092 if (!in && (data->mad_Flags & MADF_SELECTED)) /* going out */
2094 set(obj, MUIA_Selected, FALSE);
2096 else if (in && !(data->mad_Flags & MADF_SELECTED)) /* going in */
2098 set(obj, MUIA_Selected, TRUE);
2102 return MUI_EventHandlerRC_Eat;
2105 /**************************************************************************
2107 **************************************************************************/
2108 static IPTR Area__MUIM_HandleEvent(struct IClass *cl, Object *obj,
2109 struct MUIP_HandleEvent *msg)
2111 struct MUI_AreaData *data = INST_DATA(cl, obj);
2113 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\n", obj, msg->imsg,
2114 // msg->muikey);
2115 if (data->mad_DisableCount)
2116 return 0;
2117 if (data->mad_InputMode == MUIV_InputMode_None
2118 && !data->mad_ContextMenu)
2119 return 0;
2121 if (msg->muikey != MUIKEY_NONE)
2123 switch (msg->muikey)
2125 case MUIKEY_PRESS:
2126 if (data->mad_Flags & MADF_SELECTED)
2127 break;
2128 if (data->mad_ehn.ehn_Events)
2129 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2130 (IPTR) & data->mad_ehn);
2131 data->mad_ehn.ehn_Events |= IDCMP_RAWKEY;
2132 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2133 (IPTR) & data->mad_ehn);
2134 handle_press(cl, obj);
2135 return MUI_EventHandlerRC_Eat;
2137 case MUIKEY_TOGGLE:
2138 if (data->mad_InputMode == MUIV_InputMode_Toggle)
2139 set(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED));
2140 return MUI_EventHandlerRC_Eat;
2142 case MUIKEY_RELEASE:
2143 if (data->mad_ehn.ehn_Events)
2144 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2145 (IPTR) & data->mad_ehn);
2146 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2147 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2148 (IPTR) & data->mad_ehn);
2149 handle_release(cl, obj, FALSE /* cancel */ );
2150 return MUI_EventHandlerRC_Eat;
2152 return 0;
2155 if (msg->imsg)
2157 switch (msg->imsg->Class)
2159 case IDCMP_MOUSEBUTTONS:
2160 return event_button(cl, obj, msg->imsg);
2161 case IDCMP_MOUSEMOVE:
2162 return event_motion(cl, obj, msg->imsg);
2163 case IDCMP_RAWKEY:
2165 unsigned char code;
2166 UWORD msg_code;
2167 /* Remove the up prefix as convert key does not convert an
2168 * upkey event */
2169 msg_code = msg->imsg->Code;
2170 msg->imsg->Code &= ~IECODE_UP_PREFIX;
2171 code = ConvertKey(msg->imsg);
2172 msg->imsg->Code = msg_code;
2174 if (code != 0 && code == data->mad_ControlChar)
2176 if (msg->imsg->Code & IECODE_UP_PREFIX)
2178 msg->muikey = MUIKEY_RELEASE;
2180 else
2182 msg->muikey = MUIKEY_PRESS;
2184 msg->imsg = NULL;
2185 return Area__MUIM_HandleEvent(cl, obj, msg);
2188 if (msg->imsg->
2189 Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
2191 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2192 (IPTR) & data->mad_ehn);
2193 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2194 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2195 (IPTR) & data->mad_ehn);
2196 handle_release(cl, obj, TRUE /*cancel */ );
2198 return MUI_EventHandlerRC_Eat;
2200 break;
2203 return 0;
2206 /**************************************************************************
2208 **************************************************************************/
2209 static IPTR Area__MUIM_HandleInput(struct IClass *cl, Object *obj,
2210 struct MUIP_HandleInput *msg)
2212 /* Actually a dummy, but real MUI does handle here the input stuff which
2213 * Zune has in Area_HandleEvent. For compatibility we should do this too */
2214 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\b", obj, msg->imsg,
2215 // msg->muikey);
2216 return 0;
2219 /**************************************************************************
2220 Trivial; custom classes may override this to get dynamic menus.
2221 **************************************************************************/
2222 static IPTR Area__MUIM_ContextMenuBuild(struct IClass *cl, Object *obj,
2223 struct MUIP_ContextMenuBuild *msg)
2225 struct MUI_AreaData *data = INST_DATA(cl, obj);
2226 return (IPTR) data->mad_ContextMenu; /* a Menustrip object */
2229 /**************************************************************************/
2230 static IPTR Area__MUIM_ContextMenuChoice(struct IClass *cl, Object *obj,
2231 struct MUIP_ContextMenuChoice *msg)
2233 set(obj, MUIA_ContextMenuTrigger, msg->item);
2234 return 0;
2238 /**************************************************************************
2239 MUIM_Export : to export an objects "contents" to a dataspace object.
2240 **************************************************************************/
2241 static IPTR Area__MUIM_Export(struct IClass *cl, Object *obj,
2242 struct MUIP_Export *msg)
2244 struct MUI_AreaData *data = INST_DATA(cl, obj);
2245 ULONG id;
2247 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2249 char selected = (data->mad_Flags & MADF_SELECTED) ? 1 : 0;
2250 DoMethod(msg->dataspace, MUIM_Dataspace_Add, (IPTR) & selected,
2251 sizeof(char), (IPTR) id);
2253 return 0;
2257 /**************************************************************************
2258 MUIM_Import : to import an objects "contents" from a dataspace object.
2259 **************************************************************************/
2260 static IPTR Area__MUIM_Import(struct IClass *cl, Object *obj,
2261 struct MUIP_Import *msg)
2263 ULONG id;
2265 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2267 char *selected =
2268 (char *)DoMethod(msg->dataspace, MUIM_Dataspace_Find,
2269 (IPTR) id);
2271 if (selected)
2272 set(obj, MUIA_Selected, *selected);
2274 return 0;
2277 /**************************************************************************
2278 MUIM_Timer
2279 **************************************************************************/
2280 static IPTR Area__MUIM_Timer(struct IClass *cl, Object *obj, Msg msg)
2282 struct MUI_AreaData *data = INST_DATA(cl, obj);
2283 if (data->mad_Timer.ihn_Millis)
2284 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
2285 (IPTR) & data->mad_Timer);
2286 data->mad_Timer.ihn_Millis = 50;
2287 DoMethod(_app(obj), MUIM_Application_AddInputHandler,
2288 (IPTR) & data->mad_Timer);
2290 if (data->mad_Flags & MADF_SELECTED)
2291 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
2292 return 0;
2295 /**************************************************************************
2296 MUIM_DoDrag
2297 **************************************************************************/
2298 static IPTR Area__MUIM_DoDrag(struct IClass *cl, Object *obj,
2299 struct MUIP_DoDrag *msg)
2301 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2302 DoMethod(_win(obj), MUIM_Window_DragObject, (IPTR) obj, msg->touchx,
2303 msg->touchy, msg->flags);
2304 return 0;
2307 /**************************************************************************
2308 MUIM_CreateDragImage
2309 **************************************************************************/
2310 static IPTR Area__MUIM_CreateDragImage(struct IClass *cl, Object *obj,
2311 struct MUIP_CreateDragImage *msg)
2313 struct MUI_DragImage *img =
2314 (struct MUI_DragImage *)AllocVec(sizeof(struct
2315 MUIP_CreateDragImage), MEMF_CLEAR);
2316 if (img)
2318 const struct ZuneFrameGfx *zframe;
2319 LONG depth =
2320 GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
2322 zframe =
2323 zune_zframe_get(obj,
2324 &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Drag]);
2326 img->width = _width(obj) + zframe->ileft + zframe->iright;
2327 img->height = _height(obj) + zframe->itop + zframe->ibottom;
2329 if ((img->bm =
2330 AllocBitMap(img->width, img->height, depth, BMF_MINPLANES,
2331 _screen(obj)->RastPort.BitMap)))
2333 /* Render the stuff now */
2334 struct RastPort *rp_save = muiRenderInfo(obj)->mri_RastPort;
2335 struct RastPort temprp;
2336 InitRastPort(&temprp);
2337 temprp.BitMap = img->bm;
2338 ClipBlit(_rp(obj), _left(obj), _top(obj), &temprp,
2339 zframe->ileft, zframe->itop, _width(obj), _height(obj),
2340 0xc0);
2342 muiRenderInfo(obj)->mri_RastPort = &temprp;
2343 zframe->draw(zframe->customframe, muiRenderInfo(obj), 0, 0,
2344 img->width, img->height, 0, 0, img->width, img->height);
2345 muiRenderInfo(obj)->mri_RastPort = rp_save;
2348 img->touchx = msg->touchx;
2349 img->touchy = msg->touchy;
2350 img->flags = 0;
2352 return (IPTR) img;
2355 /**************************************************************************
2356 MUIM_DeleteDragImage
2357 **************************************************************************/
2358 static IPTR Area__MUIM_DeleteDragImage(struct IClass *cl, Object *obj,
2359 struct MUIP_DeleteDragImage *msg)
2361 if (msg->di)
2363 if (msg->di->bm)
2364 FreeBitMap(msg->di->bm);
2365 FreeVec(msg->di);
2367 return 0;
2370 /**************************************************************************
2371 MUIM_DragQueryExtended
2372 **************************************************************************/
2373 static IPTR Area__MUIM_DragQueryExtended(struct IClass *cl, Object *obj,
2374 struct MUIP_DragQueryExtended *msg)
2376 struct MUI_AreaData *data = INST_DATA(cl, obj);
2377 if (data->mad_Flags & MADF_DROPABLE)
2379 if (_left(obj) <= msg->x && msg->x <= _right(obj)
2380 && _top(obj) <= msg->y && msg->y <= _bottom(obj))
2382 if (DoMethod(obj, MUIM_DragQuery,
2383 (IPTR) msg->obj) == MUIV_DragQuery_Accept)
2384 return (IPTR) obj;
2387 return 0;
2390 /**************************************************************************
2391 MUIM_DragBegin
2392 **************************************************************************/
2393 static IPTR Area__MUIM_DragBegin(struct IClass *cl, Object *obj,
2394 struct MUIP_DragBegin *msg)
2396 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2397 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2398 return 0;
2401 /**************************************************************************
2402 MUIM_DragFinish
2403 **************************************************************************/
2404 static IPTR Area__MUIM_DragFinish(struct IClass *cl, Object *obj,
2405 struct MUIP_DragFinish *msg)
2407 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2408 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2409 return 0;
2414 * Calculates addleft, addtop, subwidth, subheight from current settings.
2415 * If frame phantom, ignore horizontal frame components.
2416 * Depends on inner sizes and frame
2418 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
2419 const struct MUI_FrameSpec_intern *frame,
2420 const struct ZuneFrameGfx *zframe)
2423 /* if (XGET(obj, MUIA_UserData) == 42) */
2424 /* { */
2425 /* D(bug("area_update_msizes(%p) : ileft=%ld itop=%ld\n", obj, */
2426 /* zframe->ileft, zframe->itop)); */
2427 /* } */
2429 struct dt_frame_image *fi = zframe->customframe;
2431 if (fi != NULL)
2433 //UWORD w = fi->tile_left + fi->tile_right;
2434 //UWORD h = fi->tile_top + fi->tile_bottom;
2436 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2437 data->mad_subwidth =
2438 data->mad_addleft + data->mad_InnerRight + zframe->iright;
2439 data->mad_addtop =
2440 data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2441 data->mad_subheight =
2442 data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2444 else
2446 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2447 data->mad_subwidth =
2448 data->mad_addleft + data->mad_InnerRight + zframe->iright;
2449 data->mad_addtop =
2450 data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2451 data->mad_subheight =
2452 data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2455 if (data->mad_Flags & MADF_FRAMEPHANTOM)
2457 data->mad_addleft = 0;
2458 data->mad_subwidth = 0;
2461 // clamping ... maybe ?
2463 /* D(bug("area_update_msizes(%x,%d) => addleft/top=%d/%d, " */
2464 /* "subwidth/height=%d/%d\n", */
2465 /* obj, data->mad_Frame, data->mad_addleft, data->mad_addtop, */
2466 /* data->mad_subwidth, data->mad_subheight)); */
2469 /**************************************************************************
2470 MUIM_Area_UnknownDropDestination
2471 **************************************************************************/
2472 IPTR Area__MUIM_UnknownDropDestination(struct IClass *cl, Object *obj,
2473 struct MUIP_UnknownDropDestination *msg)
2475 return 0;
2478 /**************************************************************************
2479 MUIM_UpdateInnerSizes - Updates the innersizes of an object. You actually
2480 should only call this method if the dimensions of an object would not be
2481 affected, otherwise the results are unexpected
2482 **************************************************************************/
2483 static IPTR Area__MUIM_UpdateInnerSizes(struct IClass *cl, Object *obj,
2484 struct MUIP_UpdateInnerSizes *msg)
2486 struct MUI_AreaData *data = INST_DATA(cl, obj);
2487 const struct ZuneFrameGfx *zframe;
2488 const struct MUI_FrameSpec_intern *frame;
2489 struct MUI_FrameSpec_intern tempframe;
2491 if (_flags(obj) & MADF_SETUP)
2493 frame = get_intframe(obj, data, &tempframe);
2494 zframe = zune_zframe_get(obj, frame);
2495 area_update_msizes(obj, data, frame, zframe);
2497 return 1;
2500 static IPTR Area__MUIM_FindAreaObject(struct IClass *cl, Object *obj,
2501 struct MUIP_FindAreaObject *msg)
2503 if (msg->obj == obj)
2504 return (IPTR) obj;
2505 else
2506 return (IPTR) NULL;
2509 BOOPSI_DISPATCHER(IPTR, Area_Dispatcher, cl, obj, msg)
2511 switch (msg->MethodID)
2513 case OM_NEW:
2514 return Area__OM_NEW(cl, obj, (struct opSet *)msg);
2515 case OM_DISPOSE:
2516 return Area__OM_DISPOSE(cl, obj, msg);
2517 case OM_SET:
2518 return Area__OM_SET(cl, obj, (struct opSet *)msg);
2519 case OM_GET:
2520 return Area__OM_GET(cl, obj, (struct opGet *)msg);
2521 case MUIM_AskMinMax:
2522 return Area__MUIM_AskMinMax(cl, obj, (APTR) msg);
2523 case MUIM_Draw:
2524 return Area__MUIM_Draw(cl, obj, (APTR) msg);
2525 case MUIM_DrawBackground:
2526 return Area__MUIM_DrawBackground(cl, obj, (APTR) msg);
2527 case MUIM_DrawBackgroundBuffered:
2528 return Area__MUIM_DrawBackgroundBuffered(cl, obj, (APTR) msg);
2529 case MUIM_DrawParentBackground:
2530 return Area__MUIM_DrawParentBackground(cl, obj, (APTR) msg);
2531 case MUIM_Setup:
2532 return Area__MUIM_Setup(cl, obj, (APTR) msg);
2533 case MUIM_Cleanup:
2534 return Area__MUIM_Cleanup(cl, obj, (APTR) msg);
2535 case MUIM_Show:
2536 return Area__MUIM_Show(cl, obj, (APTR) msg);
2537 case MUIM_Hide:
2538 return Area__MUIM_Hide(cl, obj, (APTR) msg);
2539 case MUIM_GoActive:
2540 return Area__MUIM_GoActive(cl, obj, (APTR) msg);
2541 case MUIM_GoInactive:
2542 return Area__MUIM_GoInactive(cl, obj, (APTR) msg);
2543 case MUIM_Layout:
2544 return 1;
2545 case MUIM_CreateShortHelp:
2546 return Area__MUIM_CreateShortHelp(cl, obj, (APTR) msg);
2547 case MUIM_DeleteShortHelp:
2548 return Area__MUIM_DeleteShortHelp(cl, obj, (APTR) msg);
2549 case MUIM_CreateBubble:
2550 return Area__MUIM_CreateBubble(cl, obj, (APTR) msg);
2551 case MUIM_DeleteBubble:
2552 return Area__MUIM_DeleteBubble(cl, obj, (APTR) msg);
2553 case MUIM_HandleEvent:
2554 return Area__MUIM_HandleEvent(cl, obj, (APTR) msg);
2555 case MUIM_ContextMenuBuild:
2556 return Area__MUIM_ContextMenuBuild(cl, obj, (APTR) msg);
2557 case MUIM_ContextMenuChoice:
2558 return Area__MUIM_ContextMenuChoice(cl, obj, (APTR) msg);
2559 case MUIM_Timer:
2560 return Area__MUIM_Timer(cl, obj, msg);
2561 case MUIM_UpdateInnerSizes:
2562 return Area__MUIM_UpdateInnerSizes(cl, obj, (APTR) msg);
2563 case MUIM_DragQuery:
2564 return MUIV_DragQuery_Refuse;
2565 case MUIM_DragBegin:
2566 return Area__MUIM_DragBegin(cl, obj, (APTR) msg);
2567 case MUIM_DragDrop:
2568 return FALSE;
2569 case MUIM_UnknownDropDestination:
2570 return Area__MUIM_UnknownDropDestination(cl, obj, (APTR) msg);
2571 case MUIM_DragFinish:
2572 return Area__MUIM_DragFinish(cl, obj, (APTR) msg);
2573 case MUIM_DragReport:
2574 return MUIV_DragReport_Continue; /* or MUIV_DragReport_Abort? */
2575 case MUIM_DoDrag:
2576 return Area__MUIM_DoDrag(cl, obj, (APTR) msg);
2577 case MUIM_CreateDragImage:
2578 return Area__MUIM_CreateDragImage(cl, obj, (APTR) msg);
2579 case MUIM_DeleteDragImage:
2580 return Area__MUIM_DeleteDragImage(cl, obj, (APTR) msg);
2581 case MUIM_DragQueryExtended:
2582 return Area__MUIM_DragQueryExtended(cl, obj, (APTR) msg);
2583 case MUIM_HandleInput:
2584 return Area__MUIM_HandleInput(cl, obj, (APTR) msg);
2585 case MUIM_FindAreaObject:
2586 return Area__MUIM_FindAreaObject(cl, obj, (APTR) msg);
2588 case MUIM_Export:
2589 return Area__MUIM_Export(cl, obj, (APTR) msg);
2590 case MUIM_Import:
2591 return Area__MUIM_Import(cl, obj, (APTR) msg);
2594 return DoSuperMethodA(cl, obj, msg);
2596 BOOPSI_DISPATCHER_END
2599 * Class descriptor.
2601 const struct __MUIBuiltinClass _MUI_Area_desc =
2603 MUIC_Area,
2604 MUIC_Notify,
2605 sizeof(struct MUI_AreaData),
2606 (void *) Area_Dispatcher