revert between 56095 -> 55830 in arch
[AROS.git] / workbench / system / Workbook / wbicon.c
blob281bff4a6fa4a34149f7d9c482b483eda579313e
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Workbook Icon Class
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <string.h>
12 #include <aros/debug.h>
14 #include <proto/icon.h>
15 #include <proto/intuition.h>
16 #include <proto/gadtools.h>
17 #include <proto/utility.h>
18 #include <proto/exec.h>
19 #include <proto/dos.h>
20 #include <proto/icon.h>
21 #include <proto/graphics.h>
22 #include <proto/workbench.h>
24 #include <intuition/cghooks.h>
26 #include "workbook_intern.h"
27 #include "classes.h"
29 struct wbIcon {
30 STRPTR File;
31 struct DiskObject *Icon;
32 STRPTR Label;
33 struct Screen *Screen;
35 struct timeval LastActive;
38 const struct TagItem wbIcon_DrawTags[] = {
39 { ICONDRAWA_Frameless, TRUE, },
40 { ICONDRAWA_Borderless, TRUE, },
41 { ICONDRAWA_EraseBackground, FALSE, },
42 { TAG_DONE },
45 void wbIcon_Update(Class *cl, Object *obj)
47 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
48 struct wbIcon *my = INST_DATA(cl, obj);
49 struct Rectangle rect;
50 UWORD w,h;
52 /* Update the parent's idea of how big we are
54 GetIconRectangleA(&my->Screen->RastPort, my->Icon, (STRPTR)my->Label, &rect, (struct TagItem *)wbIcon_DrawTags);
56 w = (rect.MaxX - rect.MinX) + 1;
57 h = (rect.MaxY - rect.MinY) + 1;
59 /* If the icon is outside of the bounds for this
60 * screen, ignore the position information
62 if ((my->Icon->do_CurrentX != NO_ICON_POSITION ||
63 my->Icon->do_CurrentY != NO_ICON_POSITION) && my->Screen) {
64 if ((my->Icon->do_CurrentX != NO_ICON_POSITION &&
65 (my->Icon->do_CurrentX < my->Screen->LeftEdge ||
66 (my->Icon->do_CurrentX > (my->Screen->LeftEdge + my->Screen->Width - w)))) ||
67 (my->Icon->do_CurrentY != NO_ICON_POSITION &&
68 (my->Icon->do_CurrentY < my->Screen->TopEdge ||
69 (my->Icon->do_CurrentY > (my->Screen->TopEdge + my->Screen->Height - h))))) {
70 my->Icon->do_CurrentY = NO_ICON_POSITION;
71 my->Icon->do_CurrentX = NO_ICON_POSITION;
75 D(bug("%s: %dx%d @%d,%d (%s)\n", my->File, (int)w, (int)h, (WORD)my->Icon->do_CurrentX, (WORD)my->Icon->do_CurrentY, my->Label));
76 SetAttrs(obj,
77 GA_Left, (my->Icon->do_CurrentX == NO_ICON_POSITION) ? ~0 : my->Icon->do_CurrentX,
78 GA_Top, (my->Icon->do_CurrentY == NO_ICON_POSITION) ? ~0 : my->Icon->do_CurrentY,
79 GA_Width, w,
80 GA_Height, h,
81 TAG_END);
84 // OM_NEW
85 static IPTR wbIconNew(Class *cl, Object *obj, struct opSet *ops)
87 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
88 struct wbIcon *my;
89 CONST_STRPTR file, label = "???";
91 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)ops);
92 if (obj == NULL)
93 return 0;
95 my = INST_DATA(cl, obj);
97 my->File = NULL;
98 my->Icon = (struct DiskObject *)GetTagData(WBIA_Icon, (IPTR)NULL, ops->ops_AttrList);
99 my->Screen = (struct Screen *)GetTagData(WBIA_Screen, (IPTR)NULL, ops->ops_AttrList);
100 if (my->Icon != NULL) {
101 if (my->Icon->do_Gadget.GadgetText != NULL &&
102 my->Icon->do_Gadget.GadgetText->IText != NULL)
103 label = my->Icon->do_Gadget.GadgetText->IText;
104 } else {
105 file = (CONST_STRPTR)GetTagData(WBIA_File, (IPTR)NULL, ops->ops_AttrList);
106 if (file == NULL)
107 goto error;
109 my->File = StrDup(file);
110 if (my->File == NULL)
111 goto error;
113 strcpy(my->File, file);
115 label = FilePart(my->File);
117 my->Icon = GetIconTags(my->File,
118 ICONGETA_Screen, my->Screen,
119 ICONGETA_FailIfUnavailable, FALSE,
120 TAG_END);
121 if (my->Icon == NULL)
122 goto error;
126 my->Label = StrDup((CONST_STRPTR)GetTagData(WBIA_Label, (IPTR)label, ops->ops_AttrList));
127 if (my->Label == NULL)
128 goto error;
130 wbIcon_Update(cl, obj);
132 return (IPTR)obj;
134 error:
135 if (my->File)
136 FreeVec(my->File);
137 DoSuperMethod(cl, obj, OM_DISPOSE);
138 return 0;
141 // OM_DISPOSE
142 static IPTR wbIconDispose(Class *cl, Object *obj, Msg msg)
144 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
145 struct wbIcon *my = INST_DATA(cl, obj);
146 #if 0
147 struct TagItem tags[] = {
148 { ICONPUTA_OnlyUpdatePosition, TRUE },
149 { TAG_END } };
151 /* If need be, update the on-disk Icon's position information */
152 PutIconTagList(my->File, my->Icon, tags);
153 #endif
155 /* If my->File is set, then we allocated it
156 * and my->Icon. Otherwise, Icon was passed in
157 * via WBIA_Icon, and its the caller's responsibility.
159 if (my->File) {
160 FreeVec(my->File);
161 if (my->Icon)
162 FreeDiskObject(my->Icon);
165 if (my->Label)
166 FreeVec(my->Label);
168 return DoSuperMethodA(cl, obj, msg);
171 // OM_GET
172 static IPTR wbIconGet(Class *cl, Object *obj, struct opGet *opg)
174 struct wbIcon *my = INST_DATA(cl, obj);
175 IPTR rc = TRUE;
177 switch (opg->opg_AttrID) {
178 case WBIA_File:
179 *(opg->opg_Storage) = (IPTR)my->File;
180 break;
181 case WBIA_Label:
182 *(opg->opg_Storage) = (IPTR)my->Label;
183 break;
184 default:
185 rc = DoSuperMethodA(cl, obj, (Msg)opg);
186 break;
189 return rc;
192 // GM_RENDER
193 static IPTR wbIconRender(Class *cl, Object *obj, struct gpRender *gpr)
195 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
196 struct wbIcon *my = INST_DATA(cl, obj);
197 struct RastPort *rp = gpr->gpr_RPort;
198 struct Window *win = gpr->gpr_GInfo->gi_Window;
199 struct Region *clip;
200 struct Gadget *gadget = (struct Gadget *)obj; /* Legal for 'gadgetclass' */
201 WORD x,y;
203 x = gadget->LeftEdge;
204 y = gadget->TopEdge;
206 /* Clip to the window for drawing */
207 clip = wbClipWindow(wb, win);
208 DrawIconStateA(rp, my->Icon, (STRPTR)my->Label, x, y,
209 (gadget->Flags & GFLG_SELECTED) ? TRUE : FALSE, (struct TagItem *)wbIcon_DrawTags);
210 wbUnclipWindow(wb, win, clip);
212 return 0;
215 // GM_GOACTIVE
216 static IPTR wbIconGoActive(Class *cl, Object *obj, struct gpInput *gpi)
218 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
219 struct wbIcon *my = INST_DATA(cl, obj);
220 struct Gadget *gadget = (struct Gadget *)obj;
221 BOOL dclicked;
222 struct Region *clip;
223 struct RastPort *rp;
225 if ((rp = ObtainGIRPort(gpi->gpi_GInfo))) {
226 gadget->Flags ^= GFLG_SELECTED;
227 /* Clip to the window for drawing */
228 clip = wbClipWindow(wb, gpi->gpi_GInfo->gi_Window);
229 DoMethod(obj, GM_RENDER, gpi->gpi_GInfo, rp, GREDRAW_TOGGLE);
230 wbUnclipWindow(wb, gpi->gpi_GInfo->gi_Window, clip);
231 ReleaseGIRPort(rp);
234 /* On a double-click, don't go 'active', just
235 * do the action.
237 dclicked = DoubleClick(my->LastActive.tv_secs,
238 my->LastActive.tv_micro,
239 gpi->gpi_IEvent->ie_TimeStamp.tv_secs,
240 gpi->gpi_IEvent->ie_TimeStamp.tv_micro);
242 my->LastActive = gpi->gpi_IEvent->ie_TimeStamp;
244 if (dclicked)
245 DoMethod(obj, WBIM_Open);
247 return GMR_MEACTIVE;
250 // GM_GOINACTIVE
251 static IPTR wbIconGoInactive(Class *cl, Object *obj, struct gpGoInactive *gpgi)
253 return GMR_NOREUSE;
256 // GM_HANDLEINPUT
257 static IPTR wbIconHandleInput(Class *cl, Object *obj, struct gpInput *gpi)
259 struct InputEvent *iev = gpi->gpi_IEvent;
261 if ((iev->ie_Class == IECLASS_RAWMOUSE) &&
262 (iev->ie_Code == SELECTUP))
263 return GMR_REUSE;
265 return GMR_MEACTIVE;
268 // WBIM_Open
269 static IPTR wbIconOpen(Class *cl, Object *obj, Msg msg)
271 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
272 struct wbIcon *my = INST_DATA(cl, obj);
274 struct TagItem tags[] = {
275 { NP_Seglist, (IPTR)wb->wb_OpenerSegList },
276 { NP_Arguments, (IPTR)my->File },
277 { NP_FreeSeglist, FALSE },
278 { TAG_END, 0 },
280 CreateNewProc(tags);
282 return TRUE;
285 // WBIM_Copy
286 static IPTR wbIconCopy(Class *cl, Object *obj, Msg msg)
288 return FALSE;
291 // WBIM_Rename
292 static IPTR wbIconRename(Class *cl, Object *obj, Msg msg)
294 return FALSE;
297 // WBIM_Info
298 static IPTR wbIconInfo(Class *cl, Object *obj, Msg msg)
300 struct WorkbookBase *wb = (APTR)cl->cl_UserData;
301 struct wbIcon *my = INST_DATA(cl, obj);
303 return WBInfo(BNULL, my->File, NULL);
306 // WBIM_Snapshot
307 static IPTR wbIconSnapshot(Class *cl, Object *obj, Msg msg)
309 return FALSE;
312 // WBIM_Unsnapshot
313 static IPTR wbIconUnsnapshot(Class *cl, Object *obj, Msg msg)
315 return FALSE;
318 // WBIM_Leave_Out
319 static IPTR wbIconLeaveOut(Class *cl, Object *obj, Msg msg)
321 return FALSE;
324 // WBIM_Put_Away
325 static IPTR wbIconPutAway(Class *cl, Object *obj, Msg msg)
327 return FALSE;
330 // WBIM_Delete
331 static IPTR wbIconDelete(Class *cl, Object *obj, Msg msg)
333 return FALSE;
336 // WBIM_Format
337 static IPTR wbIconFormat(Class *cl, Object *obj, Msg msg)
339 return FALSE;
342 // WBIM_Empty_Trash
343 static IPTR wbIconEmptyTrash(Class *cl, Object *obj, Msg msg)
345 return FALSE;
348 static IPTR dispatcher(Class *cl, Object *obj, Msg msg)
350 IPTR rc = 0;
352 switch (msg->MethodID) {
353 case OM_NEW: rc = wbIconNew(cl, obj, (APTR)msg); break;
354 case OM_DISPOSE: rc = wbIconDispose(cl, obj, (APTR)msg); break;
355 case OM_GET: rc = wbIconGet(cl, obj, (APTR)msg); break;
356 case GM_RENDER: rc = wbIconRender(cl, obj, (APTR)msg); break;
357 case GM_GOACTIVE: rc = wbIconGoActive(cl, obj, (APTR)msg); break;
358 case GM_GOINACTIVE: rc = wbIconGoInactive(cl, obj, (APTR)msg); break;
359 case GM_HANDLEINPUT: rc = wbIconHandleInput(cl, obj, (APTR)msg); break;
360 case WBIM_Open: rc = wbIconOpen(cl, obj, msg); break;
361 case WBIM_Copy: rc = wbIconCopy(cl, obj, msg); break;
362 case WBIM_Rename: rc = wbIconRename(cl, obj, msg); break;
363 case WBIM_Info: rc = wbIconInfo(cl, obj, msg); break;
364 case WBIM_Snapshot: rc = wbIconSnapshot(cl, obj, msg); break;
365 case WBIM_Unsnapshot: rc = wbIconUnsnapshot(cl, obj, msg); break;
366 case WBIM_Leave_Out: rc = wbIconLeaveOut(cl, obj, msg); break;
367 case WBIM_Put_Away: rc = wbIconPutAway(cl, obj, msg); break;
368 case WBIM_Delete: rc = wbIconDelete(cl, obj, msg); break;
369 case WBIM_Format: rc = wbIconFormat(cl, obj, msg); break;
370 case WBIM_Empty_Trash: rc = wbIconEmptyTrash(cl, obj, msg); break;
371 default: rc = DoSuperMethodA(cl, obj, msg); break;
374 return rc;
377 Class *WBIcon_MakeClass(struct WorkbookBase *wb)
379 Class *cl;
381 cl = MakeClass( NULL, "gadgetclass", NULL,
382 sizeof(struct wbIcon),
384 if (cl != NULL) {
385 cl->cl_Dispatcher.h_Entry = HookEntry;
386 cl->cl_Dispatcher.h_SubEntry = dispatcher;
387 cl->cl_Dispatcher.h_Data = NULL;
388 cl->cl_UserData = (IPTR)wb;
391 return cl;