Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23.  
  24. #include "maths.h"
  25. #include "pstypes.h"
  26. #include "gr.h"
  27. #include "event.h"
  28. #include "ui.h"
  29. #include "mouse.h"
  30. #include "key.h"
  31. #include "u_mem.h"
  32.  
  33. #include "dxxsconf.h"
  34. #include "dsx-ns.h"
  35. #include <array>
  36. #include <memory>
  37.  
  38. namespace dcx {
  39.  
  40. // ts = total span
  41. // w = width of each item
  42. // n = number of items
  43. // i = item number (0 based)
  44. #define EVEN_DIVIDE(ts,w,n,i) ((((ts)-((w)*(n)))*((i)+1))/((n)+1))+((w)*(i))
  45.  
  46. #define BUTTON_HORZ_SPACING 20
  47. #define TEXT_EXTRA_HEIGHT 5
  48.  
  49. namespace {
  50.  
  51. struct messagebox
  52. {
  53.         const ui_messagebox_tie *button;
  54.         std::array<std::unique_ptr<UI_GADGET_BUTTON>, 10> button_g;
  55.         const char                              *text;
  56.         int                                     *choice;
  57.         int                                     width;
  58.         int                                     text_y;
  59.         int                                     line_y;
  60. };
  61.  
  62. }
  63.  
  64. static window_event_result messagebox_handler(UI_DIALOG *dlg,const d_event &event, messagebox *m)
  65. {
  66.         if (event.type == EVENT_UI_DIALOG_DRAW)
  67.         {
  68.                 const grs_font * temp_font;
  69.  
  70.                 gr_set_current_canvas(grd_curscreen->sc_canvas);
  71.                 auto &canvas = *grd_curcanv;
  72.                 temp_font = grd_curscreen->sc_canvas.cv_font;
  73.                
  74.                 if (grd_curscreen->get_screen_width() < 640) {
  75.                         grd_curscreen->sc_canvas.cv_font = ui_small_font.get();
  76.                 }
  77.                
  78.                 ui_dialog_set_current_canvas(dlg);
  79.                 ui_string_centered(canvas, m->width / 2, m->text_y, m->text);
  80.                
  81.                 Hline(canvas, 1, m->width - 2, m->line_y + 1, CGREY);
  82.                 Hline(canvas, 2, m->width - 2, m->line_y + 2, CBRIGHT);
  83.  
  84.                 grd_curscreen->sc_canvas.cv_font = temp_font;
  85.                
  86.                 return window_event_result::handled;
  87.         }
  88.  
  89.         for (uint_fast32_t i=0; i < m->button->count(); i++ )
  90.         {
  91.                 if (GADGET_PRESSED(m->button_g[i].get()))
  92.                 {
  93.                         *(m->choice) = i+1;
  94.                         return window_event_result::handled;
  95.                 }
  96.         }
  97.        
  98.         return window_event_result::ignored;
  99. }
  100.  
  101. int (ui_messagebox)( short xc, short yc, const char * text, const ui_messagebox_tie &Button )
  102. {
  103.         UI_DIALOG * dlg;
  104.         int avg, x, y;
  105.         int button_width, button_height, text_height, text_width;
  106.         int w, h;
  107.  
  108.         int choice;
  109.  
  110.         auto m = std::make_unique<messagebox>();
  111.         m->button = &Button;
  112.         m->text = text;
  113.         m->choice = &choice;
  114.  
  115.         button_width = button_height = 0;
  116.  
  117.         gr_set_current_canvas(grd_curscreen->sc_canvas);
  118.         auto &canvas = *grd_curcanv;
  119.         auto &cv_font = *canvas.cv_font;
  120.         w = grd_curscreen->get_screen_width();
  121.         h = grd_curscreen->get_screen_height();
  122.  
  123.         for (uint_fast32_t i=0; i < Button.count(); i++ )
  124.         {
  125.                 int width, height;
  126.                 ui_get_button_size(cv_font, Button.string(i), width, height);
  127.  
  128.                 if ( width > button_width ) button_width = width;
  129.                 if ( height > button_height ) button_height = height;
  130.         }
  131.  
  132.         gr_get_string_size(cv_font, text, &text_width, &text_height, &avg);
  133.  
  134.         unsigned width, height;
  135.         width = button_width*Button.count();
  136.         width += BUTTON_HORZ_SPACING*(Button.count()+1);
  137.         width ++;
  138.  
  139.         text_width += avg*6;
  140.         text_width += 10;
  141.  
  142.         if (text_width > width )
  143.                 width = text_width;
  144.  
  145.         height = text_height;
  146.         height += button_height;
  147.         height += 4*TEXT_EXTRA_HEIGHT;
  148.         height += 2;  // For line in middle
  149.  
  150.         {
  151.                 int mx, my, mz;
  152.                
  153.                 mouse_get_pos(&mx, &my, &mz);
  154.  
  155.                 if ( xc == -1 )
  156.                         xc = mx;
  157.  
  158.                 if ( yc == -1 )
  159.                         yc = my - button_height/2;
  160.         }
  161.  
  162.         if ( xc == -2 )
  163.                 xc = w/2;
  164.  
  165.         if ( yc == -2 )
  166.                 yc = h/2;
  167.  
  168.         x = xc - width/2;
  169.         y = yc - height/2;
  170.  
  171.         if (x < 0 ) {
  172.                 x = 0;
  173.         }
  174.  
  175.         if ( (x+width-1) >= w ) {
  176.                 x = w - width;
  177.         }
  178.  
  179.         if (y < 0 ) {
  180.                 y = 0;
  181.         }
  182.  
  183.         if ( (y+height-1) >= h ) {
  184.                 y = h - height;
  185.         }
  186.  
  187.         dlg = ui_create_dialog(x, y, width, height, static_cast<dialog_flags>(DF_DIALOG | DF_MODAL), messagebox_handler, m.get());
  188.  
  189.         y = TEXT_EXTRA_HEIGHT + text_height/2 - 1;
  190.  
  191.         m->width = width;
  192.         m->text_y = y;
  193.  
  194.         y = 2*TEXT_EXTRA_HEIGHT + text_height;
  195.        
  196.         m->line_y = y;
  197.  
  198.         y = height - TEXT_EXTRA_HEIGHT - button_height;
  199.  
  200.         for (uint_fast32_t i=0; i < Button.count(); i++ )
  201.         {
  202.  
  203.                 x = EVEN_DIVIDE(width,button_width,Button.count(),i);
  204.  
  205.                 m->button_g[i] = ui_add_gadget_button( dlg, x, y, button_width, button_height, Button.string(i), NULL );
  206.         }
  207.  
  208.         ui_gadget_calc_keys(dlg);
  209.  
  210.         //key_flush();
  211.  
  212.         dlg->keyboard_focus_gadget = m->button_g[0].get();
  213.  
  214.         choice = 0;
  215.  
  216.         while(choice==0)
  217.                 event_process();
  218.  
  219.         ui_close_dialog(dlg);
  220.  
  221.         return choice;
  222. }
  223.  
  224. }
  225.