1 /*
2  * wmslib/src/abut/help.c, part of wmslib library
3  * Copyright (C) 1994-1996 William Shubert.
4  * See "configure.h.in" for more copyright information.
5  */
6 
7 #include <math.h>
8 #include <wms.h>
9 #include <but/but.h>
10 #include <but/text.h>
11 #include <but/ctext.h>
12 #include <but/box.h>
13 #include <but/tblock.h>
14 #include <but/plain.h>
15 #include <but/textin.h>
16 #include <but/menu.h>
17 #include <but/canvas.h>
18 #ifdef  _ABUT_HELP_H_
19   Levelization Error.
20 #endif
21 #include "help.h"
22 
23 
24 /**********************************************************************
25  * Forward declarations
26  **********************************************************************/
27 static ButOut  unmap(ButWin *win);
28 static ButOut  map(ButWin *win);
29 static ButOut  resize(ButWin *win);
30 static ButOut  subWinResize(ButWin *win);
31 static ButOut  destroy(ButWin *win);
32 static ButOut  ok(But *but);
33 static ButOut  newMenuOpt(But *but, int value);
34 
35 
36 /**********************************************************************
37  * Functions
38  **********************************************************************/
abutHelp_create(Abut * a,const char * title,const char * menuTitle,const AbutHelpPage * pages,int numPages,int x,int y,int w,int h,int minW,int minH)39 AbutHelp  *abutHelp_create(Abut *a, const char *title, const char *menuTitle,
40 			   const AbutHelpPage *pages, int numPages,
41 			   int x, int y, int w, int h, int minW, int minH)  {
42   AbutHelp  *help;
43 
44   help = wms_malloc(sizeof(AbutHelp));
45   MAGIC_SET(help);
46   help->abut = a;
47   help->pages = pages;
48   help->maxMenuOpts = 0;
49   help->menuOpts = NULL;
50   help->curPage = 0;
51   help->numPages = 0;
52   help->win = butWin_create(help, a->env, title, w, h,
53 			    unmap, map, resize, destroy);
54   if (x != BUT_NOCHANGE)  {
55     butWin_setX(help->win, x);
56     butWin_setY(help->win, y);
57   }
58   if (minW != BUT_NOCHANGE)
59     butWin_setMinW(help->win, minW);
60   if (minH != BUT_NOCHANGE)
61     butWin_setMinH(help->win, minH);
62   butWin_setMaxW(help->win, 0);
63   butWin_setMaxH(help->win, 0);
64   butWin_activate(help->win);
65   help->bg = butBoxFilled_create(help->win, 0, BUT_DRAWABLE);
66   if (a->ulPixmap != None)
67     butBoxFilled_setPixmaps(help->bg, a->ulPixmap, a->lrPixmap, a->bgPixmap);
68   help->menu = NULL;
69   help->swin = abutSwin_create(help, help->win, 1, ABUTSWIN_LSLIDE,
70 			       subWinResize);
71   help->swinW = 0;
72   help->swinH = 0;
73   help->subBg = butPlain_create(help->swin->win, 0, BUT_DRAWABLE, BUT_BG);
74   help->ok = butCt_create(ok, NULL, help->win, 1,
75 			  BUT_DRAWABLE|BUT_PRESSABLE, a->ok);
76   help->numTextButs = 0;
77   help->maxTextButs = 0;
78   help->textButs = NULL;
79   help->destroyCallback = NULL;
80   help->packet = NULL;
81   abutHelp_newPages(help, menuTitle, pages, numPages);
82   return(help);
83 }
84 
85 
abutHelp_destroy(AbutHelp * help)86 void  abutHelp_destroy(AbutHelp *help)  {
87   assert(MAGIC(help));
88   butWin_destroy(help->win);
89 }
90 
91 
abutHelp_setDestroyCallback(AbutHelp * help,ButOut (* callback)(AbutHelp * help,void * packet),void * packet)92 void  abutHelp_setDestroyCallback(AbutHelp *help,
93 				  ButOut (*callback)(AbutHelp *help,
94 						     void *packet),
95 				  void *packet)  {
96   assert(MAGIC(help));
97   help->destroyCallback = callback;
98   help->packet = packet;
99 }
100 
101 
abutHelp_newPages(AbutHelp * help,const char * menuTitle,const AbutHelpPage * pages,int numPages)102 void  abutHelp_newPages(AbutHelp *help, const char *menuTitle,
103 			const AbutHelpPage *pages, int numPages)  {
104   int  i, bw;
105 
106   assert(MAGIC(help));
107   if (help->menu != NULL)  {
108     but_destroy(help->menu);
109     help->menu = NULL;
110   }
111   help->pages = pages;
112   if (help->maxMenuOpts < numPages + 1)  {
113     if (help->menuOpts != NULL)
114       wms_free(help->menuOpts);
115     help->maxMenuOpts = numPages + 1;
116     help->menuOpts = wms_malloc(help->maxMenuOpts * sizeof(const char *));
117   }
118   for (i = 0;  i < numPages;  ++i)  {
119     if (pages[i].pageName == NULL)
120       help->menuOpts[i] = BUTMENU_OLBREAK;
121     else
122       help->menuOpts[i] = pages[i].pageName;
123   }
124   help->menuOpts[i] = BUTMENU_OLEND;
125   help->menu = butMenu_downCreate(newMenuOpt, help, help->win, 1, 2,
126 				  BUT_DRAWABLE|BUT_PRESSABLE,
127 				  menuTitle, help->menuOpts, 0);
128   bw = butEnv_stdBw(butWin_env(help->win));
129   but_resize(help->menu, bw*2, bw*2,
130 	     butWin_w(help->win) - bw*4, help->abut->butH * 2);
131   abutHelp_newPage(help, 0);
132 }
133 
134 
abutHelp_newPage(AbutHelp * help,int pageNum)135 void  abutHelp_newPage(AbutHelp *help, int pageNum)  {
136   int  i;
137   int  numTbs;
138 
139   assert(MAGIC(help));
140   abutSwin_vMove(help->swin, 0);
141   help->curPage = pageNum;
142   for (i = 0;  i < help->numTextButs;  ++i)
143     but_destroy(help->textButs[i]);
144   for (numTbs = 0;  help->pages[pageNum].text[numTbs].text;  ++numTbs);
145   if (numTbs > help->maxTextButs)  {
146     if (help->textButs)
147       wms_free(help->textButs);
148     help->textButs = wms_malloc(numTbs * sizeof(But *));
149     help->maxTextButs = numTbs;
150   }
151   help->numTextButs = numTbs;
152   for (i = 0;  i < numTbs;  ++i)  {
153     help->textButs[i] = butTblock_create(help->swin->win, 1, BUT_DRAWABLE,
154 					 help->pages[pageNum].text[i].text,
155 					 help->pages[pageNum].text[i].align);
156     butTblock_setFont(help->textButs[i], help->pages[pageNum].text[i].fontNum);
157   }
158   help->swinW = 0;
159   subWinResize(help->swin->win);
160 }
161 
162 
unmap(ButWin * win)163 static ButOut  unmap(ButWin *win)  {
164   return(0);
165 }
166 
167 
map(ButWin * win)168 static ButOut  map(ButWin *win)  {
169   return(0);
170 }
171 
172 
resize(ButWin * win)173 static ButOut  resize(ButWin *win)  {
174   AbutHelp  *help = butWin_packet(win);
175   int  w, h;
176   int  bw = butEnv_stdBw(butWin_env(win));
177   int  physFontH = butEnv_fontH(butWin_env(win), 0);
178 
179   assert(MAGIC(help));
180   w = butWin_w(win);
181   h = butWin_h(win);
182   but_resize(help->bg, 0, 0, w, h);
183   but_resize(help->menu, bw*2, bw*2, w - bw*4, help->abut->butH * 2);
184   abutSwin_resize(help->swin, bw*2, bw*3 + help->abut->butH * 2,
185 		  w - bw*4, h - help->abut->butH * 3 - bw*6,
186 		  (physFontH * 3) / 2, physFontH);
187   butCan_resizeWin(help->swin->win, 0, butWin_w(help->swin->win), TRUE);
188   but_resize(help->ok, bw*2, h - help->abut->butH - bw*2,
189 	     w - bw*4, help->abut->butH);
190   return(0);
191 }
192 
193 
destroy(ButWin * win)194 static ButOut  destroy(ButWin *win)  {
195   AbutHelp  *help = butWin_packet(win);
196   ButOut  result = 0;
197 
198   assert(MAGIC(help));
199   if (help->destroyCallback)
200     result = help->destroyCallback(help, help->packet);
201   abutSwin_destroy(help->swin);
202   MAGIC_UNSET(help);
203   wms_free(help);
204   return(result);
205 }
206 
207 
subWinResize(ButWin * win)208 static ButOut  subWinResize(ButWin *win)  {
209   AbutSwin  *swin;
210   AbutHelp  *help;
211   int  i, bw, w, h, y;
212 
213   swin = butWin_packet(win);
214   assert(MAGIC(swin));
215   help = swin->packet;
216   assert(MAGIC(help));
217   w = butWin_w(win);
218   h = butWin_h(win);
219   but_resize(help->subBg, 0, 0, w, h);
220   help->swinW = w;
221   bw = butEnv_stdBw(butWin_env(win));
222   y = bw;
223   for (i = 0;  i < help->numTextButs;  ++i)
224     y += butTblock_resize(help->textButs[i], bw, y, w - bw*2);
225   if ((help->swinH != y + bw) ||
226       (help->swinH != h))  {
227     help->swinH = y + bw;
228     butCan_resizeWin(help->swin->win, help->swinW, help->swinH, TRUE);
229   }
230   return(0);
231 }
232 
233 
ok(But * but)234 static ButOut  ok(But *but)  {
235   butWin_destroy(but_win(but));
236   return(0);
237 }
238 
239 
newMenuOpt(But * but,int value)240 static ButOut  newMenuOpt(But *but, int value)  {
241   AbutHelp  *help = but_packet(but);
242 
243   assert(MAGIC(help));
244   if (value != help->curPage)  {
245     abutHelp_newPage(help, value);
246   }
247   return(0);
248 }
249