00001
00002
00003
00004
00005
00006
00007
00008 #include "lcconfig.h"
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 #include <stdarg.h>
00013 #include "lcstring.h"
00014 #include "screen.h"
00015 #include "geometry.h"
00016 #include "dialbox.h"
00017 #include "mouse.h"
00018 #include "lclib.h"
00019
00020 static Dialog_Box db_entry[MAX_DBOX_ENTRIES];
00021 static Dialog_Box * button[MAX_DBOX_ENTRIES];
00022 static Dialog_Box * line[MAX_DBOX_ENTRIES];
00023
00024 static Rect dialog_window;
00025 static Rect text_window;
00026
00027 static Rect db_rect[MAX_DBOX_ENTRIES];
00028
00029
00030
00031 static Mouse_Handle * main_handle;
00032 static Mouse_Handle * text_handle;
00033
00034 static int dbn;
00035 static int bn;
00036 static int ln;
00037
00038 static int db_longest_button;
00039 static int db_longest_line;
00040
00041 static int bs;
00042 static int bse;
00043
00044 static int color;
00045
00046 static short db_up = 0;
00047 static int db_return_value;
00048
00049 char * db_screen_buffer;
00050 char db_screen_fresh;
00051
00052
00053
00054
00055
00056
00057 void
00058 main_handler(int x, int y, int button)
00059 {
00060
00061 }
00062
00063 void
00064 text_handler(int x, int y, int button)
00065 {
00066 int i;
00067 for (i = 0; i < dbn; i++) {
00068 if (mouse_in_rect(&db_rect[i], x, y) && db_entry[i].retval)
00069 dialog_close(db_entry[i].retval);
00070 }
00071
00072
00073 }
00074
00075
00076
00077
00078
00079 void
00080 dialog_key_handler (int key)
00081 {
00082 int i;
00083
00084 if (key == 0)
00085 return;
00086
00087
00088
00089 if (key == 10 || key == 13 || key == 32)
00090 for (i = 0; i < dbn; i++)
00091 if (db_entry[i].type == 2) {
00092 dialog_close(db_entry[i].retval);
00093 return;
00094 }
00095 else
00096 for (i = 0; i < dbn; i++)
00097 if (key == db_entry[i].retval) {
00098 dialog_close(db_entry[i].retval);
00099 return;
00100 }
00101 }
00102
00103
00104 int
00105 dialog_box(int arg_color, int argc, ...)
00106 {
00107 va_list ap;
00108 int i;
00109 int db_last_button = -1;
00110 int key;
00111 char * working_str;
00112
00113
00114 if (db_up) {
00115 printf("Already have a dialog box on screen!\n");
00116 exit(-1);
00117 } else {
00118 db_up = 1;
00119 db_flag = 1;
00120 }
00121
00122 bn = 0; ln = 0; dbn = 0;
00123 db_longest_button = 0; db_longest_line = 0;
00124 bs = 0; bse = 0;
00125 color = arg_color;
00126 db_screen_fresh = 0;
00127
00128 va_start(ap, argc);
00129
00130
00131
00132
00133
00134 for (i = 0; i < argc; i++) {
00135
00136 if (dbn >= MAX_DBOX_ENTRIES) {
00137 fprintf(stderr,"Too many buttons in dialog_box!\n"
00138 "Tweak MAX_DBOX_ENTRIES\n");
00139 exit(212);
00140 }
00141
00142 db_entry[dbn].type = (short) va_arg(ap, int);
00143 db_entry[dbn].retval = (short) va_arg(ap, int);
00144
00145 if (db_entry[dbn].type == 0) {
00146
00147 char * newline;
00148 working_str = va_arg(ap, char *);
00149 do {
00150 newline = (char *)strchr(working_str,'\n');
00151 if (newline) {
00152 int linelen = newline - working_str;
00153 db_entry[dbn].text = (char *)lcalloc(1 + linelen);
00154 strncpy(db_entry[dbn].text,working_str,linelen);
00155 db_entry[dbn].text[linelen] = '\0';
00156 working_str = (newline + 1) != '\0' ? newline + 1 : NULL;
00157 } else {
00158 db_entry[dbn].text = (char *)lcalloc(1 + strlen(working_str));
00159 strncpy(db_entry[dbn].text,working_str,strlen(working_str));
00160 db_entry[dbn].text[strlen(working_str)] = '\0';
00161 working_str = NULL;
00162 }
00163
00164 db_entry[dbn].type = 0;
00165 db_entry[dbn].retval = 0;
00166
00167 db_rect[dbn].w = (strlen(db_entry[dbn].text) * CHAR_WIDTH);
00168 db_rect[dbn].h = CHAR_HEIGHT;
00169 if (db_rect[dbn].w > db_longest_line)
00170 db_longest_line = db_rect[dbn].w;
00171
00172 ln++;
00173 dbn++;
00174 } while ((working_str != NULL) && (strlen(working_str) >= 1));
00175 } else {
00176 db_entry[dbn].text = va_arg(ap, char *);
00177 db_rect[dbn].w = ((strlen(db_entry[dbn].text) * CHAR_WIDTH)
00178 + (BUTTON_BORDER * 2));
00179 db_rect[dbn].h = (CHAR_HEIGHT + (BUTTON_BORDER * 2));
00180
00181 db_longest_button += db_rect[dbn].w;
00182 bn++;
00183 dbn++;
00184 }
00185 }
00186
00187 va_end(ap);
00188
00189
00190 text_window.h =
00191 ((ln * (CHAR_HEIGHT + DB_V_SPACE)) + BUTTON_HEIGHT + DB_V_SPACE);
00192
00193 if ((db_longest_button + (bn * BUTTON_MIN_SPACING)) >
00194 (db_longest_line + LINE_MIN_SPACING)) {
00195 text_window.w = (db_longest_button + (bn * BUTTON_MIN_SPACING));
00196 } else {
00197 text_window.w = (db_longest_line + LINE_MIN_SPACING);
00198 }
00199
00200
00201
00202
00203 bs = (text_window.w - db_longest_button) / bn;
00204 bse = ((text_window.w - db_longest_line) % bn) / 2;
00205
00206
00207
00208 for (i = 0; i < dbn; i++)
00209 {
00210 if (db_entry[i].type) {
00211 if (db_last_button == -1)
00212 db_rect[i].x = ((bs + bse) / 2) - BUTTON_BORDER;
00213 else
00214 db_rect[i].x = ((db_rect[db_last_button].x
00215 + db_rect[db_last_button].w + bs)
00216 - BUTTON_BORDER);
00217
00218 db_rect[i].y = ((ln * (CHAR_HEIGHT + DB_V_SPACE) + DB_V_SPACE)
00219 - BUTTON_BORDER);
00220
00221 db_last_button = i;
00222 } else {
00223 db_rect[i].x = ((text_window.w - db_rect[i].w) / 2);
00224 db_rect[i].y = (i * (CHAR_HEIGHT + DB_V_SPACE));
00225 }
00226 }
00227
00228
00229
00230 dialog_window.w = (text_window.w + BORDER_SIZE*2);
00231 dialog_window.h = (text_window.h + BORDER_SIZE*2);
00232
00233 main_handle = mouse_register(&scr.client_win,&main_handler);
00234 text_handle = mouse_register(&text_window,&text_handler);
00235
00236 dialog_refresh();
00237
00238 db_return_value = 0;
00239
00240
00241
00242
00243 while (!db_return_value) {
00244 #ifndef LC_X11
00245 lc_usleep (1000);
00246 #endif
00247
00248 #ifdef LC_X11
00249 call_wait_event ();
00250 key = x_key_value;
00251 x_key_value = 0;
00252 #elif defined (WIN32)
00253 HandleMouse ();
00254 key = GetKeystroke ();
00255 #else
00256 mouse_update ();
00257 key = vga_getkey ();
00258 #endif
00259 if (key == 0) continue;
00260
00261 if (key == 10 || key == 13 || key == ' ')
00262 for (i = 0; i <= dbn; i++) {
00263 if (db_entry[i].type == 2) {
00264 dialog_close(db_entry[i].retval);
00265 break;
00266 }
00267 }
00268 else
00269 for (i = 0; i <= dbn; i++) {
00270 if (key == db_entry[i].retval) {
00271 dialog_close(key);
00272 break;
00273 }
00274 }
00275 }
00276 return (db_return_value);
00277 }
00278
00279
00280 void
00281 dialog_refresh(void)
00282 {
00283 int i;
00284 if (!db_up)
00285 return;
00286
00287
00288 dialog_window.x = (scr.client_w / 2) - (dialog_window.w / 2);
00289 dialog_window.y = (scr.client_h / 2) - (dialog_window.h / 2);
00290
00291 text_window.x = dialog_window.x + BORDER_SIZE;
00292 text_window.y = dialog_window.y + BORDER_SIZE;
00293
00294 hide_mouse();
00295
00296 if (screen_refreshing && db_screen_fresh) {
00297 free(db_screen_buffer);
00298 db_screen_fresh = 0;
00299 }
00300
00301 if (!db_screen_fresh) {
00302 db_screen_buffer = (char *)lcalloc(dialog_window.w * dialog_window.h);
00303 Fgl_getrect(&dialog_window,db_screen_buffer);
00304 db_screen_fresh = 1;
00305 };
00306
00307
00308
00309 draw_bezel(dialog_window,BORDER_SIZE,color);
00310
00311 Fgl_fillbox(text_window.x,text_window.y,text_window.w,text_window.h,color);
00312
00313 #ifdef USE_EXPANDED_FONT
00314 gl_setwritemode (WRITEMODE_MASKED | FONT_EXPANDED);
00315 #else
00316 Fgl_setfontcolors (color, TEXT_FG_COLOUR);
00317 #endif
00318
00319
00320 for (i = 0; i < dbn; i++)
00321 {
00322
00323 if (db_entry[i].type) {
00324 Fgl_fillbox(db_rect[i].x + text_window.x,
00325 db_rect[i].y + text_window.y,
00326 db_rect[i].w,
00327 db_rect[i].h,
00328 white(0));
00329 }
00330 Fgl_write(db_rect[i].x + text_window.x + BUTTON_BORDER,
00331 db_rect[i].y + text_window.y + BUTTON_BORDER,
00332 db_entry[i].text);
00333 }
00334
00335 #ifdef USE_EXPANDED_FONT
00336 gl_setwritemode (WRITEMODE_OVERWRITE | FONT_EXPANDED);
00337 #else
00338 Fgl_setfontcolors (TEXT_BG_COLOUR, TEXT_FG_COLOUR);
00339 #endif
00340
00341 redraw_mouse();
00342
00343 }
00344
00345
00346
00347
00348 void
00349 dialog_close(int return_value)
00350 {
00351 int i;
00352
00353 mouse_unregister(main_handle);
00354 mouse_unregister(text_handle);
00355 db_up = 0;
00356 db_return_value = return_value;
00357
00358 for (i = 0; i < dbn; i++)
00359 if (db_entry[i].type == DB_PARA)
00360 free(db_entry[i].text);
00361
00362 if (db_screen_fresh) {
00363 Fgl_putrect(&dialog_window,db_screen_buffer);
00364 free(db_screen_buffer);
00365 db_screen_fresh = 0;
00366 }
00367
00368 db_flag = 0;
00369 }
00370