MUIA_Frame attribute now should also support specifying frame as
[tangerine.git] / workbench / libs / muimaster / classes / area.c
blob13dc873f4cba0f78823a5510631c93537df3f6b0
1 /*
2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, 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(
116 Object *obj,
117 struct MUI_AreaData *data,
118 struct MUI_FrameSpec_intern *tempstore);
119 static void set_inner_sizes (Object *obj, struct MUI_AreaData *data);
120 static void set_title_sizes (Object *obj, struct MUI_AreaData *data);
122 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
123 const struct MUI_FrameSpec_intern *frame,
124 const struct ZuneFrameGfx *zframe);
125 static void setup_control_char (struct MUI_AreaData *data, Object *obj,
126 struct IClass *cl);
127 static void cleanup_control_char (struct MUI_AreaData *data, Object *obj);
129 //static void setup_cycle_chain (struct MUI_AreaData *data, Object *obj);
130 //static void cleanup_cycle_chain (struct MUI_AreaData *data, Object *obj);
132 #define ZUNE_FOCUS_TYPE_ACTIVE_OBJ 0
133 #define ZUNE_FOCUS_TYPE_DROP_OBJ 1
135 static void _zune_focus_new(Object *obj, int type)
137 Object *parent;
138 struct RastPort *rp;
139 UWORD oldDrPt;
141 //bug("_zune_focus_new 1 %p\n", obj);
143 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
144 return;
146 parent = _parent(obj);
147 rp = _rp(obj);
148 oldDrPt = rp->LinePtrn;
150 int x1 = _left(obj);
151 int y1 = _top(obj);
152 int x2 = _left(obj) + _width(obj) -1;
153 int y2 = _top(obj) + _height(obj) -1;
155 if (!parent || parent == _win(obj)) return;
157 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], _pens(obj)[MPEN_SHADOW], JAM2);
159 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
161 SetDrPt(rp, 0xCCCC);
162 x1--; y1--; x2++; y2++;
164 else
166 SetDrPt(rp,0xF0F0);
169 Move(rp, x1, y1);
170 Draw(rp, x2, y1);
171 Draw(rp, x2, y2);
172 Draw(rp, x1, y2);
173 Draw(rp, x1, y1);
174 SetDrPt(rp, oldDrPt);
177 static void _zune_focus_destroy(Object *obj, int type)
179 Object *parent;
181 //bug("_zune_focus_destroy 1 %p\n", obj);
183 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
184 return;
186 parent = _parent(obj);
187 int x1 = _left(obj);
188 int y1 = _top(obj);
189 int x2 = _left(obj) + _width(obj) - 1;
190 int y2 = _top(obj) + _height(obj) - 1;
191 int width;
192 int height;
194 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
196 if (!parent || parent == _win(obj)) return;
198 x1--; y1--; x2++; y2++;
199 width = x2 - x1 + 1;
200 height = y2 - y1 + 1;
202 DoMethod(parent, MUIM_DrawBackground, x1, y1, width, 1, x1, y1, 0);
203 DoMethod(parent, MUIM_DrawBackground, x2, y1, 1, height, x2, y1, 0);
204 DoMethod(parent, MUIM_DrawBackground, x1, y2, width, 1, x1, y2, 0);
205 DoMethod(parent, MUIM_DrawBackground, x1, y1, 1, height, x1, y1, 0);
207 else
209 struct Region *region;
210 struct Rectangle rect;
211 APTR clip = NULL;
213 region = NewRegion();
214 if (region)
216 rect.MinX = _left(obj);
217 rect.MinY = _top(obj);
218 rect.MaxX = _right(obj);
219 rect.MaxY = _top(obj);
221 OrRectRegion(region, &rect);
223 rect.MinX = _right(obj);
224 rect.MinY = _top(obj);
225 rect.MaxX = _right(obj);
226 rect.MaxY = _bottom(obj);
228 OrRectRegion(region, &rect);
230 rect.MinX = _left(obj);
231 rect.MinY = _bottom(obj);
232 rect.MaxX = _right(obj);
233 rect.MaxY = _bottom(obj);
235 OrRectRegion(region, &rect);
237 rect.MinX = _left(obj);
238 rect.MinY = _top(obj);
239 rect.MaxX = _left(obj);
240 rect.MaxY = _bottom(obj);
242 OrRectRegion(region, &rect);
244 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
246 } /* if (region) */
248 MUI_Redraw(obj, MADF_DRAWOBJECT);
250 if (region)
252 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
260 /**************************************************************************
261 OM_NEW
262 **************************************************************************/
263 static IPTR Area__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
265 struct MUI_AreaData *data;
266 struct TagItem *tags,*tag;
268 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
269 if (!obj) return FALSE;
271 /* Initial local instance data */
272 data = INST_DATA(cl, obj);
274 data->mad_Flags = MADF_FILLAREA | MADF_SHOWME | MADF_SHOWSELSTATE | MADF_DROPABLE;
275 data->mad_HorizWeight = data->mad_VertWeight = 100;
276 data->mad_InputMode = MUIV_InputMode_None;
278 /* parse initial taglist */
280 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); )
282 switch (tag->ti_Tag)
284 case MUIA_Background:
286 data->mad_Flags |= MADF_OWNBG;
287 if (data->mad_BackgroundSpec)
289 zune_image_spec_free(data->mad_BackgroundSpec);
291 data->mad_BackgroundSpec = zune_image_spec_duplicate(tag->ti_Data);
293 break;
295 case MUIA_ControlChar:
296 data->mad_ControlChar = tag->ti_Data;
297 break;
299 case MUIA_CycleChain:
300 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
301 break;
303 case MUIA_Disabled:
304 case MUIA_NestedDisabled:
305 if (tag->ti_Data)
307 data->mad_DisableCount = 1;
309 break;
311 case MUIA_FillArea:
312 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
313 break;
315 case MUIA_Draggable:
316 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
317 break;
319 case MUIA_Dropable:
320 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
321 break;
323 case MUIA_FixHeight:
324 data->mad_Flags |= MADF_FIXHEIGHT;
325 data->mad_HardHeight = tag->ti_Data;
326 break;
328 case MUIA_FixHeightTxt:
329 data->mad_HardHeightTxt = (STRPTR)tag->ti_Data;
330 break;
332 case MUIA_FixWidth:
333 data->mad_Flags |= MADF_FIXWIDTH;
334 data->mad_HardWidth = tag->ti_Data;
335 break;
337 case MUIA_FixWidthTxt:
338 data->mad_HardWidthTxt = (STRPTR)tag->ti_Data;
339 break;
341 case MUIA_Font:
342 data->mad_FontPreset = tag->ti_Data;
343 break;
345 case MUIA_Frame:
346 data->mad_Frame = tag->ti_Data;
347 break;
349 case MUIA_FramePhantomHoriz:
350 data->mad_Flags |= MADF_FRAMEPHANTOM;
351 break;
353 case MUIA_FrameTitle:
354 data->mad_FrameTitle = (STRPTR)tag->ti_Data;
355 break;
357 case MUIA_HorizWeight:
358 data->mad_HorizWeight = tag->ti_Data;
359 break;
361 case MUIA_InnerBottom:
362 data->mad_Flags |= MADF_INNERBOTTOM;
363 data->mad_InnerBottom = CLAMP((IPTR)tag->ti_Data, 0, 32);
364 break;
366 case MUIA_InnerLeft:
367 data->mad_Flags |= MADF_INNERLEFT;
368 data->mad_InnerLeft = CLAMP((IPTR)tag->ti_Data, 0, 32);
369 break;
371 case MUIA_InnerRight:
372 data->mad_Flags |= MADF_INNERRIGHT;
373 data->mad_InnerRight = CLAMP((IPTR)tag->ti_Data, 0, 32);
374 break;
376 case MUIA_InnerTop:
377 data->mad_Flags |= MADF_INNERTOP;
378 data->mad_InnerTop = CLAMP((IPTR)tag->ti_Data, 0, 32);
379 break;
381 case MUIA_InputMode:
382 data->mad_InputMode = tag->ti_Data;
383 break;
385 case MUIA_MaxHeight:
386 data->mad_Flags |= MADF_MAXHEIGHT;
387 data->mad_HardHeight = tag->ti_Data;
388 break;
390 case MUIA_MaxWidth:
391 data->mad_Flags |= MADF_MAXWIDTH;
392 data->mad_HardWidth = tag->ti_Data;
393 break;
395 case MUIA_Selected:
396 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SELECTED);
397 break;
399 case MUIA_ShortHelp:
400 data->mad_ShortHelp = (STRPTR)tag->ti_Data;
401 break;
403 case MUIA_ShowMe:
404 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWME);
405 break;
407 case MUIA_ShowSelState:
408 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWSELSTATE);
409 break;
411 case MUIA_VertWeight:
412 data->mad_VertWeight = tag->ti_Data;
413 break;
415 case MUIA_Weight:
416 data->mad_HorizWeight = data->mad_VertWeight = tag->ti_Data;
417 break;
419 case MUIA_ContextMenu:
420 data->mad_ContextMenu = (Object*)tag->ti_Data;
421 break;
425 /* In Soliton MUIA_Selected was setted to MUIV_InputMode_RelVerify (=1) for MUIA_Input_Mode
426 ** MUIV_InputMode_RelVerify which is wrong of course but MUI seems to filter this out
427 ** so we have to do it also
429 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
431 if (data->mad_Flags & MADF_SELECTED)
432 D(bug("MUIA_Selected was set in OM_NEW, although being in MUIV_InputMode_RelVerify\n"));
433 data->mad_Flags &= ~MADF_SELECTED;
436 data->mad_ehn.ehn_Events = 0; /* Will be filled on demand */
437 data->mad_ehn.ehn_Priority = -5;
438 /* Please also send mui key events to us, no idea if mui handles this like this */
439 data->mad_ehn.ehn_Flags = MUI_EHF_ALWAYSKEYS;
440 data->mad_ehn.ehn_Object = obj;
441 data->mad_ehn.ehn_Class = cl;
443 data->mad_hiehn.ehn_Events = 0;
444 data->mad_hiehn.ehn_Priority = -10;
445 data->mad_hiehn.ehn_Flags = MUI_EHF_HANDLEINPUT;
446 data->mad_hiehn.ehn_Object = obj;
447 data->mad_hiehn.ehn_Class = 0;
449 return (IPTR)obj;
452 /**************************************************************************
453 OM_DISPOSE
454 **************************************************************************/
455 static IPTR Area__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
457 struct MUI_AreaData *data = INST_DATA(cl, obj);
459 zune_image_spec_free(data->mad_BackgroundSpec); /* Safe to call this with NULL */
461 return DoSuperMethodA(cl, obj, msg);
465 /**************************************************************************
466 OM_SET
467 **************************************************************************/
468 static IPTR Area__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
470 struct MUI_AreaData *data = INST_DATA(cl, obj);
471 struct TagItem *tags = msg->ops_AttrList;
472 struct TagItem *tag;
473 CONST_STRPTR old_backgroundspec;
475 int change_disable = 0; /* Has the disable state changed? */
477 while ((tag = NextTagItem((const struct TagItem **)&tags)) != NULL)
479 switch (tag->ti_Tag)
481 case MUIA_Background:
482 old_backgroundspec = data->mad_BackgroundSpec;
483 data->mad_BackgroundSpec = zune_image_spec_duplicate(tag->ti_Data);
484 if (!data->mad_BackgroundSpec)
486 /* Out of memory */
487 data->mad_BackgroundSpec = old_backgroundspec;
488 break;
491 data->mad_Flags |= MADF_OWNBG;
493 if (old_backgroundspec && (strcmp(data->mad_BackgroundSpec, old_backgroundspec) == 0))
495 /* New background does not differ from old one */
496 zune_image_spec_free(old_backgroundspec);
497 tag->ti_Tag = TAG_IGNORE;
498 break;
501 zune_image_spec_free(old_backgroundspec);
503 if (data->mad_Background)
505 if (_flags(obj) & MADF_CANDRAW)
507 zune_imspec_hide(data->mad_Background);
509 if (_flags(obj) & MADF_SETUP)
511 zune_imspec_cleanup(data->mad_Background);
512 data->mad_Background = NULL;
516 if (_flags(obj) & MADF_SETUP)
518 data->mad_Background =
519 zune_imspec_setup((IPTR)data->mad_BackgroundSpec,
520 muiRenderInfo(obj));
522 if (_flags(obj) & MADF_CANDRAW)
524 zune_imspec_show(data->mad_Background, obj);
526 MUI_Redraw(obj, MADF_DRAWOBJECT);
527 break;
529 case MUIA_FillArea:
530 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
531 break;
533 case MUIA_Frame:
534 /* this is not documented in MUI but it is possible,
535 and needed to suppress frame for external images */
536 data->mad_Frame = tag->ti_Data;
537 if (muiGlobalInfo(obj))
539 set_inner_sizes(obj, data);
540 set_title_sizes(obj, data);
542 break;
544 case MUIA_ControlChar:
545 if (_flags(obj) & MADF_SETUP)
546 cleanup_control_char(data, obj);
547 data->mad_ControlChar = tag->ti_Data;
548 if (_flags(obj) & MADF_SETUP)
549 setup_control_char(data, obj, cl);
550 break;
552 case MUIA_CycleChain:
553 // if (data->mad_InputMode == MUIV_InputMode_None)
554 // break;
556 if ((!(_flags(obj) & MADF_CYCLECHAIN) && tag->ti_Data)
557 || ((_flags(obj) & MADF_CYCLECHAIN) && !tag->ti_Data))
559 if (_flags(obj) & MADF_SETUP)
561 cleanup_control_char(data,obj);
562 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
563 setup_control_char(data,obj,cl);
564 } else _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
566 break;
568 case MUIA_Disabled:
569 if (tag->ti_Data)
571 if (!data->mad_DisableCount)
573 data->mad_DisableCount = 1;
574 change_disable = 1;
577 else
579 if (data->mad_DisableCount)
581 data->mad_DisableCount = 0;
582 change_disable = 1;
585 break;
587 case MUIA_NestedDisabled:
588 if (tag->ti_Data)
590 if (!data->mad_DisableCount) change_disable = 1;
591 data->mad_DisableCount++;
593 else
595 if (data->mad_DisableCount)
597 data->mad_DisableCount--;
598 if (!data->mad_DisableCount) change_disable = 1;
601 break;
604 case MUIA_HorizWeight:
605 data->mad_HorizWeight = tag->ti_Data;
606 break;
608 case MUIA_Pressed:
609 if (tag->ti_Data)
610 data->mad_Flags |= MADF_PRESSED;
611 else
612 data->mad_Flags &= ~MADF_PRESSED;
613 break;
615 case MUIA_ShortHelp:
616 data->mad_ShortHelp = (STRPTR)tag->ti_Data;
617 break;
619 case MUIA_ShowMe:
621 ULONG oldflags = data->mad_Flags;
622 int recalc = 0;
624 if (tag->ti_Data) data->mad_Flags |= MADF_SHOWME;
625 else data->mad_Flags &= ~MADF_SHOWME;
627 if (oldflags != data->mad_Flags)
629 if (!tag->ti_Data)
631 /* Should be made invisible, so send a MUIM_Hide and then a MUIM_Cleanup to the object if needed,
632 ** as objects with MUIA_ShowMe to false neighter get MUIM_Setup nor MUIM_Show */
633 if (_flags(obj)&MADF_CANDRAW)
635 DoHideMethod(obj);
636 recalc = 1;
638 #if 0 /* SHOWME affects only show/hide */
639 if (_flags(obj)&MADF_SETUP) DoMethod(obj,MUIM_Cleanup);
640 #endif
642 else
644 Object *parent = _parent(obj); /* Will be NULL if direct child of a window! */
645 if (parent)
647 #if 0 /* SHOWME affects only show/hide */
648 if (_flags(parent) & MADF_SETUP) DoSetupMethod(obj,muiRenderInfo(parent));
649 #endif
650 if (_flags(parent) & MADF_CANDRAW)
652 DoShowMethod(obj);
653 recalc = 1;
655 } else
657 /* Check if window is open... */
661 if (recalc && muiRenderInfo(obj)) /* If renderinfo is NULL _win(obj) does not work (crash) */
663 DoMethod(_win(obj), MUIM_Window_RecalcDisplay, (IPTR)_parent(obj));
667 break;
669 case MUIA_Selected:
670 /* D(bug(" Area_Set(%p) :
671 MUIA_Selected val=%ld sss=%d\n", obj, tag->ti_Data, !!(data->mad_Flags & MADF_SHOWSELSTATE)));
673 if (tag->ti_Data) data->mad_Flags |= MADF_SELECTED;
674 else data->mad_Flags &= ~MADF_SELECTED;
675 /* if (data->mad_Flags & MADF_SHOWSELSTATE) */
676 MUI_Redraw(obj, MADF_DRAWOBJECT);
677 /* else */
678 /* MUI_Redraw(obj, MADF_DRAWUPDATE); */
679 break;
681 case MUIA_Timer:
682 data->mad_Timeval = tag->ti_Data;
683 break;
685 case MUIA_VertWeight:
686 data->mad_VertWeight = tag->ti_Data;
687 break;
689 case MUIA_Draggable:
690 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
691 break;
693 case MUIA_Dropable:
694 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
695 break;
697 case MUIA_ContextMenu:
698 data->mad_ContextMenu = (Object*)tag->ti_Data;
699 break;
701 case MUIA_Font:
702 data->mad_FontPreset = tag->ti_Data;
703 break;
705 case MUIA_InputMode:
706 data->mad_InputMode = tag->ti_Data;
707 break;
712 if (change_disable)
714 MUI_Redraw(obj, MADF_DRAWOBJECT);
717 return DoSuperMethodA(cl, obj, (Msg)msg);
721 /**************************************************************************
722 OM_GET
723 **************************************************************************/
724 static IPTR Area__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
726 #define STORE *(msg->opg_Storage)
728 struct MUI_AreaData *data = INST_DATA(cl, obj);
730 switch(msg->opg_AttrID)
732 case MUIA_Background:
733 STORE = (IPTR)data->mad_Background;
734 return TRUE;
736 case MUIA_BottomEdge:
737 STORE = (IPTR)_bottom(obj);
738 return TRUE;
740 case MUIA_ControlChar:
741 STORE = data->mad_ControlChar;
742 return TRUE;
744 case MUIA_CycleChain:
745 STORE = ((data->mad_Flags & MADF_CYCLECHAIN) != 0);
746 return TRUE;
748 case MUIA_Disabled:
749 case MUIA_NestedDisabled:
750 STORE = !!data->mad_DisableCount; /* BOOLEAN */
751 return TRUE;
753 case MUIA_Font:
754 STORE = (IPTR)data->mad_FontPreset;
755 return TRUE;
757 case MUIA_Height:
758 STORE = (IPTR)_height(obj);
759 return TRUE;
761 case MUIA_HorizWeight:
762 STORE = (IPTR)data->mad_HorizWeight;
763 return TRUE;
765 case MUIA_InnerBottom:
766 STORE = (IPTR)data->mad_InnerBottom;
767 return TRUE;
769 case MUIA_InnerLeft:
770 STORE = (IPTR)data->mad_InnerLeft;
771 return TRUE;
773 case MUIA_InnerRight:
774 STORE = (IPTR)data->mad_InnerRight;
775 return TRUE;
777 case MUIA_InnerTop:
778 STORE = (IPTR)data->mad_InnerTop;
779 return TRUE;
781 case MUIA_LeftEdge:
782 STORE = (IPTR)_left(obj);
783 return TRUE;
785 case MUIA_Pressed:
786 STORE = !!(data->mad_Flags & MADF_PRESSED);
787 return TRUE;
789 case MUIA_RightEdge:
790 STORE = (IPTR)_right(obj);
791 return TRUE;
793 case MUIA_Selected:
794 STORE = !!(data->mad_Flags & MADF_SELECTED);
795 return TRUE;
797 case MUIA_ShortHelp:
798 STORE = (IPTR)data->mad_ShortHelp;
799 return TRUE;
801 case MUIA_ShowMe:
802 STORE = (data->mad_Flags & MADF_SHOWME);
803 return TRUE;
805 case MUIA_Timer:
806 return TRUE;
808 case MUIA_TopEdge:
809 STORE = (IPTR)_top(obj);
810 return TRUE;
812 case MUIA_VertWeight:
813 STORE = (IPTR)data->mad_VertWeight;
814 return TRUE;
816 case MUIA_Width:
817 STORE = (IPTR)_width(obj);
818 return TRUE;
820 case MUIA_Window:
821 if (muiAreaData(obj)->mad_RenderInfo)
822 STORE = (IPTR)_window(obj);
823 else
824 STORE = 0L;
825 return TRUE;
827 case MUIA_WindowObject:
828 if (muiAreaData(obj)->mad_RenderInfo)
829 STORE = (IPTR)_win(obj);
830 else
831 STORE = 0L;
832 return TRUE;
834 case MUIA_ContextMenu:
835 STORE = (IPTR)data->mad_ContextMenu;
836 return TRUE;
839 return(DoSuperMethodA(cl, obj, (Msg) msg));
840 #undef STORE
844 /**************************************************************************
845 MUIM_AskMinMax
846 **************************************************************************/
847 static IPTR Area__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
849 struct MUI_AreaData *data = INST_DATA(cl, obj);
850 const struct ZuneFrameGfx *zframe;
851 const struct MUI_FrameSpec_intern *frame;
852 struct MUI_FrameSpec_intern tempframe;
854 frame = get_intframe(obj, data, &tempframe);
855 zframe = zune_zframe_get(obj, frame);
857 area_update_msizes(obj, data, frame, zframe);
859 msg->MinMaxInfo->MinWidth = _subwidth(obj);
860 msg->MinMaxInfo->MinHeight = _subheight(obj);
862 msg->MinMaxInfo->MaxWidth = msg->MinMaxInfo->MinWidth;
863 msg->MinMaxInfo->MaxHeight = msg->MinMaxInfo->MinHeight;
864 msg->MinMaxInfo->DefWidth = msg->MinMaxInfo->MinWidth;
865 msg->MinMaxInfo->DefHeight = msg->MinMaxInfo->MinHeight;
867 /* D(bug("Area_AskMinMax 0x%lx (%s): Min=%ldx%ld Max=%ldx%ld Def=%ldx%ld\n", obj, data->mad_FrameTitle, */
868 /* msg->MinMaxInfo->MinWidth, msg->MinMaxInfo->MinHeight, */
869 /* msg->MinMaxInfo->MaxWidth, msg->MinMaxInfo->MaxHeight, */
870 /* msg->MinMaxInfo->DefWidth, msg->MinMaxInfo->DefHeight)); */
872 return TRUE;
876 * Called after MUIM_AskMinMax, to handle fixed and max sizes.
878 void __area_finish_minmax(Object *obj, struct MUI_MinMax *MinMaxInfo)
880 struct MUI_AreaData *data = muiAreaData(obj);
882 if ((_flags(obj) & MADF_FIXHEIGHT) && data->mad_HardHeight)
884 int h = data->mad_HardHeight + data->mad_subheight;
886 MinMaxInfo->MinHeight =
887 MinMaxInfo->DefHeight =
888 MinMaxInfo->MaxHeight = CLAMP(h, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
890 else if (data->mad_HardHeightTxt)
892 ZText *text;
894 if ((text = zune_text_new(NULL, data->mad_HardHeightTxt, ZTEXT_ARG_NONE, 0)))
896 zune_text_get_bounds(text, obj);
898 MinMaxInfo->MinHeight =
899 MinMaxInfo->DefHeight =
900 MinMaxInfo->MaxHeight =
901 CLAMP(text->height + data->mad_subheight, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
903 zune_text_destroy(text);
907 else if (_flags(obj) & MADF_MAXHEIGHT)
909 MinMaxInfo->MaxHeight =
910 CLAMP(data->mad_HardHeight + data->mad_subheight,
911 MinMaxInfo->MinHeight,
912 MinMaxInfo->MaxHeight);
915 if ((_flags(obj) & MADF_FIXWIDTH) && data->mad_HardWidth)
917 int w = data->mad_HardWidth + data->mad_subwidth;
919 MinMaxInfo->MinWidth =
920 MinMaxInfo->DefWidth =
921 MinMaxInfo->MaxWidth = CLAMP(w, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
923 else if (data->mad_HardWidthTxt)
925 ZText *text;
927 if ((text = zune_text_new(NULL, data->mad_HardWidthTxt, ZTEXT_ARG_NONE, 0)))
929 zune_text_get_bounds(text, obj);
931 MinMaxInfo->MinWidth =
932 MinMaxInfo->DefWidth =
933 MinMaxInfo->MaxWidth =
934 CLAMP(text->width + data->mad_subwidth, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
936 zune_text_destroy(text);
940 else if (_flags(obj) & MADF_MAXWIDTH)
942 MinMaxInfo->MaxWidth =
943 CLAMP(data->mad_HardWidth + data->mad_subwidth,
944 MinMaxInfo->MinWidth,
945 MinMaxInfo->MaxWidth);
948 /* Set minmax */
949 _minwidth(obj) = MinMaxInfo->MinWidth;
950 _minheight(obj) = MinMaxInfo->MinHeight;
951 _maxwidth(obj) = MinMaxInfo->MaxWidth;
952 _maxheight(obj) = MinMaxInfo->MaxHeight;
953 _defwidth(obj) = MinMaxInfo->DefWidth;
954 _defheight(obj) = MinMaxInfo->DefHeight;
957 /* <-- _top(obj) (frame title position depends of _top(obj))
958 * ====== Title ===== <-- frame_top (depends of title, if centered/above)
959 * | | <-- bgtop (depends of frame, bg always begins under frame)
960 * | |
961 * | |
962 * ================== <-- "bgbottom" and "frame_bottom" (frame overwrites bg (1))
964 * (1) : needed for phantom frame objects, where no frame overwrites bg, thus bg
965 * must go as far as theorical bottom frame border.
969 * draw object background if MADF_FILLAREA.
971 static void Area_Draw_handle_background(Object *obj, struct MUI_AreaData *data, ULONG flags,
972 const struct ZuneFrameGfx *zframe)
974 struct MUI_ImageSpec_intern *background;
975 struct Rectangle r, r2, rects[4];
976 int i, bgtop, bgleft, bgw, bgh, numrects;
978 if (!(data->mad_Flags & MADF_SELECTED) || !(data->mad_Flags & MADF_SHOWSELSTATE))
979 background = data->mad_Background;
980 else
981 background = data->mad_SelBack;
983 if (zframe->customframe)
985 bgtop = _top(obj) + data->mad_TitleHeightAbove;
987 else
989 bgtop = _top(obj) + data->mad_TitleHeightAbove + zframe->itop;
992 bgleft = _left(obj);
993 bgw = _width(obj);
994 bgh = _height(obj) - bgtop + _top(obj);
996 r.MinX = bgleft;
997 r.MinY = bgtop;
998 r.MaxX = bgleft + bgw - 1;
999 r.MaxY = bgtop + bgh - 1;
1001 if (data->mad_Flags & MADF_FILLAREA)
1003 rects[0] = r;
1004 numrects = 1;
1006 else
1008 /* MADF_FILLAREA not set. Only draw frame outside of
1009 innerbox (_mleft, _mtop, _mright, _mbottom):
1011 .............
1012 .***********.
1013 .*#########*.
1014 .*#########*.
1015 .***********.
1016 .............
1018 # = innerbox
1019 * = frame outside of innerbox
1020 . = object frame
1023 r2.MinX = _mleft(obj);
1024 r2.MinY = _mtop(obj);
1025 r2.MaxX = _mright(obj);
1026 r2.MaxY = _mbottom(obj);
1028 numrects = SubtractRectFromRect(&r, &r2, rects);
1031 for(i = 0; i < numrects; i++)
1033 if (!background)
1035 /* This will do the rest, TODO: on MADF_DRAWALL we not really need to draw this */
1036 /* D(bug(" Area_Draw(%p):%ld: MUIM_DrawBackground\n", obj, __LINE__)); */
1037 /* ATTENTION: This draws the clipped away regions of the area. Comment out and */
1038 /* check the result to see what I mean. */
1039 DoMethod(obj, MUIM_DrawBackground,
1040 rects[i].MinX, rects[i].MinY,
1041 rects[i].MaxX - rects[i].MinX + 1, rects[i].MaxY - rects[i].MinY + 1,
1042 rects[i].MinX, rects[i].MinY,
1043 data->mad_Flags
1046 else
1048 /* D(bug(" Area_Draw(%p):%ld: zune_imspec_draw\n", obj, __LINE__)); */
1049 zune_imspec_draw(background, data->mad_RenderInfo,
1050 rects[i].MinX, rects[i].MinY,
1051 rects[i].MaxX - rects[i].MinX + 1, rects[i].MaxY - rects[i].MinY + 1,
1052 rects[i].MinX, rects[i].MinY,
1058 if (muiGlobalInfo(obj)->mgi_Prefs->window_redraw == WINDOW_REDRAW_WITHOUT_CLEAR)
1060 if (bgtop > _top(obj) && !(flags & MADF_DRAWALL))
1062 /* Fill in the gap produced by the title with the background
1063 * of the parent object but only if
1064 * the upper object hasn't drawn it already
1065 * (which is the case if MADF_DRAWALL is setted) */
1066 DoMethod(
1067 obj, MUIM_DrawParentBackground, bgleft, _top(obj), bgw, bgtop - _top(obj),
1068 bgleft, _top(obj), data->mad_Flags
1076 * draw object frame + title if not MADF_FRAMEPHANTOM.
1078 static void Area_Draw_handle_frame(Object *obj, struct MUI_AreaData *data,
1079 const struct ZuneFrameGfx *zframe)
1081 APTR textdrawclip = (APTR)-1;
1082 struct Region *region;
1083 int tx;
1084 int tw, frame_height, frame_top;
1085 int addtw;
1086 struct TextExtent te;
1087 int nchars;
1088 int maxtxtwidth;
1090 /* no frametitle, just draw frame and return */
1091 if (!data->mad_FrameTitle)
1093 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), _top(obj), _width(obj), _height(obj), _left(obj), _top(obj), _width(obj), _height(obj));
1094 return;
1097 /* set clipping so that frame is not drawn behind title */
1099 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_color)
1101 case GROUP_TITLE_COLOR_OUTLINE:
1102 addtw = 2;
1103 break;
1104 case GROUP_TITLE_COLOR_3D:
1105 addtw = 1;
1106 break;
1107 default:
1108 addtw = 0;
1111 maxtxtwidth = _width(obj) - zframe->ileft - zframe->iright - 2 * 5 - addtw;
1113 nchars = TextFit(_rp(obj), data->mad_FrameTitle,
1114 strlen(data->mad_FrameTitle),
1115 &te, NULL, 1, maxtxtwidth, _font(obj)->tf_YSize);
1117 tw = te.te_Width + addtw;
1118 tx = _left(obj) + (_width(obj) - tw) / 2;
1120 frame_top = _top(obj) + data->mad_TitleHeightAbove;
1121 frame_height = _height(obj) - frame_top + _top(obj);
1123 if ((region = NewRegion()))
1125 struct Rectangle rect;
1126 int hspace = _font(obj)->tf_YSize / 8;
1128 rect.MinX = tx - hspace;
1129 rect.MinY = _top(obj);
1130 rect.MaxX = tx + tw - 1 + hspace;
1131 rect.MaxY = _top(obj) + _font(obj)->tf_YSize - 1; // frame is not thick enough anywhy
1132 OrRectRegion(region,&rect);
1134 rect.MinX = _left(obj);
1135 rect.MinY = _top(obj);
1136 rect.MaxX = _right(obj);
1137 rect.MaxY = _bottom(obj);
1138 XorRectRegion(region,&rect);
1140 textdrawclip = MUI_AddClipRegion(muiRenderInfo(obj),region);
1143 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), frame_top, _width(obj), frame_height, _left(obj), frame_top, _width(obj), frame_height);
1145 if (region && textdrawclip != (APTR)-1)
1147 MUI_RemoveClipRegion(muiRenderInfo(obj),textdrawclip);
1148 /* DisposeRegion(region);*/ /* sba: DisposeRegion happens in MUI_RemoveClipRegion, this seems wrong to me */
1151 /* Title text drawing */
1152 SetDrMd(_rp(obj), JAM1);
1153 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1154 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_3D)
1156 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline + 1);
1157 Text(_rp(obj), data->mad_FrameTitle, nchars);
1158 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1159 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1160 Text(_rp(obj), data->mad_FrameTitle, nchars);
1162 else if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_OUTLINE)
1164 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1166 tx += addtw / 2;
1167 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline);
1168 Text(_rp(obj), data->mad_FrameTitle, nchars);
1169 Move(_rp(obj), tx - 1, _top(obj) + _font(obj)->tf_Baseline);
1170 Text(_rp(obj), data->mad_FrameTitle, nchars);
1171 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline + 1);
1172 Text(_rp(obj), data->mad_FrameTitle, nchars);
1173 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline - 1);
1174 Text(_rp(obj), data->mad_FrameTitle, nchars);
1176 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1177 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1178 Text(_rp(obj), data->mad_FrameTitle, nchars);
1180 else
1182 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_HILITE)
1184 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1186 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1187 Text(_rp(obj), data->mad_FrameTitle, nchars);
1191 /**************************************************************************
1192 MUIM_Draw
1193 **************************************************************************/
1194 static IPTR Area__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
1196 struct MUI_AreaData *data = INST_DATA(cl, obj);
1197 const struct ZuneFrameGfx *zframe;
1198 struct TextFont *obj_font = NULL;
1199 ULONG flags = data->mad_Flags & MADF_DRAWFLAGS;
1201 //APTR areaclip;
1203 /* D(bug("Area_Draw(0x%lx) %ldx%ldx%ldx%ld\n",obj,_left(obj),_top(obj),_right(obj),_bottom(obj))); */
1204 /* D(bug(" Area_Draw(%p) msg=0x%08lx flags=0x%08lx\n",obj, msg->flags,_flags(obj))); */
1206 if (flags & MADF_DRAWALL)
1207 flags |= MADF_DRAWOBJECT;
1209 msg->flags = flags;
1210 data->mad_Flags &= ~MADF_DRAWFLAGS;
1212 if (!(flags & MADF_DRAWOBJECT))
1214 /* dont draw bg/frame, let subclass redraw content only
1216 return 0;
1220 /* Background cant be drawn without knowing anything about frame, thus some
1221 * calculations are made before background and frame drawing.
1224 /* on selected state, will get the opposite frame */
1225 const struct MUI_FrameSpec_intern *frame;
1226 struct MUI_FrameSpec_intern tempframe;
1227 int state;
1229 frame = get_intframe(obj, data, &tempframe);
1230 state = frame->state;
1231 if ((data->mad_Flags & MADF_SELECTED) && (data->mad_Flags & MADF_SHOWSELSTATE))
1232 state ^= 1;
1234 zframe = zune_zframe_get_with_state(
1235 obj, frame, state);
1236 /* update innersizes as there are frames which have different inner spacings in selected state */
1237 area_update_msizes(obj, data, frame, zframe);
1240 /* Background drawing */
1241 Area_Draw_handle_background(obj, data, msg->flags, zframe);
1243 obj_font = _font(obj);
1244 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1245 SetFont(_rp(obj), _font(obj));
1247 /* Frame and frametitle drawing */
1248 if (!(data->mad_Flags & MADF_FRAMEPHANTOM))
1250 Area_Draw_handle_frame(obj, data, zframe);
1253 _font(obj) = obj_font;
1254 SetFont(_rp(obj), _font(obj));
1256 /* MUI_RemoveClipping(muiRenderInfo(obj), areaclip);*/
1258 return TRUE;
1261 /**************************************************************************
1262 MUIM_DrawParentBackground
1263 **************************************************************************/
1264 static IPTR Area__MUIM_DrawParentBackground(struct IClass *cl, Object *obj, struct MUIP_DrawParentBackground *msg)
1266 struct MUI_AreaData *data = INST_DATA(cl, obj);
1267 Object *parent;
1269 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1270 return FALSE;
1272 get(obj, MUIA_Parent, &parent);
1273 if (parent)
1275 DoMethod(parent, MUIM_DrawBackground, msg->left, msg->top,
1276 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1278 else
1280 D(bug("Area_DrawParentBackground(%p) : MUIM_Window_DrawBackground\n", obj));
1281 DoMethod(_win(obj), MUIM_Window_DrawBackground, msg->left, msg->top,
1282 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1284 return TRUE;
1287 /**************************************************************************
1288 MUIM_DrawBackground
1289 **************************************************************************/
1290 static IPTR Area__MUIM_DrawBackground(struct IClass *cl, Object *obj, struct MUIP_DrawBackground *msg)
1292 struct MUI_AreaData *data = INST_DATA(cl, obj);
1293 struct MUI_ImageSpec_intern *bg;
1294 LONG state;
1296 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1297 return FALSE;
1299 if ((msg->flags & MADF_SELECTED) && (msg->flags & MADF_SHOWSELSTATE) && data->mad_SelBack)
1301 /* D(bug("Area_DrawBackground(%p): selected bg\n", obj)); */
1302 bg = data->mad_SelBack;
1303 state = IDS_SELECTED;
1305 else
1307 /* D(bug("Area_DrawBackground(%p): normal bg\n", obj)); */
1308 bg = data->mad_Background;
1309 state = IDS_NORMAL;
1312 const struct ZuneFrameGfx *zframe;
1313 const struct MUI_FrameSpec_intern *frame;
1314 struct MUI_FrameSpec_intern tempframe;
1316 if (!bg)
1318 Object *parent;
1319 get(obj, MUIA_Parent, &parent);
1321 D(bug("Area_DrawBackground(%p) : MUIM_DrawParentBackground\n",
1322 obj));
1324 return DoMethod(obj, MUIM_DrawParentBackground, msg->left, msg->top,
1325 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1328 frame = get_intframe(obj, data, &tempframe);
1330 int xstate = frame->state;
1331 if ((data->mad_Flags & MADF_SELECTED) && (data->mad_Flags & MADF_SHOWSELSTATE))
1332 xstate ^= 1;
1334 zframe = zune_zframe_get_with_state(obj, frame, xstate);
1336 if (zframe->customframe == NULL)
1338 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1339 zune_imspec_draw(bg, data->mad_RenderInfo,
1340 msg->left, msg->top, msg->width, msg->height,
1341 msg->xoffset, msg->yoffset, state);
1343 // if (!data->mad_FrameTitle)
1344 // {
1347 else
1349 if (zframe->noalpha == FALSE)
1351 zune_imspec_draw(bg, data->mad_RenderInfo,
1352 msg->left, msg->top, msg->width, msg->height,
1353 msg->xoffset, msg->yoffset, state);
1358 if (zframe->customframe)
1360 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), _top(obj), _width(obj), _height(obj), msg->left, msg->top, msg->width, msg->height);
1363 return TRUE;
1366 static IPTR Area__MUIM_DrawBackgroundBuffered(struct IClass *cl, Object *obj, struct MUIP_DrawBackgroundBuffered *msg)
1368 struct MUI_AreaData *data = INST_DATA(cl, obj);
1369 struct MUI_ImageSpec_intern *bg;
1370 LONG state;
1372 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1373 return FALSE;
1375 bg = data->mad_Background;
1377 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1378 zune_imspec_drawbuffered(bg, msg->rp, data->mad_RenderInfo,
1379 msg->left, msg->top, msg->width, msg->height,
1380 msg->xoffset+msg->left, msg->yoffset+msg->top, state, msg->left, msg->top, 1,
1381 _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));
1383 return TRUE;
1386 /* Perverting the EventHandlerNode structure to specify a shortcut.
1388 static void setup_control_char (struct MUI_AreaData *data, Object *obj, struct IClass *cl)
1390 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1392 data->mad_ccn.ehn_Events = data->mad_ControlChar;
1393 switch (data->mad_InputMode)
1395 case MUIV_InputMode_RelVerify:
1396 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1397 break;
1398 case MUIV_InputMode_Toggle:
1399 data->mad_ccn.ehn_Flags = MUIKEY_TOGGLE;
1400 break;
1401 case MUIV_InputMode_Immediate:
1402 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1403 break;
1405 data->mad_ccn.ehn_Priority = 0;
1406 data->mad_ccn.ehn_Object = obj;
1407 data->mad_ccn.ehn_Class = cl;
1408 DoMethod(_win(obj), MUIM_Window_AddControlCharHandler, (IPTR)&data->mad_ccn);
1413 static void cleanup_control_char (struct MUI_AreaData *data, Object *obj)
1415 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1417 DoMethod(_win(obj),
1418 MUIM_Window_RemControlCharHandler, (IPTR)&data->mad_ccn);
1422 static const struct MUI_FrameSpec_intern *get_intframe(
1423 Object *obj, struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore)
1425 if (data->mad_Frame > 100)
1427 /* Frame is spec in string format. Store it in tempstore and return a pointer
1428 to it. The caller should have such a temp variable on the stack. Don't want
1429 to add it to MUI_AreaData as that will increase mem usage of every object. */
1431 if (zune_frame_spec_to_intern((CONST_STRPTR)data->mad_Frame, tempstore))
1433 return tempstore;
1435 else
1437 return &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_None];
1440 else
1442 /* Frame is MUIV_Frame_<something> */
1443 return &muiGlobalInfo(obj)->mgi_Prefs->frames[data->mad_Frame];
1447 static void set_inner_sizes (Object *obj, struct MUI_AreaData *data)
1449 const struct MUI_FrameSpec_intern *frame;
1450 struct MUI_FrameSpec_intern tempframe;
1452 frame = get_intframe(obj, data, &tempframe);
1453 // Use frame inner spacing when not hardcoded
1454 if (!(data->mad_Flags & MADF_INNERLEFT))
1455 data->mad_InnerLeft = frame->innerLeft;
1456 if (!(data->mad_Flags & MADF_INNERTOP))
1457 data->mad_InnerTop = frame->innerTop;
1458 if (!(data->mad_Flags & MADF_INNERRIGHT))
1459 data->mad_InnerRight = frame->innerRight;
1460 if (!(data->mad_Flags & MADF_INNERBOTTOM))
1461 data->mad_InnerBottom = frame->innerBottom;
1465 static void set_title_sizes (Object *obj, struct MUI_AreaData *data)
1467 if (data->mad_FrameTitle)
1469 const struct ZuneFrameGfx *zframe;
1470 const struct MUI_FrameSpec_intern *frame;
1471 struct MUI_FrameSpec_intern tempframe;
1473 frame = get_intframe(obj, data, &tempframe);
1474 zframe = zune_zframe_get(obj, frame);
1476 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1478 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_position)
1480 case GROUP_TITLE_POSITION_ABOVE:
1481 data->mad_TitleHeightAbove = _font(obj)->tf_Baseline;
1482 break;
1483 case GROUP_TITLE_POSITION_CENTERED:
1484 data->mad_TitleHeightAbove = _font(obj)->tf_YSize / 2;
1485 break;
1488 data->mad_TitleHeightAdd = _font(obj)->tf_YSize - data->mad_InnerTop - zframe->itop;
1489 data->mad_TitleHeightBelow = data->mad_TitleHeightAdd - data->mad_TitleHeightAbove;
1494 /**************************************************************************
1495 First method to be called after an OM_NEW, it is the place
1496 for all initializations depending on the environment, but not
1497 on the gadget size/position. Matched by MUIM_Cleanup.
1498 **************************************************************************/
1499 static IPTR Area__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
1501 struct MUI_AreaData *data = INST_DATA(cl, obj);
1502 const struct ZuneFrameGfx *zframe;
1503 const struct MUI_FrameSpec_intern *frame;
1504 struct MUI_FrameSpec_intern tempframe;
1506 muiRenderInfo(obj) = msg->RenderInfo;
1508 if (data->mad_Frame)
1510 /* no frame allowed for root object (see Area.doc) */
1511 IPTR rootobj;
1512 get(_win(obj), MUIA_Window_RootObject, &rootobj);
1513 if ((Object*)rootobj == obj)
1515 data->mad_Frame = MUIV_Frame_None;
1516 data->mad_FrameTitle = NULL;
1520 set_inner_sizes(obj, data);
1521 set_title_sizes(obj, data);
1523 frame = get_intframe(obj, data, &tempframe);
1524 zframe = zune_zframe_get(obj, frame);
1526 area_update_msizes(obj, data, frame, zframe);
1528 if (data->mad_Flags & MADF_OWNBG)
1530 data->mad_Background = zune_imspec_setup((IPTR)data->mad_BackgroundSpec,
1531 muiRenderInfo(obj));
1534 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1535 (data->mad_InputMode != MUIV_InputMode_None))
1537 data->mad_SelBack = zune_imspec_setup(MUII_SelectedBack, muiRenderInfo(obj));
1540 if (data->mad_InputMode != MUIV_InputMode_None || data->mad_ContextMenu)
1542 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1543 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1546 /* Those are filled by RequestIDCMP() */
1547 if (data->mad_hiehn.ehn_Events)
1548 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_hiehn);
1550 setup_control_char (data, obj, cl);
1551 // setup_cycle_chain (data, obj);
1553 if (data->mad_FontPreset == MUIV_Font_Inherit)
1555 if (_parent(obj) != NULL && _parent(obj) != _win(obj))
1556 data->mad_Font = _font(_parent(obj));
1557 else
1559 D(bug("Area_Setup %p: getting normal font\n", obj));
1560 data->mad_Font = zune_font_get(obj, MUIV_Font_Normal);
1561 D(bug("Area_Setup %p: got normal font %p\n", obj, data->mad_Font));
1564 else
1566 data->mad_Font = zune_font_get(obj, data->mad_FontPreset);
1569 _flags(obj) |= MADF_SETUP;
1571 data->mad_Timer.ihn_Flags = MUIIHNF_TIMER;
1572 data->mad_Timer.ihn_Method = MUIM_Timer;
1573 data->mad_Timer.ihn_Object = obj;
1575 return TRUE;
1579 /**************************************************************************
1580 Called to match a MUIM_Setup, when environment is no more available.
1581 **************************************************************************/
1582 static IPTR Area__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
1584 struct MUI_AreaData *data = INST_DATA(cl, obj);
1586 _flags(obj) &= ~MADF_SETUP;
1588 // cleanup_cycle_chain (data, obj);
1589 cleanup_control_char (data, obj);
1591 if (data->mad_Timer.ihn_Millis)
1593 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1594 data->mad_Timer.ihn_Millis = 0;
1597 /* Remove the handler if it is added */
1598 if (data->mad_hiehn.ehn_Events)
1599 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_hiehn);
1601 /* Remove the event handler if it has been added */
1602 if (data->mad_ehn.ehn_Events)
1603 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1605 D(bug("Area cleanup %p active=%p\n", obj,
1606 (Object *)XGET(_win(obj), MUIA_Window_ActiveObject)));
1607 if (obj == (Object *)XGET(_win(obj), MUIA_Window_ActiveObject))
1609 D(bug("we are active, unset us\n"));
1610 set(_win(obj), MUIA_Window_ActiveObject, MUIV_Window_ActiveObject_None);
1613 /* It's save to call the following function with NULL */
1614 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1615 (data->mad_InputMode != MUIV_InputMode_None))
1617 zune_imspec_cleanup(data->mad_SelBack);
1618 data->mad_SelBack = NULL;
1620 if (data->mad_Flags & MADF_OWNBG)
1622 zune_imspec_cleanup(data->mad_Background);
1623 data->mad_Background = NULL;
1626 muiRenderInfo(obj) = NULL;
1628 return TRUE;
1632 /**************************************************************************
1633 Called after the window is open and the area layouted, but before
1634 any drawing. Matched by one MUIM_Hide.
1635 Good place to init things depending on gadget size/position.
1636 **************************************************************************/
1637 static IPTR Area__MUIM_Show(struct IClass *cl, Object *obj, struct MUIP_Show *msg)
1639 struct MUI_AreaData *data = INST_DATA(cl, obj);
1641 zune_imspec_show(data->mad_Background, obj);
1643 if (data->mad_Flags & MADF_SHOWSELSTATE
1644 && data->mad_InputMode != MUIV_InputMode_None)
1646 zune_imspec_show(data->mad_SelBack, obj);
1649 return TRUE;
1652 /**************************************************************************
1653 Called when the window is about to be closed, to match MUIM_Show.
1654 **************************************************************************/
1655 static IPTR Area__MUIM_Hide(struct IClass *cl, Object *obj, struct MUIP_Hide *msg)
1657 struct MUI_AreaData *data = INST_DATA(cl, obj);
1659 zune_imspec_hide(data->mad_Background);
1660 if (data->mad_Flags & MADF_SHOWSELSTATE
1661 && data->mad_InputMode != MUIV_InputMode_None)
1663 zune_imspec_hide(data->mad_SelBack);
1666 if (data->mad_ContextZMenu)
1668 zune_close_menu(data->mad_ContextZMenu);
1669 data->mad_ContextZMenu = NULL;
1672 return TRUE;
1675 /**************************************************************************
1676 Called when gadget activated
1677 **************************************************************************/
1678 static IPTR Area__MUIM_GoActive(struct IClass *cl, Object *obj, Msg msg)
1680 //bug("Area_GoActive %p\n", obj);
1681 if (_flags(obj) & MADF_CANDRAW)
1682 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1683 return TRUE;
1686 /**************************************************************************
1687 Called when gadget deactivated
1688 **************************************************************************/
1689 static IPTR Area__MUIM_GoInactive(struct IClass *cl, Object *obj, Msg msg)
1691 //bug("Area_GoInactive %p\n", obj);
1692 if (_flags(obj) & MADF_CANDRAW)
1693 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1694 return TRUE;
1697 /**************************************************************************
1698 This one or derived methods wont be called if short help is
1699 not set in area instdata. So set this to a dummy val if overriding
1700 **************************************************************************/
1701 static IPTR Area__MUIM_CreateShortHelp(struct IClass *cl, Object *obj, struct MUIP_CreateShortHelp *msg)
1703 struct MUI_AreaData *data = INST_DATA(cl, obj);
1705 return (IPTR)data->mad_ShortHelp;
1708 /**************************************************************************
1710 **************************************************************************/
1711 static IPTR Area__MUIM_DeleteShortHelp(struct IClass *cl, Object *obj, struct MUIP_DeleteShortHelp *msg)
1713 return TRUE;
1716 /**************************************************************************
1718 **************************************************************************/
1719 static IPTR Area__MUIM_CreateBubble(struct IClass *cl, Object *obj, struct MUIP_CreateBubble *msg)
1721 return (IPTR)zune_bubble_create(obj, msg->x, msg->y, msg->txt, msg->flags);
1724 /**************************************************************************
1726 **************************************************************************/
1727 static IPTR Area__MUIM_DeleteBubble(struct IClass *cl, Object *obj, struct MUIP_DeleteBubble *msg)
1729 zune_bubble_delete(obj, msg->bubble);
1731 return TRUE;
1734 /* either lmb or press key */
1735 static void handle_press(struct IClass *cl, Object *obj)
1737 struct MUI_AreaData *data = INST_DATA(cl, obj);
1739 switch (data->mad_InputMode)
1741 case MUIV_InputMode_RelVerify:
1742 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
1743 if (!data->mad_Timer.ihn_Millis)
1745 data->mad_Timer.ihn_Millis = 300;
1746 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->mad_Timer);
1748 SetAttrs(obj, MUIA_Selected, TRUE, MUIA_Pressed, TRUE, TAG_DONE);
1749 break;
1751 case MUIV_InputMode_Immediate:
1753 IPTR selected;
1755 get(obj, MUIA_Selected, &selected);
1756 if (selected)
1758 /* D(bug("handle_press(%p) : nnset MUIA_Selected FALSE\n", obj)); */
1759 nnset(obj, MUIA_Selected, FALSE);
1761 /* D(bug("handle_press(%p) : set MUIA_Selected TRUE\n", obj)); */
1762 set(obj, MUIA_Selected, TRUE);
1763 /* D(bug("handle_press(%p) : done\n", obj)); */
1764 break;
1766 case MUIV_InputMode_Toggle:
1767 // although undocumented, MUI sets MUIA_Pressed too
1768 SetAttrs(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED),
1769 MUIA_Pressed, !(data->mad_Flags & MADF_PRESSED),
1770 TAG_DONE);
1771 break;
1775 /* either lmb or release key */
1776 static void handle_release(struct IClass *cl, Object *obj, int cancel)
1778 struct MUI_AreaData *data = INST_DATA(cl, obj);
1780 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1782 if (data->mad_Flags & MADF_SELECTED)
1784 if (cancel)
1785 nnset(obj, MUIA_Pressed, FALSE);
1786 else
1787 set(obj, MUIA_Pressed, FALSE);
1789 set(obj, MUIA_Selected, FALSE);
1793 if (data->mad_Timer.ihn_Millis)
1795 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1796 data->mad_Timer.ihn_Millis = 0;
1801 static IPTR event_button(Class *cl, Object *obj, struct IntuiMessage *imsg)
1803 struct MUI_AreaData *data = INST_DATA(cl, obj);
1804 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1805 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1807 switch (imsg->Code)
1809 case SELECTDOWN:
1810 if (data->mad_InputMode == MUIV_InputMode_None)
1811 break;
1813 if (in)
1815 // set(_win(obj), MUIA_Window_ActiveObject, obj);
1816 data->mad_ClickX = imsg->MouseX;
1817 data->mad_ClickY = imsg->MouseY;
1819 if ((data->mad_InputMode != MUIV_InputMode_Toggle) && (data->mad_Flags & MADF_SELECTED))
1820 break;
1821 nnset(obj,MUIA_Timer,0);
1822 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1824 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1825 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE | IDCMP_RAWKEY;
1826 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1828 handle_press(cl, obj);
1829 return MUI_EventHandlerRC_Eat;
1832 case SELECTUP:
1833 if (data->mad_InputMode == MUIV_InputMode_None)
1834 break;
1836 if (data->mad_ehn.ehn_Events != IDCMP_MOUSEBUTTONS)
1838 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1839 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1840 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1841 if (!in) nnset(obj, MUIA_Pressed, FALSE);
1842 handle_release(cl, obj, FALSE /*cancel*/ );
1843 return MUI_EventHandlerRC_Eat;
1845 break;
1847 case MENUDOWN:
1848 if (in && data->mad_ContextMenu)
1850 Object *menuobj = (Object*)DoMethod(obj, MUIM_ContextMenuBuild, imsg->MouseX, imsg->MouseY);
1851 if (menuobj)
1853 struct NewMenu *newmenu;
1855 /* stegerg: HACKME, CHECKME! The menu/menu item objs should automatically
1856 be connected (parentobject setup) without need for
1857 this, but they aren't. Because of how family class is and
1858 is used by other classes, I think!? */
1859 DoMethod(menuobj, MUIM_ConnectParent, obj);
1861 get(menuobj,MUIA_Menuitem_NewMenu,&newmenu);
1862 if (newmenu)
1864 if (data->mad_ContextZMenu) zune_close_menu(data->mad_ContextZMenu);
1865 data->mad_ContextZMenu = zune_open_menu(_window(obj),newmenu);
1868 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1869 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE;
1870 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1872 return MUI_EventHandlerRC_Eat;
1874 break;
1876 case MENUUP:
1877 if (data->mad_ContextZMenu)
1879 struct MenuItem *item = zune_leave_menu(data->mad_ContextZMenu);
1881 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1882 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1883 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1885 if (item)
1887 Object *itemobj = (Object*)GTMENUITEM_USERDATA(item);
1889 /* CHECKME: MUIA_MenuItem_Trigger should probably be set inside
1890 MUIM_ContextMenuChoice!? But there I only know about
1891 itemobj, not MenuItem itself! */
1892 if (item->Flags & CHECKIT)
1894 set(itemobj, MUIA_Menuitem_Checked, !!(item->Flags & CHECKED));
1896 } /* if (item->Flags & CHECKIT) */
1898 set(itemobj, MUIA_Menuitem_Trigger, item);
1900 DoMethod(obj, MUIM_ContextMenuChoice, itemobj);
1902 } /* if (item) */
1904 zune_close_menu(data->mad_ContextZMenu);
1905 data->mad_ContextZMenu = NULL;
1907 return MUI_EventHandlerRC_Eat;
1909 } /* if (data->mad_ContextZMenu) */
1910 break;
1913 return 0;
1916 static IPTR event_motion(Class *cl, Object *obj, struct IntuiMessage *imsg)
1918 struct MUI_AreaData *data = INST_DATA(cl, obj);
1920 if ((imsg->Qualifier & IEQUALIFIER_RBUTTON) && data->mad_ContextZMenu)
1922 zune_mouse_update(data->mad_ContextZMenu, 0);
1923 return MUI_EventHandlerRC_Eat;
1926 if (imsg->Qualifier & IEQUALIFIER_LEFTBUTTON)
1928 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1929 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1931 if (in)
1933 if ((data->mad_Flags & MADF_DRAGGABLE) && ((abs(data->mad_ClickX-imsg->MouseX) >= 3) || (abs(data->mad_ClickY-imsg->MouseY)>=3)))
1934 /* should be user configurable */
1936 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1937 set(obj, MUIA_Selected, FALSE);
1938 nnset(obj, MUIA_Pressed, FALSE);
1940 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1941 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1942 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1943 if (data->mad_Timer.ihn_Millis)
1945 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1946 data->mad_Timer.ihn_Millis = 0;
1949 DoMethod(obj,MUIM_DoDrag, data->mad_ClickX - _left(obj), data->mad_ClickY - _top(obj), 0);
1950 return MUI_EventHandlerRC_Eat;
1954 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1956 if (!in && (data->mad_Flags & MADF_SELECTED)) /* going out */
1958 set(obj, MUIA_Selected, FALSE);
1960 else if (in && !(data->mad_Flags & MADF_SELECTED)) /* going in */
1962 set(obj, MUIA_Selected, TRUE);
1966 return MUI_EventHandlerRC_Eat;
1969 /**************************************************************************
1971 **************************************************************************/
1972 static IPTR Area__MUIM_HandleEvent(struct IClass *cl, Object *obj, struct MUIP_HandleEvent *msg)
1974 struct MUI_AreaData *data = INST_DATA(cl, obj);
1976 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\n", obj, msg->imsg, msg->muikey);
1977 if (data->mad_DisableCount) return 0;
1978 if (data->mad_InputMode == MUIV_InputMode_None && !data->mad_ContextMenu) return 0;
1980 if (msg->muikey != MUIKEY_NONE)
1982 switch (msg->muikey)
1984 case MUIKEY_PRESS:
1985 if (data->mad_Flags & MADF_SELECTED)
1986 break;
1987 if (data->mad_ehn.ehn_Events)
1988 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1989 data->mad_ehn.ehn_Events |= IDCMP_RAWKEY;
1990 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1991 handle_press(cl, obj);
1992 return MUI_EventHandlerRC_Eat;
1994 case MUIKEY_TOGGLE:
1995 if (data->mad_InputMode == MUIV_InputMode_Toggle)
1996 set(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED));
1997 return MUI_EventHandlerRC_Eat;
1999 case MUIKEY_RELEASE:
2000 if (data->mad_ehn.ehn_Events)
2001 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
2002 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2003 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
2004 handle_release(cl, obj, FALSE /* cancel */);
2005 return MUI_EventHandlerRC_Eat;
2007 return 0;
2010 if (msg->imsg)
2012 switch (msg->imsg->Class)
2014 case IDCMP_MOUSEBUTTONS: return event_button(cl, obj, msg->imsg);
2015 case IDCMP_MOUSEMOVE: return event_motion(cl, obj, msg->imsg);
2016 case IDCMP_RAWKEY:
2018 unsigned char code;
2019 UWORD msg_code;
2020 /* Remove the up prefix as convert key does not convert a upkey event */
2021 msg_code = msg->imsg->Code;
2022 msg->imsg->Code &= ~IECODE_UP_PREFIX;
2023 code = ConvertKey(msg->imsg);
2024 msg->imsg->Code = msg_code;
2026 if (code != 0 && code == data->mad_ControlChar)
2028 if (msg->imsg->Code & IECODE_UP_PREFIX)
2030 msg->muikey = MUIKEY_RELEASE;
2032 else
2034 msg->muikey = MUIKEY_PRESS;
2036 msg->imsg = NULL;
2037 return Area__MUIM_HandleEvent(cl, obj, msg);
2040 if (msg->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
2042 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
2043 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2044 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
2045 handle_release(cl,obj, TRUE /*cancel */);
2047 return MUI_EventHandlerRC_Eat;
2049 break;
2052 return 0;
2055 /**************************************************************************
2057 **************************************************************************/
2058 static IPTR Area__MUIM_HandleInput(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg)
2060 /* Actually a dummy, but real MUI does handle here the input stuff which Zune
2061 ** has in Area_HandleEvent. For compatibility we should do this too
2063 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\b", obj, msg->imsg, msg->muikey);
2064 return 0;
2067 /**************************************************************************
2068 Trivial; custom classes may override this to get dynamic menus.
2069 **************************************************************************/
2070 static IPTR Area__MUIM_ContextMenuBuild(struct IClass *cl, Object *obj, struct MUIP_ContextMenuBuild *msg)
2072 struct MUI_AreaData *data = INST_DATA(cl, obj);
2073 return (IPTR)data->mad_ContextMenu; /* a Menustrip object */
2076 /**************************************************************************/
2077 static IPTR Area__MUIM_ContextMenuChoice(struct IClass *cl, Object *obj, struct MUIP_ContextMenuChoice *msg)
2079 set(obj, MUIA_ContextMenuTrigger, msg->item);
2080 return 0;
2084 /**************************************************************************
2085 MUIM_Export : to export an objects "contents" to a dataspace object.
2086 **************************************************************************/
2087 static IPTR Area__MUIM_Export(struct IClass *cl, Object *obj, struct MUIP_Export *msg)
2089 struct MUI_AreaData *data = INST_DATA(cl, obj);
2090 ULONG id;
2092 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2094 char selected = (data->mad_Flags & MADF_SELECTED)?1:0;
2095 DoMethod(msg->dataspace, MUIM_Dataspace_Add, (IPTR)&selected, sizeof(char),(IPTR)id);
2097 return 0;
2101 /**************************************************************************
2102 MUIM_Import : to import an objects "contents" from a dataspace object.
2103 **************************************************************************/
2104 static IPTR Area__MUIM_Import(struct IClass *cl, Object *obj, struct MUIP_Import *msg)
2106 ULONG id;
2108 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2110 char *selected = (char*)DoMethod(msg->dataspace, MUIM_Dataspace_Find, (IPTR)id);
2112 if (selected)
2113 set(obj, MUIA_Selected, *selected);
2115 return 0;
2118 /**************************************************************************
2119 MUIM_Timer
2120 **************************************************************************/
2121 static IPTR Area__MUIM_Timer(struct IClass *cl, Object *obj, Msg msg)
2123 struct MUI_AreaData *data = INST_DATA(cl, obj);
2124 if (data->mad_Timer.ihn_Millis)
2125 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
2126 data->mad_Timer.ihn_Millis = 50;
2127 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->mad_Timer);
2129 if (data->mad_Flags & MADF_SELECTED)
2130 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
2131 return 0;
2134 /**************************************************************************
2135 MUIM_DoDrag
2136 **************************************************************************/
2137 static IPTR Area__MUIM_DoDrag(struct IClass *cl, Object *obj, struct MUIP_DoDrag *msg)
2139 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2140 DoMethod(_win(obj), MUIM_Window_DragObject, (IPTR)obj, msg->touchx, msg->touchy, msg->flags);
2141 return 0;
2144 /**************************************************************************
2145 MUIM_CreateDragImage
2146 **************************************************************************/
2147 static IPTR Area__MUIM_CreateDragImage(struct IClass *cl, Object *obj, struct MUIP_CreateDragImage *msg)
2149 struct MUI_DragImage *img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage),MEMF_CLEAR);
2150 if (img)
2152 const struct ZuneFrameGfx *zframe;
2153 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap,BMA_DEPTH);
2155 zframe = zune_zframe_get(obj, &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Drag]);
2157 img->width = _width(obj) + zframe->ileft + zframe->iright;
2158 img->height = _height(obj) + zframe->itop + zframe->ibottom;
2160 if ((img->bm = AllocBitMap(img->width,img->height,depth,BMF_MINPLANES,_screen(obj)->RastPort.BitMap)))
2162 /* Render the stuff now */
2163 struct RastPort *rp_save = muiRenderInfo(obj)->mri_RastPort;
2164 struct RastPort temprp;
2165 InitRastPort(&temprp);
2166 temprp.BitMap = img->bm;
2167 ClipBlit(_rp(obj),_left(obj),_top(obj),&temprp,zframe->ileft,zframe->itop,_width(obj),_height(obj),0xc0);
2169 muiRenderInfo(obj)->mri_RastPort = &temprp;
2170 zframe->draw(zframe->customframe, muiRenderInfo(obj), 0, 0, img->width, img->height, 0, 0, img->width, img->height);
2171 muiRenderInfo(obj)->mri_RastPort = rp_save;
2173 DeinitRastPort(&temprp);
2176 img->touchx = msg->touchx;
2177 img->touchy = msg->touchy;
2178 img->flags = 0;
2180 return (IPTR)img;
2183 /**************************************************************************
2184 MUIM_DeleteDragImage
2185 **************************************************************************/
2186 static IPTR Area__MUIM_DeleteDragImage(struct IClass *cl, Object *obj, struct MUIP_DeleteDragImage *msg)
2188 if (msg->di)
2190 if (msg->di->bm) FreeBitMap(msg->di->bm);
2191 FreeVec(msg->di);
2193 return 0;
2196 /**************************************************************************
2197 MUIM_DragQueryExtended
2198 **************************************************************************/
2199 static IPTR Area__MUIM_DragQueryExtended(struct IClass *cl, Object *obj, struct MUIP_DragQueryExtended *msg)
2201 struct MUI_AreaData *data = INST_DATA(cl, obj);
2202 if (data->mad_Flags & MADF_DROPABLE)
2204 if (_left(obj) <= msg->x && msg->x <= _right(obj) && _top(obj) <= msg->y && msg->y <= _bottom(obj))
2206 if (DoMethod(obj,MUIM_DragQuery,(IPTR)msg->obj) == MUIV_DragQuery_Accept)
2207 return (IPTR)obj;
2210 return 0;
2213 /**************************************************************************
2214 MUIM_DragBegin
2215 **************************************************************************/
2216 static IPTR Area__MUIM_DragBegin(struct IClass *cl, Object *obj, struct MUIP_DragBegin *msg)
2218 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2219 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2220 return 0;
2223 /**************************************************************************
2224 MUIM_DragFinish
2225 **************************************************************************/
2226 static IPTR Area__MUIM_DragFinish(struct IClass *cl, Object *obj, struct MUIP_DragFinish *msg)
2228 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2229 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2230 return 0;
2235 * Calculates addleft, addtop, subwidth, subheight from current settings.
2236 * If frame phantom, ignore horizontal frame components.
2237 * Depends on inner sizes and frame
2239 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
2240 const struct MUI_FrameSpec_intern *frame,
2241 const struct ZuneFrameGfx *zframe)
2244 /* if (XGET(obj, MUIA_UserData) == 42) */
2245 /* { */
2246 /* D(bug("area_update_msizes(%p) : ileft=%ld itop=%ld\n", obj, zframe->ileft, zframe->itop)); */
2247 /* } */
2249 struct dt_frame_image *fi = zframe->customframe;
2251 if (fi != NULL)
2253 //UWORD w = fi->tile_left + fi->tile_right;
2254 //UWORD h = fi->tile_top + fi->tile_bottom;
2256 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2257 data->mad_subwidth = data->mad_addleft + data->mad_InnerRight + zframe->iright;
2258 data->mad_addtop = data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2259 data->mad_subheight = data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2261 else
2263 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2264 data->mad_subwidth = data->mad_addleft + data->mad_InnerRight + zframe->iright;
2265 data->mad_addtop = data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2266 data->mad_subheight = data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2269 if (data->mad_Flags & MADF_FRAMEPHANTOM)
2271 data->mad_addleft = 0;
2272 data->mad_subwidth = 0;
2275 // clamping ... maybe ?
2277 /* D(bug("area_update_msizes(%x,%d) => addleft/top=%d/%d, subwidth/height=%d/%d\n", */
2278 /* obj, data->mad_Frame, data->mad_addleft, data->mad_addtop, data->mad_subwidth, data->mad_subheight)); */
2281 /**************************************************************************
2282 MUIM_Area_UnknownDropDestination
2283 **************************************************************************/
2284 IPTR Area__MUIM_UnknownDropDestination(struct IClass *cl, Object *obj, struct MUIP_UnknownDropDestination *msg)
2287 return 0;
2290 /**************************************************************************
2291 MUIM_UpdateInnerSizes - Updates the innersizes of an object. You actually
2292 should only call this method if the dimensions of an object would not be
2293 affected, otherwise the results are unexpected
2294 **************************************************************************/
2295 static IPTR Area__MUIM_UpdateInnerSizes(struct IClass *cl, Object *obj, struct MUIP_UpdateInnerSizes *msg)
2297 struct MUI_AreaData *data = INST_DATA(cl, obj);
2298 const struct ZuneFrameGfx *zframe;
2299 const struct MUI_FrameSpec_intern *frame;
2300 struct MUI_FrameSpec_intern tempframe;
2302 if (_flags(obj) & MADF_SETUP)
2304 frame = get_intframe(obj, data, &tempframe);
2305 zframe = zune_zframe_get(obj, frame);
2306 area_update_msizes(obj, data, frame, zframe);
2308 return 1;
2311 static IPTR Area__MUIM_FindAreaObject(struct IClass *cl, Object *obj,
2312 struct MUIP_FindAreaObject *msg)
2314 if (msg->obj == obj)
2315 return (IPTR)obj;
2316 else
2317 return (IPTR)NULL;
2320 BOOPSI_DISPATCHER(IPTR, Area_Dispatcher, cl, obj, msg)
2322 switch (msg->MethodID)
2324 case OM_NEW: return Area__OM_NEW(cl, obj, (struct opSet *) msg);
2325 case OM_DISPOSE: return Area__OM_DISPOSE(cl, obj, msg);
2326 case OM_SET: return Area__OM_SET(cl, obj, (struct opSet *)msg);
2327 case OM_GET: return Area__OM_GET(cl, obj, (struct opGet *)msg);
2328 case MUIM_AskMinMax: return Area__MUIM_AskMinMax(cl, obj, (APTR)msg);
2329 case MUIM_Draw: return Area__MUIM_Draw(cl, obj, (APTR)msg);
2330 case MUIM_DrawBackground: return Area__MUIM_DrawBackground(cl, obj, (APTR)msg);
2331 case MUIM_DrawBackgroundBuffered: return Area__MUIM_DrawBackgroundBuffered(cl, obj, (APTR)msg);
2332 case MUIM_DrawParentBackground: return Area__MUIM_DrawParentBackground(cl, obj, (APTR)msg);
2333 case MUIM_Setup: return Area__MUIM_Setup(cl, obj, (APTR)msg);
2334 case MUIM_Cleanup: return Area__MUIM_Cleanup(cl, obj, (APTR)msg);
2335 case MUIM_Show: return Area__MUIM_Show(cl, obj, (APTR)msg);
2336 case MUIM_Hide: return Area__MUIM_Hide(cl, obj, (APTR)msg);
2337 case MUIM_GoActive: return Area__MUIM_GoActive(cl, obj, (APTR)msg);
2338 case MUIM_GoInactive: return Area__MUIM_GoInactive(cl, obj, (APTR)msg);
2339 case MUIM_Layout: return 1;
2340 case MUIM_CreateShortHelp: return Area__MUIM_CreateShortHelp(cl, obj, (APTR)msg);
2341 case MUIM_DeleteShortHelp: return Area__MUIM_DeleteShortHelp(cl, obj, (APTR)msg);
2342 case MUIM_CreateBubble: return Area__MUIM_CreateBubble(cl, obj, (APTR)msg);
2343 case MUIM_DeleteBubble: return Area__MUIM_DeleteBubble(cl, obj, (APTR)msg);
2344 case MUIM_HandleEvent: return Area__MUIM_HandleEvent(cl, obj, (APTR)msg);
2345 case MUIM_ContextMenuBuild: return Area__MUIM_ContextMenuBuild(cl, obj, (APTR)msg);
2346 case MUIM_ContextMenuChoice: return Area__MUIM_ContextMenuChoice(cl, obj, (APTR)msg);
2347 case MUIM_Timer: return Area__MUIM_Timer(cl,obj,msg);
2348 case MUIM_UpdateInnerSizes: return Area__MUIM_UpdateInnerSizes(cl,obj,(APTR)msg);
2349 case MUIM_DragQuery: return MUIV_DragQuery_Refuse;
2350 case MUIM_DragBegin: return Area__MUIM_DragBegin(cl,obj,(APTR)msg);
2351 case MUIM_DragDrop: return FALSE;
2352 case MUIM_UnknownDropDestination: return Area__MUIM_UnknownDropDestination(cl,obj,(APTR)msg);
2353 case MUIM_DragFinish: return Area__MUIM_DragFinish(cl,obj,(APTR)msg);
2354 case MUIM_DragReport: return MUIV_DragReport_Continue; /* or MUIV_DragReport_Abort? */
2355 case MUIM_DoDrag: return Area__MUIM_DoDrag(cl, obj, (APTR)msg);
2356 case MUIM_CreateDragImage: return Area__MUIM_CreateDragImage(cl, obj, (APTR)msg);
2357 case MUIM_DeleteDragImage: return Area__MUIM_DeleteDragImage(cl, obj, (APTR)msg);
2358 case MUIM_DragQueryExtended: return Area__MUIM_DragQueryExtended(cl, obj, (APTR)msg);
2359 case MUIM_HandleInput: return Area__MUIM_HandleInput(cl, obj, (APTR)msg);
2360 case MUIM_FindAreaObject: return Area__MUIM_FindAreaObject(cl, obj, (APTR)msg);
2362 case MUIM_Export: return Area__MUIM_Export(cl, obj, (APTR)msg);
2363 case MUIM_Import: return Area__MUIM_Import(cl, obj, (APTR)msg);
2366 return DoSuperMethodA(cl, obj, msg);
2368 BOOPSI_DISPATCHER_END
2372 * Class descriptor.
2374 const struct __MUIBuiltinClass _MUI_Area_desc = {
2375 MUIC_Area,
2376 MUIC_Notify,
2377 sizeof(struct MUI_AreaData),
2378 (void*)Area_Dispatcher