4 ** Copyright (C) 1993,94,95,96 Bernardo Innocenti
6 ** Parts of this code are:
8 ** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
11 ** Report status information for an operation in progress.
14 #include <intuition/intuition.h>
15 #include <intuition/gadgetclass.h>
16 #include <libraries/gadtools.h>
17 #include <libraries/asl.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/intuition.h>
22 #include <proto/gadtools.h>
23 #include <proto/graphics.h>
24 #include <proto/layers.h>
26 #include "XModulePriv.h"
51 /* Local functions prototypes */
53 static void ShowStats (struct Gadget *Gadget, LONG Value, LONG Max);
54 static void ProgressAbortClicked (void);
55 static void LogPostClose (void);
56 static LONG ProgressPreOpen (struct WinUserData *wud);
60 static UWORD LogLines = 0;
61 static UWORD ProgressOpenCount = 0;
63 static struct IntuiText ProgressIT = { 0 };
64 static BOOL ProgressAborting = FALSE;
68 static LONG ProgressArgs[] =
70 TEXT_KIND, NULL, 20, GTTX_Clipped, TRUE, TAG_DONE,
71 TEXT_KIND, NULL, 20, GTTX_Border, TRUE, TAG_DONE,
72 BUTTON_KIND, (LONG)ProgressAbortClicked, MSG_UNDERSCORE_ABORT_GAD, TAG_DONE,
78 static LONG LogArgs[] =
80 LISTVIEW_KIND, NULL, NULL, (LONG)&LogList, GTLV_ReadOnly, TRUE, TAG_DONE,
87 LONG ProgressWinTags[] =
89 XMWIN_LayoutArgs, (LONG)ProgressArgs,
90 XMWIN_GCount, Progress_CNT,
91 XMWIN_Title, MSG_PROGRESS_TITLE,
92 XMWIN_IDCMPFlags, BUTTONIDCMP|TEXTIDCMP|IDCMP_REFRESHWINDOW,
93 XMWIN_PostCloseFunc, (LONG)LogPostClose,
101 XMWIN_LayoutArgs, (LONG)LogArgs,
102 XMWIN_GCount, Log_CNT,
103 XMWIN_Title, MSG_LOG_TITLE,
104 XMWIN_WindowFlags, WFLG_CLOSEGADGET,
105 XMWIN_IDCMPFlags, LISTVIEWIDCMP|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW,
106 XMWIN_PreOpenFunc, (LONG)ProgressPreOpen,
112 GLOBALCALL void OpenProgressWindow (void)
115 if (ProgressOpenCount > 1) return;
119 NewWindow (WID_PROGRESS);
124 GLOBALCALL void CloseProgressWindow (void)
127 if (ProgressOpenCount) return;
131 MyCloseWindow (WDescr[WID_PROGRESS].Wud);
136 static LONG ProgressPreOpen (struct WinUserData *wud)
138 ProgressIT.FrontPen = DrawInfo->dri_Pens[FILLTEXTPEN] ? DrawInfo->dri_Pens[FILLTEXTPEN] : DrawInfo->dri_Pens[FILLPEN];
140 ProgressIT.DrawMode = (DrawInfo->dri_Pens[FILLPEN] == DrawInfo->dri_Pens[FILLTEXTPEN] || !DrawInfo->dri_Pens[FILLTEXTPEN]) ?
141 (JAM1 | COMPLEMENT) : (JAM1);
143 ProgressIT.ITextFont = wud->Attr;
150 static void LogPostClose (void)
152 /* Free ListView nodes */
153 while (!IsListEmpty(&LogList))
154 RemListViewNode (LogList.lh_Head);
160 GLOBALCALL void DisplayAction (ULONG msg)
162 /* Tell user what is happening in the Progress window. */
164 DisplayActionStr (STR(msg));
169 GLOBALCALL void DisplayActionStr (CONST_STRPTR str)
171 /* Tell user what is happening in the Progress window. */
173 struct WinUserData *wud;
175 if ((wud = WDescr[WID_PROGRESS].Wud) && wud->Win)
176 GT_SetGadgetAttrs (wud->Gadgets[GD_Action], wud->Win, NULL,
183 /* Tell user how are things going. Also check for abort */
184 GLOBALCALL LONG DisplayProgress (LONG Num, LONG Max)
186 struct WinUserData *wud;
188 if ((wud = WDescr[WID_PROGRESS].Wud) && wud->Win)
190 /* Check for CTRL-C Break */
191 if (SetSignal (0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
195 /* Check abort and resizing */
198 if (ProgressAborting)
200 ProgressAborting = FALSE;
206 struct Layer_Info *layerinfo;
209 /* Attempt to lock the LayerInfo associated with the
210 * screen where the Progress window resides in.
212 * We do this to prevent blocking the operation in progress
213 * when someone else (e.g. Intuition) is keeping the lock.
215 * Note that there is no AttemptLockLayerInfo() function
216 * and LockLayerInfo() will wait if the layer is already
217 * locked, which is exactly what we are trying to avoid.
219 * Our workaround is checking the LockLayersCount before
220 * locking the LayerInfo.
222 * TODO: Experiment with AttemptLockLayerRom().
225 /* Perhaps using Scr->LayerInfo would be the same */
226 layerinfo = wud->Win->RPort->Layer->LayerInfo;
229 if (!layerinfo->LockLayersCount)
233 LockLayerInfo (layerinfo);
236 g = wud->Gadgets[GD_Percent];
239 ShowStats (g, Num, Max);
241 /* Display progress string */
243 SPrintf (buf, STR(MSG_PERCENT_DONE), Num, Max, (Num * 100) / Max);
245 ProgressIT.IText = buf;
247 PrintIText (wud->Win->RPort, &ProgressIT,
248 g->LeftEdge + 2 + (g->Width - 4 - IntuiTextLength (&ProgressIT)) / 2,
249 g->TopEdge + 1 + (g->Height - 2 - wud->Win->RPort->TxHeight) / 2);
251 UnlockLayerInfo (layerinfo);
262 static void ShowStats (struct Gadget *Gadget, LONG Value, LONG Max)
264 /* Show the percentage bars. */
266 struct RastPort *RPort = WDescr[WID_PROGRESS].Wud->Win->RPort;
267 LONG MaxWidth = Gadget->Width - 4,
271 if (Max < 1) Max = 0;
272 if (Value > Max) Value = Max;
275 if((Width = (MaxWidth * Value) / Max) > 0)
277 if(Width != MaxWidth)
280 RectFill (RPort, Gadget->LeftEdge + 2 + Width - 1, Gadget->TopEdge + 1,
281 Gadget->LeftEdge + Gadget->Width - 3, Gadget->TopEdge + Gadget->Height - 2);
284 SetAPen (RPort, DrawInfo->dri_Pens[FILLPEN]);
285 RectFill (RPort,Gadget->LeftEdge + 2,Gadget->TopEdge + 1,
286 Gadget->LeftEdge + Width + 1, Gadget->TopEdge + Gadget->Height - 2);
291 RectFill (RPort, Gadget->LeftEdge + 2, Gadget->TopEdge + 1,
292 Gadget->LeftEdge + Gadget->Width - 3, Gadget->TopEdge + Gadget->Height - 2);
299 GLOBALCALL void ShowMessage (ULONG msg, ...)
301 /* Localized interface to ShowString(). */
303 ShowString (STR(msg), (LONG *)(&msg+1));
307 GLOBALCALL void ShowString (CONST_STRPTR s, LONG *args)
309 /* Formats a string and shows it to the user in the Log Window.
310 * If the Log Window can't be opened, this function will fall
311 * to ShowRequest() or to Printf().
314 struct WinUserData *wud;
318 if (StdOut) VPrintf ((STRPTR)s, args);
322 wud = WDescr[WID_LOG].Wud;
324 if (!wud || !wud->Win)
327 wud = WDescr[WID_LOG].Wud;
332 GT_SetGadgetAttrs (wud->Gadgets[GD_LogList], wud->Win, NULL,
338 RemListViewNode (LogList.lh_Head);
342 if (AddListViewNodeA (&LogList, s, args))
347 GT_SetGadgetAttrs (wud->Gadgets[GD_LogList], wud->Win, NULL,
348 GTLV_Labels, &LogList,
353 ShowRequestStr (s, NULL, args);
358 static void ProgressAbortClicked (void)
360 ProgressAborting = TRUE;