1 2 #include <stdio.h> 3 #include <stdarg.h> 4 5 #include "SDL_FrameBuf.h" 6 #include "Mac_FontServ.h" 7 8 /* This is a class set for Macintosh-like dialogue boxes. :) */ 9 /* Sorta complex... */ 10 11 /* Defaults for various dialog classes */ 12 13 #define BUTTON_WIDTH 75 14 #define BUTTON_HEIGHT 19 15 16 #define BOX_WIDTH 170 17 #define BOX_HEIGHT 20 18 19 #define EXPAND_STEPS 50 20 21 class Mac_Dialog { 22 23 public: 24 Mac_Dialog(int x, int y); ~Mac_Dialog()25 virtual ~Mac_Dialog() { } 26 27 /* Input handling */ SetButtonPress(void (* new_button_callback)(int x,int y,int button,int * doneflag))28 virtual void SetButtonPress(void (*new_button_callback) 29 (int x, int y, int button, int *doneflag)) { 30 button_callback = new_button_callback; 31 } HandleButtonPress(int x,int y,int button,int * doneflag)32 virtual void HandleButtonPress(int x, int y, int button, 33 int *doneflag) { 34 if ( button_callback ) { 35 (*button_callback)(x, y, button, doneflag); 36 } 37 } SetKeyPress(void (* new_key_callback)(SDL_keysym key,int * doneflag))38 virtual void SetKeyPress(void (*new_key_callback) 39 (SDL_keysym key, int *doneflag)) { 40 key_callback = new_key_callback; 41 } HandleKeyPress(SDL_keysym key,int * doneflag)42 virtual void HandleKeyPress(SDL_keysym key, int *doneflag) { 43 if ( key_callback ) { 44 (*key_callback)(key, doneflag); 45 } 46 } 47 48 /* Display handling */ Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)49 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 50 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 51 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 52 X += Xoff; 53 Y += Yoff; 54 Screen = screen; 55 } Show(void)56 virtual void Show(void) { 57 } 58 EnableText(void)59 static void EnableText(void) { 60 if ( text_enabled++ == 0 ) { 61 SDL_EnableUNICODE(1); 62 } 63 } DisableText(void)64 static void DisableText(void) { 65 if ( --text_enabled == 0 ) { 66 SDL_EnableUNICODE(0); 67 } 68 } 69 70 /* Error message routine */ Error(void)71 virtual char *Error(void) { 72 return(errstr); 73 } 74 75 protected: 76 static int text_enabled; 77 FrameBuf *Screen; 78 int X, Y; 79 void (*button_callback)(int x, int y, int button, int *doneflag); 80 void (*key_callback)(SDL_keysym key, int *doneflag); 81 82 /* Utility routines for dialogs */ IsSensitive(SDL_Rect * area,int x,int y)83 int IsSensitive(SDL_Rect *area, int x, int y) { 84 if ( (y > area->y) && (y < (area->y+area->h)) && 85 (x > area->x) && (x < (area->x+area->w)) ) 86 return(1); 87 return(0); 88 } 89 90 /* Error message */ SetError(char * fmt,...)91 virtual void SetError(char *fmt, ...) { 92 va_list ap; 93 94 va_start(ap, fmt); 95 vsnprintf(errbuf, sizeof(errbuf), fmt, ap); 96 va_end(ap); 97 errstr = errbuf; 98 } 99 char *errstr; 100 char errbuf[1024]; 101 }; 102 103 104 /* The button callbacks should return 1 if they finish the dialog, 105 or 0 if they do not. 106 */ 107 108 class Mac_Button : public Mac_Dialog { 109 110 public: 111 Mac_Button(int x, int y, int width, int height, 112 char *text, MFont *font, FontServ *fontserv, 113 int (*callback)(void)); ~Mac_Button()114 virtual ~Mac_Button() { 115 SDL_FreeSurface(button); 116 } 117 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)118 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 119 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 120 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 121 /* Do the normal dialog mapping */ 122 Mac_Dialog::Map(Xoff, Yoff, screen, 123 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 124 125 /* Set up the button sensitivity */ 126 sensitive.x = X; 127 sensitive.y = Y; 128 sensitive.w = Width; 129 sensitive.h = Height; 130 131 /* Map the bitmap image */ 132 button->format->palette->colors[0].r = R_bg; 133 button->format->palette->colors[0].g = G_bg; 134 button->format->palette->colors[0].b = B_bg; 135 button->format->palette->colors[1].r = R_fg; 136 button->format->palette->colors[1].g = G_fg; 137 button->format->palette->colors[1].b = B_fg; 138 } Show(void)139 virtual void Show(void) { 140 Screen->QueueBlit(X, Y, button, NOCLIP); 141 } 142 HandleButtonPress(int x,int y,int button,int * doneflag)143 virtual void HandleButtonPress(int x, int y, int button, 144 int *doneflag) { 145 if ( IsSensitive(&sensitive, x, y) ) 146 ActivateButton(doneflag); 147 } 148 149 protected: 150 int Width, Height; 151 SDL_Surface *button; 152 SDL_Rect sensitive; 153 int (*Callback)(void); 154 Bevel_Button(SDL_Surface * image)155 virtual void Bevel_Button(SDL_Surface *image) { 156 Uint16 h; 157 Uint8 *image_bits; 158 159 image_bits = (Uint8 *)image->pixels; 160 161 /* Bevel upper corners */ 162 memset(image_bits+3, 0x01, image->w-6); 163 image_bits += image->pitch; 164 memset(image_bits+1, 0x01, 2); 165 memset(image_bits+image->w-3, 0x01, 2); 166 image_bits += image->pitch; 167 memset(image_bits+1, 0x01, 1); 168 memset(image_bits+image->w-2, 0x01, 1); 169 image_bits += image->pitch; 170 171 /* Draw sides */ 172 for ( h=3; h<(image->h-3); ++h ) { 173 image_bits[0] = 0x01; 174 image_bits[image->w-1] = 0x01; 175 image_bits += image->pitch; 176 } 177 178 /* Bevel bottom corners */ 179 memset(image_bits+1, 0x01, 1); 180 memset(image_bits+image->w-2, 0x01, 1); 181 image_bits += image->pitch; 182 memset(image_bits+1, 0x01, 2); 183 memset(image_bits+image->w-3, 0x01, 2); 184 image_bits += image->pitch; 185 memset(image_bits+3, 0x01, image->w-6); 186 } InvertImage(void)187 virtual void InvertImage(void) { 188 int i; 189 Uint8 *buf; 190 191 for ( i=button->h*button->pitch, buf=(Uint8 *)button->pixels; 192 i > 0; --i, ++buf ) { 193 *buf = !*buf; 194 } 195 } ActivateButton(int * doneflag)196 virtual void ActivateButton(int *doneflag) { 197 /* Flash the button */ 198 InvertImage(); 199 Show(); 200 Screen->Update(); 201 SDL_Delay(50); 202 InvertImage(); 203 Show(); 204 Screen->Update(); 205 /* Run the callback */ 206 if ( Callback ) 207 *doneflag = (*Callback)(); 208 else 209 *doneflag = 1; 210 } 211 }; 212 213 /* The only difference between this button and the Mac_Button is that 214 if <Return> is pressed, this button is activated. 215 */ 216 class Mac_DefaultButton : public Mac_Button { 217 218 public: 219 Mac_DefaultButton(int x, int y, int width, int height, 220 char *text, MFont *font, FontServ *fontserv, 221 int (*callback)(void)); ~Mac_DefaultButton()222 virtual ~Mac_DefaultButton() { } 223 HandleKeyPress(SDL_keysym key,int * doneflag)224 virtual void HandleKeyPress(SDL_keysym key, int *doneflag) { 225 if ( key.sym == SDLK_RETURN ) 226 ActivateButton(doneflag); 227 } 228 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)229 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 230 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 231 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 232 Mac_Button::Map(Xoff, Yoff, screen, 233 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 234 Fg = Screen->MapRGB(R_fg, G_fg, B_fg); 235 } Show(void)236 virtual void Show(void) { 237 int x, y, maxx, maxy; 238 239 /* Show the normal button */ 240 Mac_Button::Show(); 241 242 /* Show the thick edge */ 243 x = X-4; 244 maxx = x+4+Width+4-1; 245 y = Y-4; 246 maxy = y+4+Height+4-1; 247 248 Screen->DrawLine(x+5, y, maxx-5, y, Fg); 249 Screen->DrawLine(x+3, y+1, maxx-3, y+1, Fg); 250 Screen->DrawLine(x+2, y+2, maxx-2, y+2, Fg); 251 Screen->DrawLine(x+1, y+3, x+5, y+3, Fg); 252 Screen->DrawLine(maxx-5, y+3, maxx-1, y+3, Fg); 253 Screen->DrawLine(x+1, y+4, x+3, y+4, Fg); 254 Screen->DrawLine(maxx-3, y+4, maxx-1, y+4, Fg); 255 Screen->DrawLine(x, y+5, x+3, y+5, Fg); 256 Screen->DrawLine(maxx-3, y+5, maxx, y+5, Fg); 257 258 Screen->DrawLine(x, y+6, x, maxy-6, Fg); 259 Screen->DrawLine(maxx, y+6, maxx, maxy-6, Fg); 260 Screen->DrawLine(x+1, y+6, x+1, maxy-6, Fg); 261 Screen->DrawLine(maxx-1, y+6, maxx-1, maxy-6, Fg); 262 Screen->DrawLine(x+2, y+6, x+2, maxy-6, Fg); 263 Screen->DrawLine(maxx-2, y+6, maxx-2, maxy-6, Fg); 264 265 Screen->DrawLine(x, maxy-5, x+3, maxy-5, Fg); 266 Screen->DrawLine(maxx-3, maxy-5, maxx, maxy-5, Fg); 267 Screen->DrawLine(x+1, maxy-4, x+3, maxy-4, Fg); 268 Screen->DrawLine(maxx-3, maxy-4, maxx-1, maxy-4, Fg); 269 Screen->DrawLine(x+1, maxy-3, x+5, maxy-3, Fg); 270 Screen->DrawLine(maxx-5, maxy-3, maxx-1, maxy-3, Fg); 271 Screen->DrawLine(x+2, maxy-2, maxx-2, maxy-2, Fg); 272 Screen->DrawLine(x+3, maxy-1, maxx-3, maxy-1, Fg); 273 Screen->DrawLine(x+5, maxy, maxx-5, maxy, Fg); 274 } 275 276 protected: 277 Uint32 Fg; /* The foreground color of the dialog */ 278 279 }; 280 281 /* Class of checkboxes */ 282 283 #define CHECKBOX_SIZE 12 284 285 class Mac_CheckBox : public Mac_Dialog { 286 287 public: 288 Mac_CheckBox(int *toggle, int x, int y, char *text, 289 MFont *font, FontServ *fontserv); ~Mac_CheckBox()290 virtual ~Mac_CheckBox() { 291 if ( label ) { 292 Fontserv->FreeText(label); 293 } 294 } 295 HandleButtonPress(int x,int y,int button,int * doneflag)296 virtual void HandleButtonPress(int x, int y, int button, 297 int *doneflag) { 298 if ( IsSensitive(&sensitive, x, y) ) { 299 *checkval = !*checkval; 300 Check_Box(*checkval); 301 Screen->Update(); 302 } 303 } 304 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)305 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 306 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 307 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 308 /* Do the normal dialog mapping */ 309 Mac_Dialog::Map(Xoff, Yoff, screen, 310 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 311 312 /* Set up the checkbox sensitivity */ 313 sensitive.x = X; 314 sensitive.y = Y; 315 sensitive.w = CHECKBOX_SIZE; 316 sensitive.h = CHECKBOX_SIZE; 317 318 /* Get the screen colors */ 319 Fg = Screen->MapRGB(R_fg, G_fg, B_fg); 320 Bg = Screen->MapRGB(R_bg, G_bg, B_bg); 321 322 /* Map the checkbox text */ 323 label->format->palette->colors[1].r = R_fg; 324 label->format->palette->colors[1].g = G_fg; 325 label->format->palette->colors[1].b = B_fg; 326 } Show(void)327 virtual void Show(void) { 328 Screen->DrawRect(X, Y, CHECKBOX_SIZE, CHECKBOX_SIZE, Fg); 329 if ( label ) { 330 Screen->QueueBlit(X+CHECKBOX_SIZE+4, Y-2, label,NOCLIP); 331 } 332 Check_Box(*checkval); 333 } 334 335 private: 336 FontServ *Fontserv; 337 SDL_Surface *label; 338 Uint32 Fg, Bg; 339 int *checkval; 340 SDL_Rect sensitive; 341 Check_Box(int checked)342 void Check_Box(int checked) { 343 Uint32 color; 344 345 if ( checked ) 346 color = Fg; 347 else 348 color = Bg; 349 350 Screen->DrawLine(X, Y, 351 X+CHECKBOX_SIZE-1, Y+CHECKBOX_SIZE-1, color); 352 Screen->DrawLine(X, Y+CHECKBOX_SIZE-1, 353 X+CHECKBOX_SIZE-1, Y, color); 354 } 355 }; 356 357 /* Class of radio buttons */ 358 359 class Mac_RadioList : public Mac_Dialog { 360 361 public: 362 Mac_RadioList(int *variable, int x, int y, 363 MFont *font, FontServ *fontserv); ~Mac_RadioList()364 virtual ~Mac_RadioList() { 365 struct radio *radio, *old; 366 367 for ( radio=radio_list.next; radio; ) { 368 old = radio; 369 radio = radio->next; 370 if ( old->label ) 371 Fontserv->FreeText(old->label); 372 delete old; 373 } 374 } 375 HandleButtonPress(int x,int y,int button,int * doneflag)376 virtual void HandleButtonPress(int x, int y, int button, 377 int *doneflag) { 378 int n; 379 struct radio *radio, *oldradio; 380 381 oldradio = radio_list.next; 382 for (n=0, radio=radio_list.next; radio; radio=radio->next, ++n){ 383 if ( n == *radiovar ) { 384 oldradio = radio; 385 break; 386 } 387 } 388 for (n=0, radio=radio_list.next; radio; radio=radio->next, ++n){ 389 if ( IsSensitive(&radio->sensitive, x, y) ) { 390 Spot(oldradio->x, oldradio->y, Bg); 391 *radiovar = n; 392 Spot(radio->x, radio->y, Fg); 393 Screen->Update(); 394 } 395 } 396 } 397 Add_Radio(int x,int y,char * text)398 virtual void Add_Radio(int x, int y, char *text) { 399 struct radio *radio; 400 401 for ( radio=&radio_list; radio->next; radio=radio->next ) 402 /* Loop to end of radio box list */; 403 /* Which is ANSI C++? */ 404 #ifdef linux 405 radio->next = new struct Mac_RadioList::radio; 406 #else 407 radio->next = new struct radio; 408 #endif 409 radio = radio->next; 410 radio->label = Fontserv->TextImage(text, Font, 411 STYLE_NORM, 0, 0, 0); 412 radio->x = x; 413 radio->y = y; 414 radio->sensitive.x = x; 415 radio->sensitive.y = y; 416 radio->sensitive.w = 20+radio->label->w; 417 radio->sensitive.h = BOX_HEIGHT; 418 radio->next = NULL; 419 } 420 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)421 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 422 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 423 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 424 struct radio *radio; 425 426 /* Do the normal dialog mapping */ 427 Mac_Dialog::Map(Xoff, Yoff, screen, 428 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 429 430 /* Get the screen colors */ 431 Fg = Screen->MapRGB(R_fg, G_fg, B_fg); 432 Bg = Screen->MapRGB(R_bg, G_bg, B_bg); 433 434 /* Adjust sensitivity and map the radiobox text */ 435 for ( radio=radio_list.next; radio; radio=radio->next ) { 436 radio->x += Xoff; 437 radio->y += Yoff; 438 radio->sensitive.x += Xoff; 439 radio->sensitive.y += Yoff; 440 radio->label->format->palette->colors[1].r = R_fg; 441 radio->label->format->palette->colors[1].g = G_fg; 442 radio->label->format->palette->colors[1].b = B_fg; 443 } 444 } Show(void)445 virtual void Show(void) { 446 int n; 447 struct radio *radio; 448 449 for (n=0, radio=radio_list.next; radio; radio=radio->next, ++n){ 450 Circle(radio->x, radio->y); 451 if ( n == *radiovar ) { 452 Spot(radio->x, radio->y, Fg); 453 } 454 if ( radio->label ) { 455 Screen->QueueBlit(radio->x+21, radio->y+3, 456 radio->label, NOCLIP); 457 } 458 } 459 } 460 461 private: 462 FontServ *Fontserv; 463 MFont *Font; 464 Uint32 Fg, Bg; 465 int *radiovar; 466 struct radio { 467 SDL_Surface *label; 468 int x, y; 469 SDL_Rect sensitive; 470 struct radio *next; 471 } radio_list; 472 Circle(int x,int y)473 void Circle(int x, int y) { 474 x += 5; 475 y += 5; 476 Screen->DrawLine(x+4, y, x+7, y, Fg); 477 Screen->DrawLine(x+2, y+1, x+3, y+1, Fg); 478 Screen->DrawLine(x+8, y+1, x+9, y+1, Fg); 479 Screen->DrawLine(x+1, y+2, x+1, y+3, Fg); 480 Screen->DrawLine(x+10, y+2, x+10, y+3, Fg); 481 Screen->DrawLine(x, y+4, x, y+7, Fg); 482 Screen->DrawLine(x+11, y+4, x+11, y+7, Fg); 483 Screen->DrawLine(x+1, y+8, x+1, y+9, Fg); 484 Screen->DrawLine(x+10, y+8, x+10, y+9, Fg); 485 Screen->DrawLine(x+2, y+10, x+3, y+10, Fg); 486 Screen->DrawLine(x+8, y+10, x+9, y+10, Fg); 487 Screen->DrawLine(x+4, y+11, x+7, y+11, Fg); 488 } Spot(int x,int y,Uint32 color)489 void Spot(int x, int y, Uint32 color) 490 { 491 x += 8; 492 y += 8; 493 Screen->DrawLine(x+1, y, x+4, y, color); 494 ++y; 495 Screen->DrawLine(x, y, x+5, y, color); 496 ++y; 497 Screen->DrawLine(x, y, x+5, y, color); 498 ++y; 499 Screen->DrawLine(x, y, x+5, y, color); 500 ++y; 501 Screen->DrawLine(x, y, x+5, y, color); 502 ++y; 503 Screen->DrawLine(x+1, y, x+4, y, color); 504 } 505 }; 506 507 508 /* Class of text entry boxes */ 509 510 class Mac_TextEntry : public Mac_Dialog { 511 512 public: 513 Mac_TextEntry(int x, int y, MFont *font, FontServ *fontserv); ~Mac_TextEntry()514 virtual ~Mac_TextEntry() { 515 struct text_entry *entry, *old; 516 517 for ( entry=entry_list.next; entry; ) { 518 old = entry; 519 entry = entry->next; 520 if ( old->text ) 521 Fontserv->FreeText(old->text); 522 delete old; 523 } 524 DisableText(); 525 } 526 HandleButtonPress(int x,int y,int button,int * doneflag)527 virtual void HandleButtonPress(int x, int y, int button, 528 int *doneflag) { 529 struct text_entry *entry; 530 531 for ( entry=entry_list.next; entry; entry=entry->next ) { 532 if ( IsSensitive(&entry->sensitive, x, y) ) { 533 current->hilite = 0; 534 Update_Entry(current); 535 current = entry; 536 DrawCursor(current); 537 Screen->Update(); 538 } 539 } 540 } HandleKeyPress(SDL_keysym key,int * doneflag)541 virtual void HandleKeyPress(SDL_keysym key, int *doneflag) { 542 int n; 543 544 switch (key.sym) { 545 case SDLK_TAB: 546 current->hilite = 0; 547 Update_Entry(current); 548 if ( current->next ) 549 current=current->next; 550 else 551 current=entry_list.next; 552 current->hilite = 1; 553 Update_Entry(current); 554 break; 555 556 case SDLK_DELETE: 557 case SDLK_BACKSPACE: 558 if ( current->hilite ) { 559 *current->variable = '\0'; 560 current->hilite = 0; 561 } else if ( *current->variable ) { 562 n = strlen(current->variable); 563 current->variable[n-1] = '\0'; 564 } 565 Update_Entry(current); 566 DrawCursor(current); 567 break; 568 569 default: 570 if ( (current->end+Cwidth) > current->width ) 571 return; 572 if ( key.unicode ) { 573 current->hilite = 0; 574 n = strlen(current->variable); 575 current->variable[n] = (char)key.unicode; 576 current->variable[n+1] = '\0'; 577 Update_Entry(current); 578 DrawCursor(current); 579 } 580 break; 581 } 582 Screen->Update(); 583 } 584 Add_Entry(int x,int y,int width,int is_default,char * variable)585 virtual void Add_Entry(int x, int y, int width, int is_default, 586 char *variable) { 587 struct text_entry *entry; 588 589 for ( entry=&entry_list; entry->next; entry=entry->next ) 590 /* Loop to end of entry list */; 591 entry->next = new struct text_entry; 592 entry = entry->next; 593 594 entry->variable = variable; 595 if ( is_default ) { 596 current = entry; 597 entry->hilite = 1; 598 } else 599 entry->hilite = 0; 600 entry->x = x+3; 601 entry->y = y+3; 602 entry->width = width*Cwidth; 603 entry->height = Cheight; 604 entry->sensitive.x = x; 605 entry->sensitive.y = y; 606 entry->sensitive.w = 3+(width*Cwidth)+3; 607 entry->sensitive.h = 3+Cheight+3; 608 entry->text = NULL; 609 entry->next = NULL; 610 } 611 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)612 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 613 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 614 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 615 struct text_entry *entry; 616 617 /* Do the normal dialog mapping */ 618 Mac_Dialog::Map(Xoff, Yoff, screen, 619 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 620 621 /* Get the screen colors */ 622 foreground.r = R_fg; 623 foreground.g = G_fg; 624 foreground.b = B_fg; 625 background.r = R_bg; 626 background.g = G_bg; 627 background.b = B_bg; 628 Fg = Screen->MapRGB(R_fg, G_fg, B_fg); 629 Bg = Screen->MapRGB(R_bg, G_bg, B_bg); 630 631 /* Adjust sensitivity and map the radiobox text */ 632 for ( entry=entry_list.next; entry; entry=entry->next ) { 633 entry->x += Xoff; 634 entry->y += Yoff; 635 entry->sensitive.x += Xoff; 636 entry->sensitive.y += Yoff; 637 } 638 } Show(void)639 virtual void Show(void) { 640 struct text_entry *entry; 641 642 for ( entry=entry_list.next; entry; entry=entry->next ) { 643 Screen->DrawRect(entry->x-3, entry->y-3, 644 3+entry->width+3, 3+Cheight+3, Fg); 645 Update_Entry(entry); 646 } 647 } 648 649 private: 650 FontServ *Fontserv; 651 MFont *Font; 652 Uint32 Fg, Bg; 653 int Cwidth, Cheight; 654 SDL_Color foreground; 655 SDL_Color background; 656 657 struct text_entry { 658 SDL_Surface *text; 659 char *variable; 660 SDL_Rect sensitive; 661 int x, y; 662 int width, height; 663 int end; 664 int hilite; 665 struct text_entry *next; 666 } entry_list, *current; 667 668 Update_Entry(struct text_entry * entry)669 void Update_Entry(struct text_entry *entry) { 670 Uint32 clear; 671 672 /* Create the new entry text */ 673 if ( entry->text ) { 674 Fontserv->FreeText(entry->text); 675 } 676 if ( entry->hilite ) { 677 clear = Fg; 678 entry->text = Fontserv->TextImage(entry->variable, 679 Font, STYLE_NORM, background, foreground); 680 } else { 681 clear = Bg; 682 entry->text = Fontserv->TextImage(entry->variable, 683 Font, STYLE_NORM, foreground, background); 684 } 685 Screen->FillRect(entry->x, entry->y, 686 entry->width, entry->height, clear); 687 if ( entry->text ) { 688 entry->end = entry->text->w; 689 Screen->QueueBlit(entry->x, entry->y, entry->text, NOCLIP); 690 } else { 691 entry->end = 0; 692 } 693 } DrawCursor(struct text_entry * entry)694 void DrawCursor(struct text_entry *entry) { 695 Screen->DrawLine(entry->x+entry->end, entry->y, 696 entry->x+entry->end, entry->y+entry->height-1, Fg); 697 } 698 }; 699 700 701 /* Class of numeric entry boxes */ 702 703 class Mac_NumericEntry : public Mac_Dialog { 704 705 public: 706 Mac_NumericEntry(int x, int y, MFont *font, FontServ *fontserv); ~Mac_NumericEntry()707 virtual ~Mac_NumericEntry() { 708 struct numeric_entry *entry, *old; 709 710 for ( entry=entry_list.next; entry; ) { 711 old = entry; 712 entry = entry->next; 713 if ( old->text ) 714 Fontserv->FreeText(old->text); 715 delete old; 716 } 717 } 718 HandleButtonPress(int x,int y,int button,int * doneflag)719 virtual void HandleButtonPress(int x, int y, int button, 720 int *doneflag) { 721 struct numeric_entry *entry; 722 723 for ( entry=entry_list.next; entry; entry=entry->next ) { 724 if ( IsSensitive(&entry->sensitive, x, y) ) { 725 current->hilite = 0; 726 Update_Entry(current); 727 current = entry; 728 DrawCursor(current); 729 Screen->Update(); 730 } 731 } 732 } HandleKeyPress(SDL_keysym key,int * doneflag)733 virtual void HandleKeyPress(SDL_keysym key, int *doneflag) { 734 int n; 735 736 switch (key.sym) { 737 case SDLK_TAB: 738 current->hilite = 0; 739 Update_Entry(current); 740 if ( current->next ) 741 current=current->next; 742 else 743 current=entry_list.next; 744 current->hilite = 1; 745 Update_Entry(current); 746 break; 747 748 case SDLK_DELETE: 749 case SDLK_BACKSPACE: 750 if ( current->hilite ) { 751 *current->variable = 0; 752 current->hilite = 0; 753 } else 754 *current->variable /= 10; 755 Update_Entry(current); 756 DrawCursor(current); 757 break; 758 759 case SDLK_0: 760 case SDLK_1: 761 case SDLK_2: 762 case SDLK_3: 763 case SDLK_4: 764 case SDLK_5: 765 case SDLK_6: 766 case SDLK_7: 767 case SDLK_8: 768 case SDLK_9: 769 n = (key.sym-SDLK_0); 770 if ( (current->end+Cwidth) > current->width ) 771 return; 772 if ( current->hilite ) { 773 *current->variable = n; 774 current->hilite = 0; 775 } else { 776 *current->variable *= 10; 777 *current->variable += n; 778 } 779 Update_Entry(current); 780 DrawCursor(current); 781 break; 782 783 default: 784 break; 785 } 786 Screen->Update(); 787 } 788 Add_Entry(int x,int y,int width,int is_default,int * variable)789 virtual void Add_Entry(int x, int y, int width, int is_default, 790 int *variable) { 791 struct numeric_entry *entry; 792 793 for ( entry=&entry_list; entry->next; entry=entry->next ) 794 /* Loop to end of numeric entry list */; 795 entry->next = new struct numeric_entry; 796 entry = entry->next; 797 798 entry->variable = variable; 799 if ( is_default ) { 800 current = entry; 801 entry->hilite = 1; 802 } else 803 entry->hilite = 0; 804 entry->x = x+3; 805 entry->y = y+3; 806 entry->width = width*Cwidth; 807 entry->height = Cheight; 808 entry->sensitive.x = x; 809 entry->sensitive.y = y; 810 entry->sensitive.w = 3+(width*Cwidth)+3; 811 entry->sensitive.h = 3+Cheight+3; 812 entry->text = NULL; 813 entry->next = NULL; 814 } 815 Map(int Xoff,int Yoff,FrameBuf * screen,Uint8 R_bg,Uint8 G_bg,Uint8 B_bg,Uint8 R_fg,Uint8 G_fg,Uint8 B_fg)816 virtual void Map(int Xoff, int Yoff, FrameBuf *screen, 817 Uint8 R_bg, Uint8 G_bg, Uint8 B_bg, 818 Uint8 R_fg, Uint8 G_fg, Uint8 B_fg) { 819 struct numeric_entry *entry; 820 821 /* Do the normal dialog mapping */ 822 Mac_Dialog::Map(Xoff, Yoff, screen, 823 R_bg, G_bg, B_bg, R_fg, G_fg, B_fg); 824 825 /* Get the screen colors */ 826 foreground.r = R_fg; 827 foreground.g = G_fg; 828 foreground.b = B_fg; 829 background.r = R_bg; 830 background.g = G_bg; 831 background.b = B_bg; 832 Fg = Screen->MapRGB(R_fg, G_fg, B_fg); 833 Bg = Screen->MapRGB(R_bg, G_bg, B_bg); 834 835 /* Adjust sensitivity and map the radiobox text */ 836 for ( entry=entry_list.next; entry; entry=entry->next ) { 837 entry->x += Xoff; 838 entry->y += Yoff; 839 entry->sensitive.x += Xoff; 840 entry->sensitive.y += Yoff; 841 } 842 } Show(void)843 virtual void Show(void) { 844 struct numeric_entry *entry; 845 846 for ( entry=entry_list.next; entry; entry=entry->next ) { 847 Screen->DrawRect(entry->x-3, entry->y-3, 848 3+entry->width+3, 3+Cheight+3, Fg); 849 Update_Entry(entry); 850 } 851 } 852 853 private: 854 FontServ *Fontserv; 855 MFont *Font; 856 Uint32 Fg, Bg; 857 int Cwidth, Cheight; 858 SDL_Color foreground; 859 SDL_Color background; 860 861 struct numeric_entry { 862 SDL_Surface *text; 863 int *variable; 864 SDL_Rect sensitive; 865 int x, y; 866 int width, height; 867 int end; 868 int hilite; 869 struct numeric_entry *next; 870 } entry_list, *current; 871 872 Update_Entry(struct numeric_entry * entry)873 void Update_Entry(struct numeric_entry *entry) { 874 char buf[128]; 875 Uint32 clear; 876 877 /* Create the new entry text */ 878 if ( entry->text ) { 879 Fontserv->FreeText(entry->text); 880 } 881 snprintf(buf, sizeof(buf), "%d", *entry->variable); 882 883 if ( entry->hilite ) { 884 clear = Fg; 885 entry->text = Fontserv->TextImage(buf, 886 Font, STYLE_NORM, background, foreground); 887 } else { 888 clear = Bg; 889 entry->text = Fontserv->TextImage(buf, 890 Font, STYLE_NORM, foreground, background); 891 } 892 entry->end = entry->text->w; 893 Screen->FillRect(entry->x, entry->y, 894 entry->width, entry->height, clear); 895 Screen->QueueBlit(entry->x, entry->y, entry->text, NOCLIP); 896 } DrawCursor(struct numeric_entry * entry)897 void DrawCursor(struct numeric_entry *entry) { 898 Screen->DrawLine(entry->x+entry->end, entry->y, 899 entry->x+entry->end, entry->y+entry->height-1, Fg); 900 } 901 }; 902 903 904 /* Finally, the macintosh-like dialog class */ 905 906 class Maclike_Dialog { 907 908 public: 909 Maclike_Dialog(int x, int y, int width, int height, FrameBuf *screen); 910 ~Maclike_Dialog(); 911 912 void Add_Rectangle(int x, int y, int w, int h, Uint32 color); 913 void Add_Image(SDL_Surface *image, int x, int y); 914 void Add_Dialog(Mac_Dialog *dialog); 915 916 void Run(int expand_steps = 1); 917 918 private: 919 FrameBuf *Screen; 920 int X, Y; 921 int Width, Height; 922 923 struct rect_elem { 924 Sint16 x, y; 925 Uint16 w, h; 926 Uint32 color; 927 struct rect_elem *next; 928 } rect_list; 929 struct image_elem { 930 SDL_Surface *image; 931 int x, y; 932 struct image_elem *next; 933 } image_list; 934 struct dialog_elem { 935 Mac_Dialog *dialog; 936 struct dialog_elem *next; 937 } dialog_list; 938 }; 939