revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / muimaster / classes / area.c
blobfe66b6d84371ecf2fea625b75cd8aced3ac554f3
1 /*
2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2016, 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>
15 #include <devices/rawkeycodes.h>
17 #include <clib/alib_protos.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <proto/graphics.h>
21 #include <proto/utility.h>
22 #include <proto/muimaster.h>
24 extern struct Library *MUIMasterBase;
25 #include "muimaster_intern.h"
27 #include "mui.h"
28 #include "support.h"
29 #include "imspec.h"
30 #include "menu.h"
31 #include "prefs.h"
32 #include "font.h"
33 #include "textengine.h"
34 #include "bubbleengine.h"
35 #include "datatypescache.h"
38 // #define MYDEBUG 1
39 #include "debug.h"
42 Area.mui/MUIA_Background done
43 Area.mui/MUIA_BottomEdge done
44 Area.mui/MUIA_ContextMenu done
45 Area.mui/MUIA_ContextMenuTrigger
46 Area.mui/MUIA_ControlChar done
47 Area.mui/MUIA_CycleChain done
48 Area.mui/MUIA_Disabled done
49 Area.mui/MUIA_Draggable done
50 Area.mui/MUIA_Dropable done
51 Area.mui/MUIA_ExportID
52 Area.mui/MUIA_FillArea done
53 Area.mui/MUIA_FixHeight done
54 Area.mui/MUIA_FixHeightTxt done
55 Area.mui/MUIA_FixWidth done
56 Area.mui/MUIA_FixWidthTxt done
57 Area.mui/MUIA_Font done
58 Area.mui/MUIA_Frame done
59 Area.mui/MUIA_FramePhantomHoriz done
60 Area.mui/MUIA_FrameTitle done
61 Area.mui/MUIA_Height done
62 Area.mui/MUIA_HorizDisappear
63 Area.mui/MUIA_HorizWeight done
64 Area.mui/MUIA_InnerBottom done
65 Area.mui/MUIA_InnerLeft done
66 Area.mui/MUIA_InnerRight done
67 Area.mui/MUIA_InnerTop done
68 Area.mui/MUIA_InputMode done
69 Area.mui/MUIA_LeftEdge done
70 Area.mui/MUIA_MaxHeight done
71 Area.mui/MUIA_MaxWidth done
72 Area.mui/MUIA_Pressed done
73 Area.mui/MUIA_RightEdge done
74 Area.mui/MUIA_Selected done
75 Area.mui/MUIA_ShortHelp done
76 Area.mui/MUIA_ShowMe done
77 Area.mui/MUIA_ShowSelState done (I only)
78 Area.mui/MUIA_Timer done
79 Area.mui/MUIA_TopEdge done
80 Area.mui/MUIA_VertDisappear
81 Area.mui/MUIA_VertWeight done
82 Area.mui/MUIA_Weight done
83 Area.mui/MUIA_Width done
84 Area.mui/MUIA_Window done
85 Area.mui/MUIA_WindowObject done
87 Area.mui/MUIM_AskMinMax done
88 Area.mui/MUIM_Cleanup done
89 Area.mui/MUIM_ContextMenuBuild done
90 Area.mui/MUIM_ContextMenuChoice done
91 Area.mui/MUIM_CreateBubble done
92 Area.mui/MUIM_CreateShortHelp done
93 Area.mui/MUIM_DeleteBubble done
94 Area.mui/MUIM_DeleteShortHelp done
95 Area.mui/MUIM_DragBegin
96 Area.mui/MUIM_DragDrop done
97 Area.mui/MUIM_DragFinish
98 Area.mui/MUIM_DragQuery done
99 Area.mui/MUIM_DragReport
100 Area.mui/MUIM_Draw done
101 Area.mui/MUIM_DrawBackground done
102 Area.mui/MUIM_HandleEvent done
103 Area.mui/MUIM_HandleInput
104 Area.mui/MUIM_Hide done
105 Area.mui/MUIM_Setup done
106 Area.mui/MUIM_Show done
109 #if (0)
110 static const int __version = 1;
111 static const int __revision = 1;
113 #ifdef DEBUG
114 static STRPTR zune_area_to_string (Object *area);
115 #endif
116 #endif
118 static const struct MUI_FrameSpec_intern *get_intframe(Object *obj,
119 struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore);
120 static void set_inner_sizes(Object *obj, struct MUI_AreaData *data);
121 static void set_title_sizes(Object *obj, struct MUI_AreaData *data);
122 static void handle_release(struct IClass *cl, Object *obj, int cancel);
124 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
125 const struct MUI_FrameSpec_intern *frame,
126 const struct ZuneFrameGfx *zframe);
127 static void setup_control_char(struct MUI_AreaData *data, Object *obj,
128 struct IClass *cl);
129 static void cleanup_control_char(struct MUI_AreaData *data, Object *obj);
131 //static void setup_cycle_chain (struct MUI_AreaData *data, Object *obj);
132 //static void cleanup_cycle_chain (struct MUI_AreaData *data, Object *obj);
134 #define ZUNE_FOCUS_TYPE_ACTIVE_OBJ 0
135 #define ZUNE_FOCUS_TYPE_DROP_OBJ 1
137 static void _zune_focus_new(Object *obj, int type)
139 Object *parent;
140 struct RastPort *rp;
141 UWORD oldDrPt;
143 //bug("_zune_focus_new 1 %p\n", obj);
145 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
146 return;
148 parent = _parent(obj);
149 rp = _rp(obj);
150 oldDrPt = rp->LinePtrn;
152 int x1 = _left(obj);
153 int y1 = _top(obj);
154 int x2 = _left(obj) + _width(obj) - 1;
155 int y2 = _top(obj) + _height(obj) - 1;
157 if (!parent || parent == _win(obj))
158 return;
160 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], _pens(obj)[MPEN_SHADOW], JAM2);
162 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
164 SetDrPt(rp, 0xCCCC);
165 x1--;
166 y1--;
167 x2++;
168 y2++;
170 else
172 SetDrPt(rp, 0xF0F0);
175 Move(rp, x1, y1);
176 Draw(rp, x2, y1);
177 Draw(rp, x2, y2);
178 Draw(rp, x1, y2);
179 Draw(rp, x1, y1);
180 SetDrPt(rp, oldDrPt);
183 static void _zune_focus_destroy(Object *obj, int type)
185 Object *parent;
187 //bug("_zune_focus_destroy 1 %p\n", obj);
189 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
190 return;
192 parent = _parent(obj);
193 int x1 = _left(obj);
194 int y1 = _top(obj);
195 int x2 = _left(obj) + _width(obj) - 1;
196 int y2 = _top(obj) + _height(obj) - 1;
197 int width;
198 int height;
200 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
202 if (!parent || parent == _win(obj))
203 return;
205 x1--;
206 y1--;
207 x2++;
208 y2++;
209 width = x2 - x1 + 1;
210 height = y2 - y1 + 1;
212 DoMethod(parent, MUIM_DrawBackground, x1, y1, width, 1, x1, y1, 0);
213 DoMethod(parent, MUIM_DrawBackground, x2, y1, 1, height, x2, y1, 0);
214 DoMethod(parent, MUIM_DrawBackground, x1, y2, width, 1, x1, y2, 0);
215 DoMethod(parent, MUIM_DrawBackground, x1, y1, 1, height, x1, y1, 0);
217 else
219 struct Region *region;
220 struct Rectangle rect;
221 APTR clip = NULL;
223 region = NewRegion();
224 if (region)
226 rect.MinX = _left(obj);
227 rect.MinY = _top(obj);
228 rect.MaxX = _right(obj);
229 rect.MaxY = _top(obj);
231 OrRectRegion(region, &rect);
233 rect.MinX = _right(obj);
234 rect.MinY = _top(obj);
235 rect.MaxX = _right(obj);
236 rect.MaxY = _bottom(obj);
238 OrRectRegion(region, &rect);
240 rect.MinX = _left(obj);
241 rect.MinY = _bottom(obj);
242 rect.MaxX = _right(obj);
243 rect.MaxY = _bottom(obj);
245 OrRectRegion(region, &rect);
247 rect.MinX = _left(obj);
248 rect.MinY = _top(obj);
249 rect.MaxX = _left(obj);
250 rect.MaxY = _bottom(obj);
252 OrRectRegion(region, &rect);
254 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
258 MUI_Redraw(obj, MADF_DRAWOBJECT);
260 if (region)
262 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
268 /**************************************************************************
269 OM_NEW
270 **************************************************************************/
271 static IPTR Area__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
273 struct MUI_AreaData *data;
274 struct TagItem *tags, *tag;
276 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
277 if (!obj)
278 return FALSE;
280 /* Initial local instance data */
281 data = INST_DATA(cl, obj);
283 data->mad_Flags =
284 MADF_FILLAREA | MADF_SHOWME | MADF_SHOWSELSTATE | MADF_DROPABLE;
285 data->mad_HorizWeight = data->mad_VertWeight = 100;
286 data->mad_InputMode = MUIV_InputMode_None;
288 /* parse initial taglist */
290 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
292 switch (tag->ti_Tag)
294 case MUIA_Background:
296 data->mad_Flags |= MADF_OWNBG;
297 if (data->mad_BackgroundSpec)
299 zune_image_spec_free(data->mad_BackgroundSpec);
301 data->mad_BackgroundSpec =
302 zune_image_spec_duplicate(tag->ti_Data);
304 break;
306 case MUIA_ControlChar:
307 data->mad_ControlChar = tag->ti_Data;
308 break;
310 case MUIA_CycleChain:
311 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
312 MADF_CYCLECHAIN);
313 break;
315 case MUIA_Disabled:
316 case MUIA_NestedDisabled:
317 if (tag->ti_Data)
319 data->mad_DisableCount = 1;
321 break;
323 case MUIA_FillArea:
324 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
325 break;
327 case MUIA_Draggable:
328 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
329 break;
331 case MUIA_Dropable:
332 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
333 break;
335 case MUIA_FixHeight:
336 data->mad_Flags |= MADF_FIXHEIGHT;
337 data->mad_HardHeight = tag->ti_Data;
338 break;
340 case MUIA_FixHeightTxt:
341 data->mad_HardHeightTxt = (STRPTR) tag->ti_Data;
342 break;
344 case MUIA_FixWidth:
345 data->mad_Flags |= MADF_FIXWIDTH;
346 data->mad_HardWidth = tag->ti_Data;
347 break;
349 case MUIA_FixWidthTxt:
350 data->mad_HardWidthTxt = (STRPTR) tag->ti_Data;
351 break;
353 case MUIA_Font:
354 data->mad_FontPreset = tag->ti_Data;
355 break;
357 case MUIA_Frame:
358 data->mad_Frame = tag->ti_Data;
359 break;
361 case MUIA_FramePhantomHoriz:
362 data->mad_Flags |= MADF_FRAMEPHANTOM;
363 break;
365 case MUIA_FrameTitle:
366 data->mad_FrameTitle = (STRPTR) tag->ti_Data;
367 break;
369 case MUIA_HorizWeight:
370 data->mad_HorizWeight = tag->ti_Data;
371 break;
373 case MUIA_InnerBottom:
374 data->mad_Flags |= MADF_INNERBOTTOM;
375 data->mad_InnerBottom = CLAMP((IPTR) tag->ti_Data, 0, 32);
376 break;
378 case MUIA_InnerLeft:
379 data->mad_Flags |= MADF_INNERLEFT;
380 data->mad_InnerLeft = CLAMP((IPTR) tag->ti_Data, 0, 32);
381 break;
383 case MUIA_InnerRight:
384 data->mad_Flags |= MADF_INNERRIGHT;
385 data->mad_InnerRight = CLAMP((IPTR) tag->ti_Data, 0, 32);
386 break;
388 case MUIA_InnerTop:
389 data->mad_Flags |= MADF_INNERTOP;
390 data->mad_InnerTop = CLAMP((IPTR) tag->ti_Data, 0, 32);
391 break;
393 case MUIA_InputMode:
394 data->mad_InputMode = tag->ti_Data;
395 break;
397 case MUIA_MaxHeight:
398 data->mad_Flags |= MADF_MAXHEIGHT;
399 data->mad_HardHeight = tag->ti_Data;
400 break;
402 case MUIA_MaxWidth:
403 data->mad_Flags |= MADF_MAXWIDTH;
404 data->mad_HardWidth = tag->ti_Data;
405 break;
407 case MUIA_Selected:
408 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SELECTED);
409 break;
411 case MUIA_ShortHelp:
412 data->mad_ShortHelp = (STRPTR) tag->ti_Data;
413 break;
415 case MUIA_ShowMe:
416 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWME);
417 break;
419 case MUIA_ShowSelState:
420 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
421 MADF_SHOWSELSTATE);
422 break;
424 case MUIA_VertWeight:
425 data->mad_VertWeight = tag->ti_Data;
426 break;
428 case MUIA_Weight:
429 data->mad_HorizWeight = data->mad_VertWeight = tag->ti_Data;
430 break;
432 case MUIA_ContextMenu:
433 data->mad_ContextMenu = (Object *) tag->ti_Data;
434 break;
438 /* In Soliton MUIA_Selected was set to MUIV_InputMode_RelVerify (=1)
439 ** for MUIA_Input_Mode MUIV_InputMode_RelVerify which is wrong of
440 ** course but MUI seems to filter this out so we have to do it also
442 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
444 if (data->mad_Flags & MADF_SELECTED)
445 D(bug("MUIA_Selected was set in OM_NEW, "
446 "although being in MUIV_InputMode_RelVerify\n"));
447 data->mad_Flags &= ~MADF_SELECTED;
450 data->mad_ehn.ehn_Events = 0; /* Will be filled on demand */
451 data->mad_ehn.ehn_Priority = -5;
453 /* Please also send mui key events to us, no idea if mui handles this
454 * like this */
455 data->mad_ehn.ehn_Flags = MUI_EHF_ALWAYSKEYS;
456 data->mad_ehn.ehn_Object = obj;
457 data->mad_ehn.ehn_Class = cl;
459 data->mad_hiehn.ehn_Events = 0;
460 data->mad_hiehn.ehn_Priority = -10;
461 data->mad_hiehn.ehn_Flags = MUI_EHF_HANDLEINPUT;
462 data->mad_hiehn.ehn_Object = obj;
463 data->mad_hiehn.ehn_Class = 0;
465 return (IPTR) obj;
468 /**************************************************************************
469 OM_DISPOSE
470 **************************************************************************/
471 static IPTR Area__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
473 struct MUI_AreaData *data = INST_DATA(cl, obj);
475 /* Safe to call this with NULL */
476 zune_image_spec_free(data->mad_BackgroundSpec);
478 return DoSuperMethodA(cl, obj, msg);
482 /**************************************************************************
483 OM_SET
484 **************************************************************************/
485 static IPTR Area__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
487 struct MUI_AreaData *data = INST_DATA(cl, obj);
488 struct TagItem *tags = msg->ops_AttrList;
489 struct TagItem *tag;
490 CONST_STRPTR old_backgroundspec;
492 int change_disable = 0; /* Has the disable state changed? */
494 while ((tag = NextTagItem(&tags)) != NULL)
496 switch (tag->ti_Tag)
498 case MUIA_Background:
499 old_backgroundspec = data->mad_BackgroundSpec;
500 data->mad_BackgroundSpec =
501 zune_image_spec_duplicate(tag->ti_Data);
502 if (!data->mad_BackgroundSpec)
504 /* Out of memory */
505 data->mad_BackgroundSpec = old_backgroundspec;
506 break;
509 data->mad_Flags |= MADF_OWNBG;
511 if (old_backgroundspec
512 && (strcmp(data->mad_BackgroundSpec,
513 old_backgroundspec) == 0))
515 /* New background does not differ from old one */
516 zune_image_spec_free(old_backgroundspec);
517 tag->ti_Tag = TAG_IGNORE;
518 break;
521 zune_image_spec_free(old_backgroundspec);
523 if (data->mad_Background)
525 if (_flags(obj) & MADF_CANDRAW)
527 zune_imspec_hide(data->mad_Background);
529 if (_flags(obj) & MADF_SETUP)
531 zune_imspec_cleanup(data->mad_Background);
532 data->mad_Background = NULL;
536 if (_flags(obj) & MADF_SETUP)
538 data->mad_Background =
539 zune_imspec_setup((IPTR) data->mad_BackgroundSpec,
540 muiRenderInfo(obj));
542 if (_flags(obj) & MADF_CANDRAW)
544 zune_imspec_show(data->mad_Background, obj);
546 MUI_Redraw(obj, MADF_DRAWOBJECT);
547 break;
549 case MUIA_FillArea:
550 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
551 break;
553 case MUIA_Frame:
554 /* this is not documented in MUI but it is possible,
555 and needed to suppress frame for external images */
556 data->mad_Frame = tag->ti_Data;
557 if (muiGlobalInfo(obj))
559 set_inner_sizes(obj, data);
560 set_title_sizes(obj, data);
562 break;
564 case MUIA_ControlChar:
565 if (_flags(obj) & MADF_SETUP)
566 cleanup_control_char(data, obj);
567 data->mad_ControlChar = tag->ti_Data;
568 if (_flags(obj) & MADF_SETUP)
569 setup_control_char(data, obj, cl);
570 break;
572 case MUIA_CycleChain:
573 // if (data->mad_InputMode == MUIV_InputMode_None)
574 // break;
576 if ((!(_flags(obj) & MADF_CYCLECHAIN) && tag->ti_Data)
577 || ((_flags(obj) & MADF_CYCLECHAIN) && !tag->ti_Data))
579 if (_flags(obj) & MADF_SETUP)
581 cleanup_control_char(data, obj);
582 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
583 MADF_CYCLECHAIN);
584 setup_control_char(data, obj, cl);
586 else
587 _handle_bool_tag(data->mad_Flags, tag->ti_Data,
588 MADF_CYCLECHAIN);
590 break;
592 case MUIA_Disabled:
593 if (tag->ti_Data)
595 if (!data->mad_DisableCount)
597 data->mad_DisableCount = 1;
598 change_disable = 1;
601 else
603 if (data->mad_DisableCount)
605 data->mad_DisableCount = 0;
606 change_disable = 1;
609 break;
611 case MUIA_NestedDisabled:
612 if (tag->ti_Data)
614 if (!data->mad_DisableCount)
615 change_disable = 1;
616 data->mad_DisableCount++;
618 else
620 if (data->mad_DisableCount)
622 data->mad_DisableCount--;
623 if (!data->mad_DisableCount)
624 change_disable = 1;
627 break;
630 case MUIA_HorizWeight:
631 data->mad_HorizWeight = tag->ti_Data;
632 break;
634 case MUIA_Pressed:
635 if (tag->ti_Data)
636 data->mad_Flags |= MADF_PRESSED;
637 else
638 data->mad_Flags &= ~MADF_PRESSED;
639 break;
641 case MUIA_ShortHelp:
642 data->mad_ShortHelp = (STRPTR) tag->ti_Data;
643 break;
645 case MUIA_ShowMe:
647 ULONG oldflags = data->mad_Flags;
648 int recalc = 0;
650 if (tag->ti_Data)
651 data->mad_Flags |= MADF_SHOWME;
652 else
653 data->mad_Flags &= ~MADF_SHOWME;
655 if (oldflags != data->mad_Flags)
657 if (!tag->ti_Data)
659 /* Should be made invisible, so send a MUIM_Hide and
660 ** then a MUIM_Cleanup to the object if needed,
661 ** as objects with MUIA_ShowMe to false get neither
662 ** MUIM_Setup nor MUIM_Show */
663 if (_flags(obj) & MADF_CANDRAW)
665 DoHideMethod(obj);
666 recalc = 1;
668 #if 0 /* SHOWME affects only show/hide */
669 if (_flags(obj) & MADF_SETUP)
670 DoMethod(obj, MUIM_Cleanup);
671 #endif
673 else
675 Object *parent = _parent(obj);
676 /* Will be NULL if direct child of a window! */
678 if (parent)
680 #if 0 /* SHOWME affects only show/hide */
681 if (_flags(parent) & MADF_SETUP)
682 DoSetupMethod(obj, muiRenderInfo(parent));
683 #endif
684 if (_flags(parent) & MADF_CANDRAW)
686 DoShowMethod(obj);
687 recalc = 1;
690 else
692 /* Check if window is open... */
696 /* If renderinfo is NULL _win(obj) doesn't work (crash) */
697 if (recalc && muiRenderInfo(obj))
699 DoMethod(_win(obj), MUIM_Window_RecalcDisplay,
700 (IPTR) _parent(obj));
704 break;
706 case MUIA_Selected:
707 /* D(bug(" Area_Set(%p) :
708 MUIA_Selected val=%ld sss=%d\n", obj, tag->ti_Data,
709 !!(data->mad_Flags & MADF_SHOWSELSTATE)));
711 if (tag->ti_Data && !(data->mad_Flags & MADF_SELECTED))
713 data->mad_Flags |= MADF_SELECTED;
714 MUI_Redraw(obj, MADF_DRAWOBJECT);
716 else if (!tag->ti_Data && (data->mad_Flags & MADF_SELECTED))
718 data->mad_Flags &= ~MADF_SELECTED;
719 MUI_Redraw(obj, MADF_DRAWOBJECT);
721 #if 0 // CHECKME: What's the purpose of this? What superclass will care?
722 else
724 tag->ti_Tag = TAG_IGNORE;
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 /* Simulate left mouse button release if the area becomes disabled */
763 if (_flags(obj) & MADF_SETUP)
764 handle_release(cl, obj, TRUE);
765 MUI_Redraw(obj, MADF_DRAWOBJECT);
768 return DoSuperMethodA(cl, obj, (Msg) msg);
772 /**************************************************************************
773 OM_GET
774 **************************************************************************/
775 static IPTR Area__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
777 #define STORE *(msg->opg_Storage)
779 struct MUI_AreaData *data = INST_DATA(cl, obj);
781 switch (msg->opg_AttrID)
783 case MUIA_Background:
784 STORE = (IPTR) data->mad_Background;
785 return TRUE;
787 case MUIA_BottomEdge:
788 STORE = (IPTR) _bottom(obj);
789 return TRUE;
791 case MUIA_ControlChar:
792 STORE = data->mad_ControlChar;
793 return TRUE;
795 case MUIA_CycleChain:
796 STORE = ((data->mad_Flags & MADF_CYCLECHAIN) != 0);
797 return TRUE;
799 case MUIA_Disabled:
800 case MUIA_NestedDisabled:
801 STORE = ! !data->mad_DisableCount; /* BOOLEAN */
802 return TRUE;
804 case MUIA_Font:
805 STORE = (IPTR) data->mad_FontPreset;
806 return TRUE;
808 case MUIA_Height:
809 STORE = (IPTR) _height(obj);
810 return TRUE;
812 case MUIA_HorizWeight:
813 STORE = (IPTR) data->mad_HorizWeight;
814 return TRUE;
816 case MUIA_InnerBottom:
817 STORE = (IPTR) data->mad_InnerBottom;
818 return TRUE;
820 case MUIA_InnerLeft:
821 STORE = (IPTR) data->mad_InnerLeft;
822 return TRUE;
824 case MUIA_InnerRight:
825 STORE = (IPTR) data->mad_InnerRight;
826 return TRUE;
828 case MUIA_InnerTop:
829 STORE = (IPTR) data->mad_InnerTop;
830 return TRUE;
832 case MUIA_LeftEdge:
833 STORE = (IPTR) _left(obj);
834 return TRUE;
836 case MUIA_Pressed:
837 STORE = ! !(data->mad_Flags & MADF_PRESSED);
838 return TRUE;
840 case MUIA_RightEdge:
841 STORE = (IPTR) _right(obj);
842 return TRUE;
844 case MUIA_Selected:
845 STORE = ! !(data->mad_Flags & MADF_SELECTED);
846 return TRUE;
848 case MUIA_ShortHelp:
849 STORE = (IPTR) data->mad_ShortHelp;
850 return TRUE;
852 case MUIA_ShowMe:
853 STORE = ! !(data->mad_Flags & MADF_SHOWME);
854 return TRUE;
856 case MUIA_Timer:
857 STORE = data->mad_Timeval;
858 return TRUE;
860 case MUIA_TopEdge:
861 STORE = (IPTR) _top(obj);
862 return TRUE;
864 case MUIA_VertWeight:
865 STORE = (IPTR) data->mad_VertWeight;
866 return TRUE;
868 case MUIA_Width:
869 STORE = (IPTR) _width(obj);
870 return TRUE;
872 case MUIA_Window:
873 if (muiAreaData(obj)->mad_RenderInfo)
874 STORE = (IPTR) _window(obj);
875 else
876 STORE = 0L;
877 return TRUE;
879 case MUIA_WindowObject:
880 if (muiAreaData(obj)->mad_RenderInfo)
881 STORE = (IPTR) _win(obj);
882 else
883 STORE = 0L;
884 return TRUE;
886 case MUIA_ContextMenu:
887 STORE = (IPTR) data->mad_ContextMenu;
888 return TRUE;
890 case MUIA_Frame:
891 STORE = (IPTR) data->mad_Frame;
892 return TRUE;
894 case MUIA_Draggable:
895 STORE = !!(data->mad_Flags & MADF_DRAGGABLE);
896 return TRUE;
898 case MUIA_Dropable:
899 STORE = !!(data->mad_Flags & MADF_DROPABLE);
900 return TRUE;
903 return (DoSuperMethodA(cl, obj, (Msg) msg));
904 #undef STORE
908 /**************************************************************************
909 MUIM_AskMinMax
910 **************************************************************************/
911 static IPTR Area__MUIM_AskMinMax(struct IClass *cl, Object *obj,
912 struct MUIP_AskMinMax *msg)
914 struct MUI_AreaData *data = INST_DATA(cl, obj);
915 const struct ZuneFrameGfx *zframe;
916 const struct MUI_FrameSpec_intern *frame;
917 struct MUI_FrameSpec_intern tempframe;
919 frame = get_intframe(obj, data, &tempframe);
920 zframe = zune_zframe_get(obj, frame);
922 area_update_msizes(obj, data, frame, zframe);
924 msg->MinMaxInfo->MinWidth = _subwidth(obj);
925 msg->MinMaxInfo->MinHeight = _subheight(obj);
927 msg->MinMaxInfo->MaxWidth = msg->MinMaxInfo->MinWidth;
928 msg->MinMaxInfo->MaxHeight = msg->MinMaxInfo->MinHeight;
929 msg->MinMaxInfo->DefWidth = msg->MinMaxInfo->MinWidth;
930 msg->MinMaxInfo->DefHeight = msg->MinMaxInfo->MinHeight;
932 /* D(bug("Area_AskMinMax 0x%lx (%s): Min=%ldx%ld Max=%ldx%ld Def=%ldx%ld\n",
933 obj, data->mad_FrameTitle, */
934 /* msg->MinMaxInfo->MinWidth, msg->MinMaxInfo->MinHeight, */
935 /* msg->MinMaxInfo->MaxWidth, msg->MinMaxInfo->MaxHeight, */
936 /* msg->MinMaxInfo->DefWidth, msg->MinMaxInfo->DefHeight)); */
938 return TRUE;
942 * Called after MUIM_AskMinMax, to handle fixed and max sizes.
944 void __area_finish_minmax(Object *obj, struct MUI_MinMax *MinMaxInfo)
946 struct MUI_AreaData *data = muiAreaData(obj);
948 if ((_flags(obj) & MADF_FIXHEIGHT) && (data->mad_HardHeight > 0))
950 int h = data->mad_HardHeight + data->mad_subheight;
952 MinMaxInfo->MinHeight =
953 MinMaxInfo->DefHeight =
954 MinMaxInfo->MaxHeight =
955 CLAMP(h, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
957 else if (data->mad_HardHeightTxt)
959 ZText *text;
961 if ((text =
962 zune_text_new(NULL, data->mad_HardHeightTxt, ZTEXT_ARG_NONE,
963 0)))
965 zune_text_get_bounds(text, obj);
967 MinMaxInfo->MinHeight =
968 MinMaxInfo->DefHeight =
969 MinMaxInfo->MaxHeight =
970 CLAMP(text->height + data->mad_subheight,
971 MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
973 zune_text_destroy(text);
977 else if (_flags(obj) & MADF_MAXHEIGHT)
979 MinMaxInfo->MaxHeight =
980 CLAMP(data->mad_HardHeight + data->mad_subheight,
981 MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
984 if ((_flags(obj) & MADF_FIXWIDTH) && (data->mad_HardWidth > 0))
986 int w = data->mad_HardWidth + data->mad_subwidth;
988 MinMaxInfo->MinWidth =
989 MinMaxInfo->DefWidth =
990 MinMaxInfo->MaxWidth =
991 CLAMP(w, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
993 else if (data->mad_HardWidthTxt)
995 ZText *text;
997 if ((text =
998 zune_text_new(NULL, data->mad_HardWidthTxt, ZTEXT_ARG_NONE,
999 0)))
1001 zune_text_get_bounds(text, obj);
1003 MinMaxInfo->MinWidth =
1004 MinMaxInfo->DefWidth =
1005 MinMaxInfo->MaxWidth =
1006 CLAMP(text->width + data->mad_subwidth,
1007 MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
1009 zune_text_destroy(text);
1013 else if (_flags(obj) & MADF_MAXWIDTH)
1015 MinMaxInfo->MaxWidth =
1016 CLAMP(data->mad_HardWidth + data->mad_subwidth,
1017 MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
1020 /* Set minmax */
1021 _minwidth(obj) = MinMaxInfo->MinWidth;
1022 _minheight(obj) = MinMaxInfo->MinHeight;
1023 _maxwidth(obj) = MinMaxInfo->MaxWidth;
1024 _maxheight(obj) = MinMaxInfo->MaxHeight;
1025 _defwidth(obj) = MinMaxInfo->DefWidth;
1026 _defheight(obj) = MinMaxInfo->DefHeight;
1029 /* <-- _top(obj) (frame title position depends of _top(obj))
1030 * ==== Title === <-- frame_top (depends of title, if centered/above)
1031 * | | <-- bgtop (depends of frame, bg always begins under frame)
1032 * | |
1033 * | |
1034 * ============== <-- "bgbottom" and "frame_bottom" (frame overwrites bg (1))
1036 * (1) : needed for phantom frame objects, where no frame overwrites bg, thus bg
1037 * must go as far as theoretical bottom frame border.
1041 * draw object background if MADF_FILLAREA.
1043 static void Area_Draw_handle_background(Object *obj,
1044 struct MUI_AreaData *data, ULONG flags,
1045 const struct ZuneFrameGfx *zframe)
1047 struct MUI_ImageSpec_intern *background;
1048 struct Rectangle r, r2, rects[4];
1049 int i, bgtop, bgleft, bgw, bgh, numrects;
1051 if (!(data->mad_Flags & MADF_SELECTED)
1052 || !(data->mad_Flags & MADF_SHOWSELSTATE))
1053 background = data->mad_Background;
1054 else
1055 background = data->mad_SelBack;
1057 if (zframe->customframe)
1058 bgtop = data->mad_TitleHeightAbove;
1059 else
1060 bgtop = data->mad_TitleHeightAbove + zframe->itop;
1062 bgleft = _left(obj);
1063 bgw = _width(obj);
1064 bgh = _height(obj) - bgtop;
1065 bgtop += _top(obj);
1067 r.MinX = bgleft;
1068 r.MinY = bgtop;
1069 r.MaxX = bgleft + bgw - 1;
1070 r.MaxY = bgtop + bgh - 1;
1072 if (data->mad_Flags & MADF_FILLAREA)
1074 rects[0] = r;
1075 numrects = 1;
1077 else
1079 /* MADF_FILLAREA not set. Only draw frame outside of
1080 innerbox (_mleft, _mtop, _mright, _mbottom):
1082 .............
1083 .***********.
1084 .*#########*.
1085 .*#########*.
1086 .***********.
1087 .............
1089 # = innerbox
1090 * = frame outside of innerbox
1091 . = object frame
1094 r2.MinX = _mleft(obj);
1095 r2.MinY = _mtop(obj);
1096 r2.MaxX = _mright(obj);
1097 r2.MaxY = _mbottom(obj);
1099 numrects = SubtractRectFromRect(&r, &r2, rects);
1102 for (i = 0; i < numrects; i++)
1104 if (!background)
1106 /* This will do the rest, TODO: on MADF_DRAWALL we not really
1107 * need to draw this */
1108 /* D(bug(" Area_Draw(%p):%ld: MUIM_DrawBackground\n", obj,
1109 __LINE__)); */
1110 /* ATTENTION: This draws the clipped away regions of the area.
1111 * Comment out and check the result to see what I mean. */
1112 DoMethod(obj, MUIM_DrawBackground,
1113 rects[i].MinX, rects[i].MinY,
1114 rects[i].MaxX - rects[i].MinX + 1,
1115 rects[i].MaxY - rects[i].MinY + 1, rects[i].MinX,
1116 rects[i].MinY, data->mad_Flags);
1118 else
1120 /* D(bug(" Area_Draw(%p):%ld: zune_imspec_draw\n", obj,
1121 __LINE__)); */
1122 zune_imspec_draw(background, data->mad_RenderInfo,
1123 rects[i].MinX, rects[i].MinY,
1124 rects[i].MaxX - rects[i].MinX + 1,
1125 rects[i].MaxY - rects[i].MinY + 1, rects[i].MinX,
1126 rects[i].MinY, 0);
1130 if (muiGlobalInfo(obj)->mgi_Prefs->window_redraw ==
1131 WINDOW_REDRAW_WITHOUT_CLEAR)
1133 if (bgtop > _top(obj) && !(flags & MADF_DRAWALL))
1135 /* Fill in the gap produced by the title with the background
1136 * of the parent object but only if
1137 * the upper object hasn't drawn it already
1138 * (which is the case if MADF_DRAWALL is setted) */
1139 DoMethod(obj, MUIM_DrawParentBackground, bgleft, _top(obj), bgw,
1140 bgtop - _top(obj), bgleft, _top(obj), data->mad_Flags);
1147 * draw object frame + title if not MADF_FRAMEPHANTOM.
1149 static void Area_Draw_handle_frame(Object *obj, struct MUI_AreaData *data,
1150 const struct ZuneFrameGfx *zframe)
1152 APTR textdrawclip = (APTR) - 1;
1153 struct Region *region;
1154 int tx;
1155 int tw, frame_height, frame_top;
1156 int addtw;
1157 struct TextExtent te;
1158 int nchars;
1159 int maxtxtwidth;
1161 /* no frametitle, just draw frame and return */
1162 if (!data->mad_FrameTitle)
1164 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1165 _top(obj), _width(obj), _height(obj), _left(obj), _top(obj),
1166 _width(obj), _height(obj));
1167 return;
1170 /* set clipping so that frame is not drawn behind title */
1172 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_color)
1174 case GROUP_TITLE_COLOR_OUTLINE:
1175 addtw = 2;
1176 break;
1177 case GROUP_TITLE_COLOR_3D:
1178 addtw = 1;
1179 break;
1180 default:
1181 addtw = 0;
1184 maxtxtwidth =
1185 _width(obj) - zframe->ileft - zframe->iright - 2 * 5 - addtw;
1187 nchars = TextFit(_rp(obj), data->mad_FrameTitle,
1188 strlen(data->mad_FrameTitle),
1189 &te, NULL, 1, maxtxtwidth, _font(obj)->tf_YSize);
1191 tw = te.te_Width + addtw;
1192 tx = _left(obj) + (_width(obj) - tw) / 2;
1194 frame_top = _top(obj) + data->mad_TitleHeightAbove;
1195 frame_height = _height(obj) - frame_top + _top(obj);
1197 if ((region = NewRegion()))
1199 struct Rectangle rect;
1200 int hspace = _font(obj)->tf_YSize / 8;
1202 rect.MinX = tx - hspace;
1203 rect.MinY = _top(obj);
1204 rect.MaxX = tx + tw - 1 + hspace;
1205 rect.MaxY = _top(obj) + _font(obj)->tf_YSize - 1;
1206 // frame is not thick enough anyway
1207 OrRectRegion(region, &rect);
1209 rect.MinX = _left(obj);
1210 rect.MinY = _top(obj);
1211 rect.MaxX = _right(obj);
1212 rect.MaxY = _bottom(obj);
1213 XorRectRegion(region, &rect);
1215 textdrawclip = MUI_AddClipRegion(muiRenderInfo(obj), region);
1218 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1219 frame_top, _width(obj), frame_height, _left(obj), frame_top,
1220 _width(obj), frame_height);
1222 if (region && textdrawclip != (APTR) - 1)
1224 MUI_RemoveClipRegion(muiRenderInfo(obj), textdrawclip);
1225 /* DisposeRegion(region);*/ /* sba: DisposeRegion happens in MUI_RemoveClipRegion, this seems wrong to me */
1228 /* Title text drawing */
1229 SetDrMd(_rp(obj), JAM1);
1230 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1231 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1232 GROUP_TITLE_COLOR_3D)
1234 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline + 1);
1235 Text(_rp(obj), data->mad_FrameTitle, nchars);
1236 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1237 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1238 Text(_rp(obj), data->mad_FrameTitle, nchars);
1240 else if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1241 GROUP_TITLE_COLOR_OUTLINE)
1243 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1245 tx += addtw / 2;
1246 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline);
1247 Text(_rp(obj), data->mad_FrameTitle, nchars);
1248 Move(_rp(obj), tx - 1, _top(obj) + _font(obj)->tf_Baseline);
1249 Text(_rp(obj), data->mad_FrameTitle, nchars);
1250 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline + 1);
1251 Text(_rp(obj), data->mad_FrameTitle, nchars);
1252 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline - 1);
1253 Text(_rp(obj), data->mad_FrameTitle, nchars);
1255 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1256 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1257 Text(_rp(obj), data->mad_FrameTitle, nchars);
1259 else
1261 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color ==
1262 GROUP_TITLE_COLOR_HILITE)
1264 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1266 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1267 Text(_rp(obj), data->mad_FrameTitle, nchars);
1271 /**************************************************************************
1272 MUIM_Draw
1273 **************************************************************************/
1274 static IPTR Area__MUIM_Draw(struct IClass *cl, Object *obj,
1275 struct MUIP_Draw *msg)
1277 struct MUI_AreaData *data = INST_DATA(cl, obj);
1278 const struct ZuneFrameGfx *zframe;
1279 struct TextFont *obj_font = NULL;
1280 ULONG flags = data->mad_Flags & MADF_DRAWFLAGS;
1282 //APTR areaclip;
1284 /* D(bug("Area_Draw(0x%lx) %ldx%ldx%ldx%ld\n", obj, _left(obj),
1285 _top(obj),_right(obj),_bottom(obj))); */
1286 /* D(bug(" Area_Draw(%p) msg=0x%08lx flags=0x%08lx\n", obj, msg->flags,
1287 _flags(obj))); */
1289 if (flags & MADF_DRAWALL)
1290 flags |= MADF_DRAWOBJECT;
1292 msg->flags = flags;
1293 data->mad_Flags &= ~MADF_DRAWFLAGS;
1295 if (!(flags & MADF_DRAWOBJECT))
1297 /* dont draw bg/frame, let subclass redraw content only
1299 return 0;
1303 /* Background can't be drawn without knowing anything about frame, thus some
1304 * calculations are made before background and frame drawing.
1307 /* on selected state, will get the opposite frame */
1308 const struct MUI_FrameSpec_intern *frame;
1309 struct MUI_FrameSpec_intern tempframe;
1310 int state;
1312 frame = get_intframe(obj, data, &tempframe);
1313 state = frame->state;
1314 if ((data->mad_Flags & MADF_SELECTED)
1315 && (data->mad_Flags & MADF_SHOWSELSTATE))
1316 state ^= 1;
1318 zframe = zune_zframe_get_with_state(obj, frame, state);
1320 /* update innersizes as there are frames which have different inner
1321 * spacings in selected state */
1322 area_update_msizes(obj, data, frame, zframe);
1325 /* Background drawing */
1326 Area_Draw_handle_background(obj, data, msg->flags, zframe);
1328 obj_font = _font(obj);
1329 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1330 SetFont(_rp(obj), _font(obj));
1332 /* Frame and frametitle drawing */
1333 if (!(data->mad_Flags & MADF_FRAMEPHANTOM))
1335 Area_Draw_handle_frame(obj, data, zframe);
1338 _font(obj) = obj_font;
1339 SetFont(_rp(obj), _font(obj));
1341 /* MUI_RemoveClipping(muiRenderInfo(obj), areaclip);*/
1343 return TRUE;
1346 /**************************************************************************
1347 MUIM_DrawParentBackground
1348 **************************************************************************/
1349 static IPTR Area__MUIM_DrawParentBackground(struct IClass *cl, Object *obj,
1350 struct MUIP_DrawParentBackground *msg)
1352 struct MUI_AreaData *data = INST_DATA(cl, obj);
1353 Object *parent = NULL;
1355 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1356 return FALSE;
1358 get(obj, MUIA_Parent, &parent);
1359 if (parent)
1361 DoMethod(parent, MUIM_DrawBackground, msg->left, msg->top,
1362 msg->width, msg->height, msg->xoffset, msg->yoffset,
1363 msg->flags);
1365 else
1367 D(bug
1368 ("Area_DrawParentBackground(%p) : MUIM_Window_DrawBackground\n",
1369 obj));
1370 DoMethod(_win(obj), MUIM_Window_DrawBackground, msg->left, msg->top,
1371 msg->width, msg->height, msg->xoffset, msg->yoffset,
1372 msg->flags);
1374 return TRUE;
1377 /**************************************************************************
1378 MUIM_DrawBackground
1379 **************************************************************************/
1380 static IPTR Area__MUIM_DrawBackground(struct IClass *cl, Object *obj,
1381 struct MUIP_DrawBackground *msg)
1383 struct MUI_AreaData *data = INST_DATA(cl, obj);
1384 struct MUI_ImageSpec_intern *bg;
1385 LONG state;
1387 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1388 return FALSE;
1390 if ((msg->flags & MADF_SELECTED) && (msg->flags & MADF_SHOWSELSTATE)
1391 && data->mad_SelBack)
1393 /* D(bug("Area_DrawBackground(%p): selected bg\n", obj)); */
1394 bg = data->mad_SelBack;
1395 state = IDS_SELECTED;
1397 else
1399 /* D(bug("Area_DrawBackground(%p): normal bg\n", obj)); */
1400 bg = data->mad_Background;
1401 state = IDS_NORMAL;
1404 const struct ZuneFrameGfx *zframe;
1405 const struct MUI_FrameSpec_intern *frame;
1406 struct MUI_FrameSpec_intern tempframe;
1408 if (!bg)
1410 D(bug("Area_DrawBackground(%p) : MUIM_DrawParentBackground\n",
1411 obj));
1413 return DoMethod(obj, MUIM_DrawParentBackground, msg->left, msg->top,
1414 msg->width, msg->height, msg->xoffset, msg->yoffset,
1415 msg->flags);
1418 frame = get_intframe(obj, data, &tempframe);
1420 int xstate = frame->state;
1421 if ((data->mad_Flags & MADF_SELECTED)
1422 && (data->mad_Flags & MADF_SHOWSELSTATE))
1423 xstate ^= 1;
1425 zframe = zune_zframe_get_with_state(obj, frame, xstate);
1427 if (zframe->customframe == NULL)
1429 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1430 zune_imspec_draw(bg, data->mad_RenderInfo,
1431 msg->left, msg->top, msg->width, msg->height,
1432 msg->xoffset, msg->yoffset, state);
1434 // if (!data->mad_FrameTitle)
1435 // {
1438 else
1440 if (zframe->noalpha == FALSE)
1442 zune_imspec_draw(bg, data->mad_RenderInfo,
1443 msg->left, msg->top, msg->width, msg->height,
1444 msg->xoffset, msg->yoffset, state);
1449 if (zframe->customframe)
1451 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj),
1452 _top(obj), _width(obj), _height(obj), msg->left, msg->top,
1453 msg->width, msg->height);
1456 return TRUE;
1459 static IPTR Area__MUIM_DrawBackgroundBuffered(struct IClass *cl,
1460 Object *obj, struct MUIP_DrawBackgroundBuffered *msg)
1462 struct MUI_AreaData *data = INST_DATA(cl, obj);
1463 struct MUI_ImageSpec_intern *bg;
1464 LONG state = 0;
1466 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1467 return FALSE;
1469 bg = data->mad_Background;
1471 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1472 zune_imspec_drawbuffered(bg, msg->rp, data->mad_RenderInfo,
1473 msg->left, msg->top, msg->width, msg->height,
1474 msg->xoffset + msg->left, msg->yoffset + msg->top, state, msg->left,
1475 msg->top, 1, _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));
1477 return TRUE;
1480 /* Perverting the EventHandlerNode structure to specify a shortcut.
1482 static void setup_control_char(struct MUI_AreaData *data, Object *obj,
1483 struct IClass *cl)
1485 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1487 data->mad_ccn.ehn_Events = data->mad_ControlChar;
1488 switch (data->mad_InputMode)
1490 case MUIV_InputMode_RelVerify:
1491 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1492 break;
1493 case MUIV_InputMode_Toggle:
1494 data->mad_ccn.ehn_Flags = MUIKEY_TOGGLE;
1495 break;
1496 case MUIV_InputMode_Immediate:
1497 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1498 break;
1500 data->mad_ccn.ehn_Priority = 0;
1501 data->mad_ccn.ehn_Object = obj;
1502 data->mad_ccn.ehn_Class = cl;
1503 DoMethod(_win(obj), MUIM_Window_AddControlCharHandler,
1504 (IPTR) & data->mad_ccn);
1509 static void cleanup_control_char(struct MUI_AreaData *data, Object *obj)
1511 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1513 DoMethod(_win(obj),
1514 MUIM_Window_RemControlCharHandler, (IPTR) & data->mad_ccn);
1518 static const struct MUI_FrameSpec_intern *get_intframe(Object *obj,
1519 struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore)
1521 if (data->mad_Frame > 100)
1523 /* Frame is spec in string format. Store it in tempstore and return
1524 a pointer to it. The caller should have such a temp variable on
1525 the stack. Don't want to add it to MUI_AreaData as that will
1526 increase mem usage of every object. */
1528 if (zune_frame_spec_to_intern((CONST_STRPTR) data->mad_Frame,
1529 tempstore))
1531 return tempstore;
1533 else
1535 return &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_None];
1538 else
1540 /* Frame is MUIV_Frame_<something> */
1541 return &muiGlobalInfo(obj)->mgi_Prefs->frames[data->mad_Frame];
1545 static void set_inner_sizes(Object *obj, struct MUI_AreaData *data)
1547 const struct MUI_FrameSpec_intern *frame;
1548 struct MUI_FrameSpec_intern tempframe;
1550 frame = get_intframe(obj, data, &tempframe);
1551 // Use frame inner spacing when not hardcoded
1552 if (!(data->mad_Flags & MADF_INNERLEFT))
1553 data->mad_InnerLeft = frame->innerLeft;
1554 if (!(data->mad_Flags & MADF_INNERTOP))
1555 data->mad_InnerTop = frame->innerTop;
1556 if (!(data->mad_Flags & MADF_INNERRIGHT))
1557 data->mad_InnerRight = frame->innerRight;
1558 if (!(data->mad_Flags & MADF_INNERBOTTOM))
1559 data->mad_InnerBottom = frame->innerBottom;
1563 static void set_title_sizes(Object *obj, struct MUI_AreaData *data)
1565 if (data->mad_FrameTitle)
1567 const struct ZuneFrameGfx *zframe;
1568 const struct MUI_FrameSpec_intern *frame;
1569 struct MUI_FrameSpec_intern tempframe;
1571 frame = get_intframe(obj, data, &tempframe);
1572 zframe = zune_zframe_get(obj, frame);
1574 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1576 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_position)
1578 case GROUP_TITLE_POSITION_ABOVE:
1579 data->mad_TitleHeightAbove = _font(obj)->tf_Baseline;
1580 break;
1581 case GROUP_TITLE_POSITION_CENTERED:
1582 data->mad_TitleHeightAbove = _font(obj)->tf_YSize / 2;
1583 break;
1586 data->mad_TitleHeightAdd =
1587 _font(obj)->tf_YSize - data->mad_InnerTop - zframe->itop;
1588 data->mad_TitleHeightBelow =
1589 data->mad_TitleHeightAdd - data->mad_TitleHeightAbove;
1594 /**************************************************************************
1595 First method to be called after an OM_NEW, it is the place
1596 for all initializations depending on the environment, but not
1597 on the gadget size/position. Matched by MUIM_Cleanup.
1598 **************************************************************************/
1599 static IPTR Area__MUIM_Setup(struct IClass *cl, Object *obj,
1600 struct MUIP_Setup *msg)
1602 struct MUI_AreaData *data = INST_DATA(cl, obj);
1603 const struct ZuneFrameGfx *zframe;
1604 const struct MUI_FrameSpec_intern *frame;
1605 struct MUI_FrameSpec_intern tempframe;
1607 muiRenderInfo(obj) = msg->RenderInfo;
1609 if (data->mad_Frame)
1611 /* no frame allowed for root object (see Area.doc) */
1612 Object *rootobj = NULL;
1613 get(_win(obj), MUIA_Window_RootObject, &rootobj);
1614 if (rootobj == obj)
1616 data->mad_Frame = MUIV_Frame_None;
1617 data->mad_FrameTitle = NULL;
1621 set_inner_sizes(obj, data);
1622 set_title_sizes(obj, data);
1624 frame = get_intframe(obj, data, &tempframe);
1625 zframe = zune_zframe_get(obj, frame);
1627 area_update_msizes(obj, data, frame, zframe);
1629 if (data->mad_Flags & MADF_OWNBG)
1631 data->mad_Background =
1632 zune_imspec_setup((IPTR) data->mad_BackgroundSpec,
1633 muiRenderInfo(obj));
1636 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1637 (data->mad_InputMode != MUIV_InputMode_None))
1639 data->mad_SelBack =
1640 zune_imspec_setup(MUII_SelectedBack, muiRenderInfo(obj));
1643 if (data->mad_InputMode != MUIV_InputMode_None || data->mad_ContextMenu)
1645 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1646 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1647 (IPTR) & data->mad_ehn);
1650 /* Those are filled by RequestIDCMP() */
1651 if (data->mad_hiehn.ehn_Events)
1652 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1653 (IPTR) & data->mad_hiehn);
1655 setup_control_char(data, obj, cl);
1656 // setup_cycle_chain (data, obj);
1658 if (data->mad_FontPreset == MUIV_Font_Inherit)
1660 if (_parent(obj) != NULL && _parent(obj) != _win(obj))
1661 data->mad_Font = _font(_parent(obj));
1662 else
1664 D(bug("Area_Setup %p: getting normal font\n", obj));
1665 data->mad_Font = zune_font_get(obj, MUIV_Font_Normal);
1666 D(bug("Area_Setup %p: got normal font %p\n", obj,
1667 data->mad_Font));
1670 else
1672 data->mad_Font = zune_font_get(obj, data->mad_FontPreset);
1675 _flags(obj) |= MADF_SETUP;
1677 data->mad_Timer.ihn_Flags = MUIIHNF_TIMER;
1678 data->mad_Timer.ihn_Method = MUIM_Timer;
1679 data->mad_Timer.ihn_Object = obj;
1681 return TRUE;
1685 /**************************************************************************
1686 Called to match a MUIM_Setup, when environment is no longer available.
1687 **************************************************************************/
1688 static IPTR Area__MUIM_Cleanup(struct IClass *cl, Object *obj,
1689 struct MUIP_Cleanup *msg)
1691 struct MUI_AreaData *data = INST_DATA(cl, obj);
1693 _flags(obj) &= ~MADF_SETUP;
1695 // cleanup_cycle_chain (data, obj);
1696 cleanup_control_char(data, obj);
1698 if (data->mad_Timer.ihn_Millis)
1700 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
1701 (IPTR) & data->mad_Timer);
1702 data->mad_Timer.ihn_Millis = 0;
1705 /* Remove the handler if it is added */
1706 if (data->mad_hiehn.ehn_Events)
1707 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1708 (IPTR) & data->mad_hiehn);
1710 /* Remove the event handler if it has been added */
1711 if (data->mad_ehn.ehn_Events)
1712 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1713 (IPTR) & data->mad_ehn);
1715 D(bug("Area cleanup %p active=%p\n", obj,
1716 (Object *) XGET(_win(obj), MUIA_Window_ActiveObject)));
1717 if (obj == (Object *) XGET(_win(obj), MUIA_Window_ActiveObject))
1719 D(bug("we are active, unset us\n"));
1720 set(_win(obj), MUIA_Window_ActiveObject,
1721 MUIV_Window_ActiveObject_None);
1724 /* It's safe to call the following function with NULL */
1725 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1726 (data->mad_InputMode != MUIV_InputMode_None))
1728 zune_imspec_cleanup(data->mad_SelBack);
1729 data->mad_SelBack = NULL;
1731 if (data->mad_Flags & MADF_OWNBG)
1733 zune_imspec_cleanup(data->mad_Background);
1734 data->mad_Background = NULL;
1737 muiRenderInfo(obj) = NULL;
1739 return TRUE;
1743 /**************************************************************************
1744 Called after the window is open and the area layouted, but before
1745 any drawing. Matched by one MUIM_Hide.
1746 Good place to init things depending on gadget size/position.
1747 **************************************************************************/
1748 static IPTR Area__MUIM_Show(struct IClass *cl, Object *obj,
1749 struct MUIP_Show *msg)
1751 struct MUI_AreaData *data = INST_DATA(cl, obj);
1753 zune_imspec_show(data->mad_Background, obj);
1755 if (data->mad_Flags & MADF_SHOWSELSTATE
1756 && data->mad_InputMode != MUIV_InputMode_None)
1758 zune_imspec_show(data->mad_SelBack, obj);
1761 return TRUE;
1764 /**************************************************************************
1765 Called when the window is about to be closed, to match MUIM_Show.
1766 **************************************************************************/
1767 static IPTR Area__MUIM_Hide(struct IClass *cl, Object *obj,
1768 struct MUIP_Hide *msg)
1770 struct MUI_AreaData *data = INST_DATA(cl, obj);
1772 zune_imspec_hide(data->mad_Background);
1773 if (data->mad_Flags & MADF_SHOWSELSTATE
1774 && data->mad_InputMode != MUIV_InputMode_None)
1776 zune_imspec_hide(data->mad_SelBack);
1779 if (data->mad_ContextZMenu)
1781 zune_close_menu(data->mad_ContextZMenu);
1782 data->mad_ContextZMenu = NULL;
1785 return TRUE;
1788 /**************************************************************************
1789 Called when gadget activated
1790 **************************************************************************/
1791 static IPTR Area__MUIM_GoActive(struct IClass *cl, Object *obj, Msg msg)
1793 //bug("Area_GoActive %p\n", obj);
1794 if (_flags(obj) & MADF_CANDRAW)
1795 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1796 return TRUE;
1799 /**************************************************************************
1800 Called when gadget deactivated
1801 **************************************************************************/
1802 static IPTR Area__MUIM_GoInactive(struct IClass *cl, Object *obj, Msg msg)
1804 //bug("Area_GoInactive %p\n", obj);
1805 if (_flags(obj) & MADF_CANDRAW)
1806 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1807 return TRUE;
1810 /**************************************************************************
1811 This one or derived methods won't be called if short help is
1812 not set in area instdata. So set this to a dummy val if overriding
1813 **************************************************************************/
1814 static IPTR Area__MUIM_CreateShortHelp(struct IClass *cl, Object *obj,
1815 struct MUIP_CreateShortHelp *msg)
1817 struct MUI_AreaData *data = INST_DATA(cl, obj);
1819 return (IPTR) data->mad_ShortHelp;
1822 /**************************************************************************
1824 **************************************************************************/
1825 static IPTR Area__MUIM_DeleteShortHelp(struct IClass *cl, Object *obj,
1826 struct MUIP_DeleteShortHelp *msg)
1828 return TRUE;
1831 /**************************************************************************
1833 **************************************************************************/
1834 static IPTR Area__MUIM_CreateBubble(struct IClass *cl, Object *obj,
1835 struct MUIP_CreateBubble *msg)
1837 return (IPTR) zune_bubble_create(obj, msg->x, msg->y, msg->txt,
1838 msg->flags);
1841 /**************************************************************************
1843 **************************************************************************/
1844 static IPTR Area__MUIM_DeleteBubble(struct IClass *cl, Object *obj,
1845 struct MUIP_DeleteBubble *msg)
1847 zune_bubble_delete(obj, msg->bubble);
1849 return TRUE;
1852 /* either lmb or press key */
1853 static void handle_press(struct IClass *cl, Object *obj)
1855 struct MUI_AreaData *data = INST_DATA(cl, obj);
1857 switch (data->mad_InputMode)
1859 case MUIV_InputMode_RelVerify:
1860 SetAttrs(obj, MUIA_Selected, TRUE, MUIA_Pressed, TRUE, TAG_DONE);
1861 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
1862 if (!data->mad_Timer.ihn_Millis && data->mad_DisableCount == 0)
1864 data->mad_Timer.ihn_Millis = 300;
1865 DoMethod(_app(obj), MUIM_Application_AddInputHandler,
1866 (IPTR) & data->mad_Timer);
1868 break;
1870 case MUIV_InputMode_Immediate:
1872 IPTR selected = FALSE;
1874 get(obj, MUIA_Selected, &selected);
1875 if (selected)
1877 /* D(bug("handle_press(%p) : nnset MUIA_Selected FALSE\n", obj)); */
1878 nnset(obj, MUIA_Selected, FALSE);
1880 /* D(bug("handle_press(%p) : set MUIA_Selected TRUE\n", obj)); */
1881 set(obj, MUIA_Selected, TRUE);
1882 /* D(bug("handle_press(%p) : done\n", obj)); */
1883 break;
1885 case MUIV_InputMode_Toggle:
1886 // although undocumented, MUI sets MUIA_Pressed too
1887 SetAttrs(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED),
1888 MUIA_Pressed, !(data->mad_Flags & MADF_PRESSED), TAG_DONE);
1889 break;
1893 /* either lmb or release key */
1894 static void handle_release(struct IClass *cl, Object *obj, int cancel)
1896 struct MUI_AreaData *data = INST_DATA(cl, obj);
1898 if (data->mad_ehn.ehn_Events)
1899 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1900 (IPTR) &data->mad_ehn);
1901 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1902 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1903 (IPTR) &data->mad_ehn);
1905 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1907 if (data->mad_Flags & MADF_SELECTED)
1909 if (cancel)
1910 nnset(obj, MUIA_Pressed, FALSE);
1911 else
1912 set(obj, MUIA_Pressed, FALSE);
1914 set(obj, MUIA_Selected, FALSE);
1918 if (data->mad_Timer.ihn_Millis)
1920 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
1921 (IPTR) & data->mad_Timer);
1922 data->mad_Timer.ihn_Millis = 0;
1927 static IPTR event_button(Class *cl, Object *obj,
1928 struct IntuiMessage *imsg)
1930 struct MUI_AreaData *data = INST_DATA(cl, obj);
1931 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1932 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1934 switch (imsg->Code)
1936 case SELECTDOWN:
1937 if (data->mad_InputMode == MUIV_InputMode_None)
1938 break;
1940 if (in)
1942 // set(_win(obj), MUIA_Window_ActiveObject, obj);
1943 data->mad_ClickX = imsg->MouseX;
1944 data->mad_ClickY = imsg->MouseY;
1946 if ((data->mad_InputMode != MUIV_InputMode_Toggle)
1947 && (data->mad_Flags & MADF_SELECTED))
1948 break;
1949 nnset(obj, MUIA_Timer, 0);
1950 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1952 if (data->mad_ehn.ehn_Events)
1953 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
1954 (IPTR) &data->mad_ehn);
1955 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE | IDCMP_RAWKEY;
1956 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
1957 (IPTR) &data->mad_ehn);
1959 handle_press(cl, obj);
1960 return MUI_EventHandlerRC_Eat;
1962 break;
1964 case SELECTUP:
1965 if (data->mad_InputMode == MUIV_InputMode_None)
1966 break;
1968 if (data->mad_ehn.ehn_Events != IDCMP_MOUSEBUTTONS)
1970 handle_release(cl, obj, FALSE /* cancel */ );
1971 return MUI_EventHandlerRC_Eat;
1973 break;
1975 case MENUDOWN:
1976 if (in && data->mad_ContextMenu)
1978 Object *menuobj =
1979 (Object *) DoMethod(obj, MUIM_ContextMenuBuild,
1980 imsg->MouseX, imsg->MouseY);
1981 if (menuobj)
1983 struct NewMenu *newmenu = NULL;
1985 /* stegerg: HACKME, CHECKME! The menu/menu item objs should
1986 automatically be connected (parentobject setup) without
1987 need for this, but they aren't. Because of how family
1988 class is and is used by other classes, I think!? */
1989 DoMethod(menuobj, MUIM_ConnectParent, obj);
1991 get(menuobj, MUIA_Menuitem_NewMenu, &newmenu);
1992 if (newmenu)
1994 if (data->mad_ContextZMenu)
1995 zune_close_menu(data->mad_ContextZMenu);
1996 data->mad_ContextZMenu =
1997 zune_open_menu(_window(obj), newmenu);
2000 if (data->mad_ehn.ehn_Events)
2001 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2002 (IPTR) &data->mad_ehn);
2003 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE;
2004 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2005 (IPTR) &data->mad_ehn);
2007 return MUI_EventHandlerRC_Eat;
2009 break;
2011 case MENUUP:
2012 if (data->mad_ContextZMenu)
2014 struct MenuItem *item = zune_leave_menu(data->mad_ContextZMenu);
2016 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2017 (IPTR) &data->mad_ehn);
2018 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2019 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2020 (IPTR) &data->mad_ehn);
2022 if (item)
2024 Object *itemobj = (Object *) GTMENUITEM_USERDATA(item);
2026 /* CHECKME: MUIA_MenuItem_Trigger should probably be set inside
2027 MUIM_ContextMenuChoice!? But there I only know about
2028 itemobj, not MenuItem itself! */
2029 if (item->Flags & CHECKIT)
2031 set(itemobj, MUIA_Menuitem_Checked,
2032 ! !(item->Flags & CHECKED));
2036 set(itemobj, MUIA_Menuitem_Trigger, item);
2038 DoMethod(obj, MUIM_ContextMenuChoice, itemobj);
2042 zune_close_menu(data->mad_ContextZMenu);
2043 data->mad_ContextZMenu = NULL;
2045 return MUI_EventHandlerRC_Eat;
2048 break;
2051 return 0;
2054 static IPTR event_motion(Class *cl, Object *obj,
2055 struct IntuiMessage *imsg)
2057 struct MUI_AreaData *data = INST_DATA(cl, obj);
2059 if ((imsg->Qualifier & IEQUALIFIER_RBUTTON) && data->mad_ContextZMenu)
2061 zune_mouse_update(data->mad_ContextZMenu, 0);
2062 return MUI_EventHandlerRC_Eat;
2065 if (imsg->Qualifier & IEQUALIFIER_LEFTBUTTON)
2067 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
2068 && _between(_top(obj), imsg->MouseY, _bottom(obj));
2070 if (in)
2072 if ((data->mad_Flags & MADF_DRAGGABLE)
2073 && ((abs(data->mad_ClickX - imsg->MouseX) >= 3)
2074 || (abs(data->mad_ClickY - imsg->MouseY) >= 3)))
2075 /* should be user configurable */
2077 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
2078 set(obj, MUIA_Selected, FALSE);
2079 nnset(obj, MUIA_Pressed, FALSE);
2081 if (data->mad_ehn.ehn_Events)
2082 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2083 (IPTR) &data->mad_ehn);
2084 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2085 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2086 (IPTR) &data->mad_ehn);
2087 if (data->mad_Timer.ihn_Millis)
2089 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
2090 (IPTR) & data->mad_Timer);
2091 data->mad_Timer.ihn_Millis = 0;
2094 DoMethod(obj, MUIM_DoDrag, data->mad_ClickX - _left(obj),
2095 data->mad_ClickY - _top(obj), 0);
2096 return MUI_EventHandlerRC_Eat;
2100 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
2102 if (!in && (data->mad_Flags & MADF_SELECTED)) /* going out */
2104 set(obj, MUIA_Selected, FALSE);
2106 else if (in && !(data->mad_Flags & MADF_SELECTED)) /* going in */
2108 set(obj, MUIA_Selected, TRUE);
2112 return MUI_EventHandlerRC_Eat;
2115 /**************************************************************************
2117 **************************************************************************/
2118 static IPTR Area__MUIM_HandleEvent(struct IClass *cl, Object *obj,
2119 struct MUIP_HandleEvent *msg)
2121 struct MUI_AreaData *data = INST_DATA(cl, obj);
2123 if (data->mad_DisableCount)
2124 return 0;
2125 if (data->mad_InputMode == MUIV_InputMode_None
2126 && !data->mad_ContextMenu)
2127 return 0;
2129 if (msg->muikey != MUIKEY_NONE)
2131 switch (msg->muikey)
2133 case MUIKEY_PRESS:
2134 if (data->mad_Flags & MADF_SELECTED)
2135 break;
2136 if (data->mad_ehn.ehn_Events)
2137 DoMethod(_win(obj), MUIM_Window_RemEventHandler,
2138 (IPTR) &data->mad_ehn);
2139 data->mad_ehn.ehn_Events |= IDCMP_RAWKEY;
2140 DoMethod(_win(obj), MUIM_Window_AddEventHandler,
2141 (IPTR) &data->mad_ehn);
2142 handle_press(cl, obj);
2143 return MUI_EventHandlerRC_Eat;
2145 case MUIKEY_TOGGLE:
2146 if (data->mad_InputMode == MUIV_InputMode_Toggle)
2147 set(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED));
2148 return MUI_EventHandlerRC_Eat;
2150 case MUIKEY_RELEASE:
2151 handle_release(cl, obj, FALSE /* cancel */ );
2152 return MUI_EventHandlerRC_Eat;
2154 return 0;
2157 if (msg->imsg)
2159 switch (msg->imsg->Class)
2161 case IDCMP_MOUSEBUTTONS:
2162 return event_button(cl, obj, msg->imsg);
2163 case IDCMP_MOUSEMOVE:
2164 return event_motion(cl, obj, msg->imsg);
2165 case IDCMP_RAWKEY:
2167 unsigned char code;
2168 UWORD msg_code;
2169 /* Remove the up prefix as convert key does not convert an
2170 * upkey event */
2171 msg_code = msg->imsg->Code;
2172 msg->imsg->Code &= ~IECODE_UP_PREFIX;
2173 code = ConvertKey(msg->imsg);
2174 msg->imsg->Code = msg_code;
2176 if (code != 0 && code == data->mad_ControlChar)
2178 if (msg->imsg->Code & IECODE_UP_PREFIX)
2180 msg->muikey = MUIKEY_RELEASE;
2182 else
2184 msg->muikey = MUIKEY_PRESS;
2186 msg->imsg = NULL;
2187 return Area__MUIM_HandleEvent(cl, obj, msg);
2190 if (msg->imsg->
2191 Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
2193 handle_release(cl, obj, TRUE /* cancel */ );
2196 /* Do not eat wheel movement events */
2197 if ((msg->imsg->Code == RAWKEY_NM_WHEEL_UP)
2198 || (msg->imsg->Code == RAWKEY_NM_WHEEL_DOWN))
2199 return 0;
2201 return MUI_EventHandlerRC_Eat;
2203 break;
2206 return 0;
2209 /**************************************************************************
2211 **************************************************************************/
2212 static IPTR Area__MUIM_HandleInput(struct IClass *cl, Object *obj,
2213 struct MUIP_HandleInput *msg)
2215 /* Actually a dummy, but real MUI does handle here the input stuff which
2216 * Zune has in Area_HandleEvent. For compatibility we should do this too */
2217 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\b", obj, msg->imsg,
2218 // msg->muikey);
2219 return 0;
2222 /**************************************************************************
2223 Trivial; custom classes may override this to get dynamic menus.
2224 **************************************************************************/
2225 static IPTR Area__MUIM_ContextMenuBuild(struct IClass *cl, Object *obj,
2226 struct MUIP_ContextMenuBuild *msg)
2228 struct MUI_AreaData *data = INST_DATA(cl, obj);
2229 return (IPTR) data->mad_ContextMenu; /* a Menustrip object */
2232 /**************************************************************************/
2233 static IPTR Area__MUIM_ContextMenuChoice(struct IClass *cl, Object *obj,
2234 struct MUIP_ContextMenuChoice *msg)
2236 set(obj, MUIA_ContextMenuTrigger, msg->item);
2237 return 0;
2241 /**************************************************************************
2242 MUIM_Export : to export an object's "contents" to a dataspace object.
2243 **************************************************************************/
2244 static IPTR Area__MUIM_Export(struct IClass *cl, Object *obj,
2245 struct MUIP_Export *msg)
2247 struct MUI_AreaData *data = INST_DATA(cl, obj);
2248 ULONG id;
2250 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2252 char selected = (data->mad_Flags & MADF_SELECTED) ? 1 : 0;
2253 DoMethod(msg->dataspace, MUIM_Dataspace_Add, (IPTR) & selected,
2254 sizeof(char), (IPTR) id);
2256 return 0;
2260 /**************************************************************************
2261 MUIM_Import : to import an object's "contents" from a dataspace object.
2262 **************************************************************************/
2263 static IPTR Area__MUIM_Import(struct IClass *cl, Object *obj,
2264 struct MUIP_Import *msg)
2266 ULONG id;
2268 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2270 char *selected =
2271 (char *)DoMethod(msg->dataspace, MUIM_Dataspace_Find,
2272 (IPTR) id);
2274 if (selected)
2275 set(obj, MUIA_Selected, *selected);
2277 return 0;
2280 /**************************************************************************
2281 MUIM_Timer
2282 **************************************************************************/
2283 static IPTR Area__MUIM_Timer(struct IClass *cl, Object *obj, Msg msg)
2285 struct MUI_AreaData *data = INST_DATA(cl, obj);
2286 if (data->mad_Timer.ihn_Millis)
2287 DoMethod(_app(obj), MUIM_Application_RemInputHandler,
2288 (IPTR) & data->mad_Timer);
2289 data->mad_Timer.ihn_Millis = 50;
2290 DoMethod(_app(obj), MUIM_Application_AddInputHandler,
2291 (IPTR) & data->mad_Timer);
2293 if (data->mad_Flags & MADF_SELECTED)
2294 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
2295 return 0;
2298 /**************************************************************************
2299 MUIM_DoDrag
2300 **************************************************************************/
2301 static IPTR Area__MUIM_DoDrag(struct IClass *cl, Object *obj,
2302 struct MUIP_DoDrag *msg)
2304 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2305 DoMethod(_win(obj), MUIM_Window_DragObject, (IPTR) obj, msg->touchx,
2306 msg->touchy, msg->flags);
2307 return 0;
2310 /**************************************************************************
2311 MUIM_CreateDragImage
2312 **************************************************************************/
2313 static IPTR Area__MUIM_CreateDragImage(struct IClass *cl, Object *obj,
2314 struct MUIP_CreateDragImage *msg)
2316 struct MUI_DragImage *img = (struct MUI_DragImage *)
2317 AllocVec(sizeof(struct MUI_DragImage), MEMF_CLEAR);
2318 if (img)
2320 const struct ZuneFrameGfx *zframe;
2321 LONG depth =
2322 GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH);
2324 zframe =
2325 zune_zframe_get(obj,
2326 &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Drag]);
2328 img->width = _width(obj) + zframe->ileft + zframe->iright;
2329 img->height = _height(obj) + zframe->itop + zframe->ibottom;
2331 if ((img->bm =
2332 AllocBitMap(img->width, img->height, depth, BMF_MINPLANES,
2333 _screen(obj)->RastPort.BitMap)))
2335 /* Render the stuff now */
2336 struct RastPort *rp_save = muiRenderInfo(obj)->mri_RastPort;
2337 struct RastPort temprp;
2338 InitRastPort(&temprp);
2339 temprp.BitMap = img->bm;
2340 ClipBlit(_rp(obj), _left(obj), _top(obj), &temprp,
2341 zframe->ileft, zframe->itop, _width(obj), _height(obj),
2342 0xc0);
2344 muiRenderInfo(obj)->mri_RastPort = &temprp;
2345 zframe->draw(zframe->customframe, muiRenderInfo(obj), 0, 0,
2346 img->width, img->height, 0, 0, img->width, img->height);
2347 muiRenderInfo(obj)->mri_RastPort = rp_save;
2350 img->touchx = msg->touchx;
2351 img->touchy = msg->touchy;
2352 img->flags = 0;
2354 return (IPTR) img;
2357 /**************************************************************************
2358 MUIM_DeleteDragImage
2359 **************************************************************************/
2360 static IPTR Area__MUIM_DeleteDragImage(struct IClass *cl, Object *obj,
2361 struct MUIP_DeleteDragImage *msg)
2363 if (msg->di)
2365 if (msg->di->bm)
2366 FreeBitMap(msg->di->bm);
2367 FreeVec(msg->di);
2369 return 0;
2372 /**************************************************************************
2373 MUIM_DragQueryExtended
2374 **************************************************************************/
2375 static IPTR Area__MUIM_DragQueryExtended(struct IClass *cl, Object *obj,
2376 struct MUIP_DragQueryExtended *msg)
2378 struct MUI_AreaData *data = INST_DATA(cl, obj);
2379 if (data->mad_Flags & MADF_DROPABLE)
2381 if (_left(obj) <= msg->x && msg->x <= _right(obj)
2382 && _top(obj) <= msg->y && msg->y <= _bottom(obj))
2384 if (DoMethod(obj, MUIM_DragQuery,
2385 (IPTR) msg->obj) == MUIV_DragQuery_Accept)
2386 return (IPTR) obj;
2389 return 0;
2392 /**************************************************************************
2393 MUIM_DragBegin
2394 **************************************************************************/
2395 static IPTR Area__MUIM_DragBegin(struct IClass *cl, Object *obj,
2396 struct MUIP_DragBegin *msg)
2398 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2399 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2400 return 0;
2403 /**************************************************************************
2404 MUIM_DragFinish
2405 **************************************************************************/
2406 static IPTR Area__MUIM_DragFinish(struct IClass *cl, Object *obj,
2407 struct MUIP_DragFinish *msg)
2409 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2410 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2411 return 0;
2416 * Calculates addleft, addtop, subwidth, subheight from current settings.
2417 * If frame phantom, ignore horizontal frame components.
2418 * Depends on inner sizes and frame
2420 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
2421 const struct MUI_FrameSpec_intern *frame,
2422 const struct ZuneFrameGfx *zframe)
2425 /* if (XGET(obj, MUIA_UserData) == 42) */
2426 /* { */
2427 /* D(bug("area_update_msizes(%p) : ileft=%ld itop=%ld\n", obj, */
2428 /* zframe->ileft, zframe->itop)); */
2429 /* } */
2431 struct dt_frame_image *fi = zframe->customframe;
2433 if (fi != NULL)
2435 //UWORD w = fi->tile_left + fi->tile_right;
2436 //UWORD h = fi->tile_top + fi->tile_bottom;
2438 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2439 data->mad_subwidth =
2440 data->mad_addleft + data->mad_InnerRight + zframe->iright;
2441 data->mad_addtop =
2442 data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2443 data->mad_subheight =
2444 data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2446 else
2448 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2449 data->mad_subwidth =
2450 data->mad_addleft + data->mad_InnerRight + zframe->iright;
2451 data->mad_addtop =
2452 data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2453 data->mad_subheight =
2454 data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2457 if (data->mad_Flags & MADF_FRAMEPHANTOM)
2459 data->mad_addleft = 0;
2460 data->mad_subwidth = 0;
2463 // clamping ... maybe ?
2465 /* D(bug("area_update_msizes(%x,%d) => addleft/top=%d/%d, " */
2466 /* "subwidth/height=%d/%d\n", */
2467 /* obj, data->mad_Frame, data->mad_addleft, data->mad_addtop, */
2468 /* data->mad_subwidth, data->mad_subheight)); */
2471 /**************************************************************************
2472 MUIM_Area_UnknownDropDestination
2473 **************************************************************************/
2474 IPTR Area__MUIM_UnknownDropDestination(struct IClass *cl, Object *obj,
2475 struct MUIP_UnknownDropDestination *msg)
2477 return 0;
2480 /**************************************************************************
2481 MUIM_UpdateInnerSizes - Updates the innersizes of an object. You actually
2482 should only call this method if the dimensions of an object would not be
2483 affected, otherwise the results are unexpected
2484 **************************************************************************/
2485 static IPTR Area__MUIM_UpdateInnerSizes(struct IClass *cl, Object *obj,
2486 struct MUIP_UpdateInnerSizes *msg)
2488 struct MUI_AreaData *data = INST_DATA(cl, obj);
2489 const struct ZuneFrameGfx *zframe;
2490 const struct MUI_FrameSpec_intern *frame;
2491 struct MUI_FrameSpec_intern tempframe;
2493 if (_flags(obj) & MADF_SETUP)
2495 frame = get_intframe(obj, data, &tempframe);
2496 zframe = zune_zframe_get(obj, frame);
2497 area_update_msizes(obj, data, frame, zframe);
2499 return 1;
2502 static IPTR Area__MUIM_FindAreaObject(struct IClass *cl, Object *obj,
2503 struct MUIP_FindAreaObject *msg)
2505 if (msg->obj == obj)
2506 return (IPTR) obj;
2507 else
2508 return (IPTR) NULL;
2511 BOOPSI_DISPATCHER(IPTR, Area_Dispatcher, cl, obj, msg)
2513 switch (msg->MethodID)
2515 case OM_NEW:
2516 return Area__OM_NEW(cl, obj, (struct opSet *)msg);
2517 case OM_DISPOSE:
2518 return Area__OM_DISPOSE(cl, obj, msg);
2519 case OM_SET:
2520 return Area__OM_SET(cl, obj, (struct opSet *)msg);
2521 case OM_GET:
2522 return Area__OM_GET(cl, obj, (struct opGet *)msg);
2523 case MUIM_AskMinMax:
2524 return Area__MUIM_AskMinMax(cl, obj, (APTR) msg);
2525 case MUIM_Draw:
2526 return Area__MUIM_Draw(cl, obj, (APTR) msg);
2527 case MUIM_DrawBackground:
2528 return Area__MUIM_DrawBackground(cl, obj, (APTR) msg);
2529 case MUIM_DrawBackgroundBuffered:
2530 return Area__MUIM_DrawBackgroundBuffered(cl, obj, (APTR) msg);
2531 case MUIM_DrawParentBackground:
2532 return Area__MUIM_DrawParentBackground(cl, obj, (APTR) msg);
2533 case MUIM_Setup:
2534 return Area__MUIM_Setup(cl, obj, (APTR) msg);
2535 case MUIM_Cleanup:
2536 return Area__MUIM_Cleanup(cl, obj, (APTR) msg);
2537 case MUIM_Show:
2538 return Area__MUIM_Show(cl, obj, (APTR) msg);
2539 case MUIM_Hide:
2540 return Area__MUIM_Hide(cl, obj, (APTR) msg);
2541 case MUIM_GoActive:
2542 return Area__MUIM_GoActive(cl, obj, (APTR) msg);
2543 case MUIM_GoInactive:
2544 return Area__MUIM_GoInactive(cl, obj, (APTR) msg);
2545 case MUIM_Layout:
2546 return 1;
2547 case MUIM_CreateShortHelp:
2548 return Area__MUIM_CreateShortHelp(cl, obj, (APTR) msg);
2549 case MUIM_DeleteShortHelp:
2550 return Area__MUIM_DeleteShortHelp(cl, obj, (APTR) msg);
2551 case MUIM_CreateBubble:
2552 return Area__MUIM_CreateBubble(cl, obj, (APTR) msg);
2553 case MUIM_DeleteBubble:
2554 return Area__MUIM_DeleteBubble(cl, obj, (APTR) msg);
2555 case MUIM_HandleEvent:
2556 return Area__MUIM_HandleEvent(cl, obj, (APTR) msg);
2557 case MUIM_ContextMenuBuild:
2558 return Area__MUIM_ContextMenuBuild(cl, obj, (APTR) msg);
2559 case MUIM_ContextMenuChoice:
2560 return Area__MUIM_ContextMenuChoice(cl, obj, (APTR) msg);
2561 case MUIM_Timer:
2562 return Area__MUIM_Timer(cl, obj, msg);
2563 case MUIM_UpdateInnerSizes:
2564 return Area__MUIM_UpdateInnerSizes(cl, obj, (APTR) msg);
2565 case MUIM_DragQuery:
2566 return MUIV_DragQuery_Refuse;
2567 case MUIM_DragBegin:
2568 return Area__MUIM_DragBegin(cl, obj, (APTR) msg);
2569 case MUIM_DragDrop:
2570 return FALSE;
2571 case MUIM_UnknownDropDestination:
2572 return Area__MUIM_UnknownDropDestination(cl, obj, (APTR) msg);
2573 case MUIM_DragFinish:
2574 return Area__MUIM_DragFinish(cl, obj, (APTR) msg);
2575 case MUIM_DragReport:
2576 return MUIV_DragReport_Continue; /* or MUIV_DragReport_Abort? */
2577 case MUIM_DoDrag:
2578 return Area__MUIM_DoDrag(cl, obj, (APTR) msg);
2579 case MUIM_CreateDragImage:
2580 return Area__MUIM_CreateDragImage(cl, obj, (APTR) msg);
2581 case MUIM_DeleteDragImage:
2582 return Area__MUIM_DeleteDragImage(cl, obj, (APTR) msg);
2583 case MUIM_DragQueryExtended:
2584 return Area__MUIM_DragQueryExtended(cl, obj, (APTR) msg);
2585 case MUIM_HandleInput:
2586 return Area__MUIM_HandleInput(cl, obj, (APTR) msg);
2587 case MUIM_FindAreaObject:
2588 return Area__MUIM_FindAreaObject(cl, obj, (APTR) msg);
2590 case MUIM_Export:
2591 return Area__MUIM_Export(cl, obj, (APTR) msg);
2592 case MUIM_Import:
2593 return Area__MUIM_Import(cl, obj, (APTR) msg);
2596 return DoSuperMethodA(cl, obj, msg);
2598 BOOPSI_DISPATCHER_END
2601 * Class descriptor.
2603 const struct __MUIBuiltinClass _MUI_Area_desc =
2605 MUIC_Area,
2606 MUIC_Notify,
2607 sizeof(struct MUI_AreaData),
2608 (void *) Area_Dispatcher