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 <stdlib.h>
  22.  
  23. #include "maths.h"
  24. #include "pstypes.h"
  25. #include "event.h"
  26. #include "gr.h"
  27. #include "ui.h"
  28. #include "mouse.h"
  29. #include "key.h"
  30. #include "timer.h"
  31.  
  32. namespace dcx {
  33.  
  34. static void gr_draw_sunken_border( short x1, short y1, short x2, short y2 );
  35.  
  36. void ui_draw_listbox( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox )
  37. {
  38.         int i, x, y, stop;
  39.         int w, h;
  40.  
  41.         //if (listbox->current_item<0)
  42.         //    listbox->current_item=0;
  43.         //if (listbox->current_item>=listbox->num_items)
  44.         //    listbox->current_item = listbox->num_items-1;
  45.         //if (listbox->first_item<0)
  46.         //   listbox->first_item=0;
  47.         //if (listbox->first_item>(listbox->num_items-listbox->num_items_displayed))
  48.         //    listbox->first_item=(listbox->num_items-listbox->num_items_displayed);
  49.  
  50. #if 0  //ndef OGL
  51.         if ((listbox->status!=1) && !listbox->moved )
  52.                 return;
  53. #endif
  54.  
  55.         gr_set_current_canvas( listbox->canvas );
  56.         auto &canvas = *grd_curcanv;
  57.        
  58.         w = listbox->width;
  59.         h = listbox->height;
  60.  
  61.         gr_rect(canvas, 0, 0, w-1, h-1, CBLACK);
  62.        
  63.         gr_draw_sunken_border( -2, -2, w+listbox->scrollbar->width+4, h+1);
  64.        
  65.         stop = listbox->first_item+listbox->num_items_displayed;
  66.         if (stop>listbox->num_items) stop = listbox->num_items;
  67.  
  68.         listbox->status = 0;
  69.  
  70.         x = y = 0;
  71.  
  72.         for (i= listbox->first_item; i< stop; i++ )
  73.         {
  74.                 const auto color = (i == listbox->current_item)
  75.                         ? CGREY
  76.                         : CBLACK;
  77.                 gr_rect(canvas, x, y, listbox->width - 1, y + h - 1, color);
  78.  
  79.                 if (i !=listbox->current_item)
  80.                 {
  81.                         if ((listbox->current_item == -1) && (dlg->keyboard_focus_gadget == listbox) && (i == listbox->first_item)  )
  82.                                 gr_set_fontcolor(canvas, CRED, -1);
  83.                         else
  84.                                 gr_set_fontcolor(canvas, CWHITE, -1);
  85.                 }
  86.                 else
  87.                 {
  88.                         if (dlg->keyboard_focus_gadget == listbox)
  89.                                 gr_set_fontcolor(canvas, CRED, -1);
  90.                         else
  91.                                 gr_set_fontcolor(canvas, CBLACK, -1);
  92.                 }
  93.                 gr_get_string_size(*canvas.cv_font, listbox->list[i], &w, &h, nullptr);
  94.                 gr_string(canvas, *canvas.cv_font, x + 2, y, listbox->list[i], w, h);
  95.                 y += h;
  96.         }
  97.  
  98.         if (stop < listbox->num_items_displayed-1 )
  99.         {
  100.                 gr_rect(canvas, x, y, listbox->width-1, listbox->height-1, CBLACK);
  101.         }
  102.  
  103.         //gr_ubox( -1, -1, listbox->width, listbox->height);
  104. }
  105.  
  106.  
  107. static void gr_draw_sunken_border( short x1, short y1, short x2, short y2 )
  108. {
  109.         const uint8_t cgrey = CGREY;
  110.         const uint8_t cbright = CBRIGHT;
  111.         Hline(*grd_curcanv, x1 - 1, x2 + 1, y1 - 1, cgrey);
  112.         Vline(*grd_curcanv, y1 - 1, y2 + 1, x1 - 1, cgrey);
  113.  
  114.         Hline(*grd_curcanv, x1 - 1, x2 + 1, y2 + 1, cbright);
  115.         Vline(*grd_curcanv, y1, y2 + 1, x2 + 1, cbright);
  116. }
  117.  
  118.  
  119. std::unique_ptr<UI_GADGET_LISTBOX> ui_add_gadget_listbox(UI_DIALOG *dlg, short x, short y, short w, short h, short numitems, char **list)
  120. {
  121.         int th, i;
  122.         gr_get_string_size(*grd_curcanv->cv_font, "*", nullptr, &th, nullptr);
  123.  
  124.         i = h / th;
  125.         h = i * th;
  126.  
  127.         std::unique_ptr<UI_GADGET_LISTBOX> listbox{ui_gadget_add<UI_GADGET_LISTBOX>( dlg, x, y, x+w-1, y+h-1 )};
  128.         listbox->list = list;
  129.         listbox->width = w;
  130.         listbox->height = h;
  131.         listbox->num_items = numitems;
  132.         listbox->num_items_displayed = i;
  133.         listbox->first_item = 0;
  134.         listbox->current_item = -1;
  135.         listbox->last_scrolled = 0;
  136.         listbox->textheight = th;
  137.         listbox->dragging = 0;
  138.         listbox->selected_item = -1;
  139.         listbox->moved = 1;
  140.         listbox->scrollbar = ui_add_gadget_scrollbar( dlg, x+w+3, y, 0, h, 0, numitems-i, 0, i );
  141.         listbox->scrollbar->parent = listbox.get();
  142.         return listbox;
  143. }
  144.  
  145. window_event_result ui_listbox_do( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox,const d_event &event )
  146. {
  147.         int mitem, oldfakepos, kf;
  148.         int keypress = 0;
  149.         if (event.type == EVENT_WINDOW_DRAW)
  150.         {
  151.                 ui_draw_listbox( dlg, listbox );
  152.                 return window_event_result::ignored;
  153.         }
  154.        
  155.         if (event.type == EVENT_KEY_COMMAND)
  156.                 keypress = event_key_get(event);
  157.        
  158.         listbox->selected_item = -1;
  159.  
  160.         listbox->moved = 0;
  161.  
  162.         if (listbox->num_items < 1 ) {
  163.                 listbox->current_item = -1;
  164.                 listbox->first_item = 0;
  165.                 listbox->old_current_item = listbox->current_item;
  166.                 listbox->old_first_item = listbox->first_item;
  167.                 //ui_draw_listbox( dlg, listbox );
  168.  
  169.                 if (dlg->keyboard_focus_gadget == listbox)
  170.                 {
  171.                         dlg->keyboard_focus_gadget = ui_gadget_get_next(listbox);
  172.                 }
  173.  
  174.                 return window_event_result::ignored;
  175.         }
  176.  
  177.         listbox->old_current_item = listbox->current_item;
  178.         listbox->old_first_item = listbox->first_item;
  179.  
  180.  
  181.         if (GADGET_PRESSED(listbox->scrollbar.get()))
  182.         {
  183.                 listbox->moved = 1;
  184.  
  185.                 listbox->first_item = listbox->scrollbar->position;
  186.  
  187.                 if (listbox->current_item<listbox->first_item)
  188.                         listbox->current_item = listbox->first_item;
  189.  
  190.                 if (listbox->current_item>(listbox->first_item+listbox->num_items_displayed-1))
  191.                         listbox->current_item = listbox->first_item + listbox->num_items_displayed-1;
  192.  
  193.         }
  194.  
  195.         if (B1_JUST_RELEASED)
  196.                 listbox->dragging = 0;
  197.  
  198.         window_event_result rval = window_event_result::ignored;
  199.         if (B1_JUST_PRESSED && ui_mouse_on_gadget( listbox ))
  200.         {
  201.                 listbox->dragging = 1;
  202.                 rval = window_event_result::handled;
  203.         }
  204.  
  205.         if ( dlg->keyboard_focus_gadget==listbox )
  206.         {
  207.                 if (keypress==KEY_ENTER)   {
  208.                         listbox->selected_item = listbox->current_item;
  209.                         rval = window_event_result::handled;
  210.                 }
  211.  
  212.                 kf = 0;
  213.  
  214.                 switch(keypress)
  215.                 {
  216.                         case (KEY_UP):
  217.                                 listbox->current_item--;
  218.                                 kf = 1;
  219.                                 break;
  220.                         case (KEY_DOWN):
  221.                                 listbox->current_item++;
  222.                                 kf = 1;
  223.                                 break;
  224.                         case (KEY_HOME):
  225.                                 listbox->current_item=0;
  226.                                 kf = 1;
  227.                                 break;
  228.                         case (KEY_END):
  229.                                 listbox->current_item=listbox->num_items-1;
  230.                                 kf = 1;
  231.                                 break;
  232.                         case (KEY_PAGEUP):
  233.                                 listbox->current_item -= listbox->num_items_displayed;
  234.                                 kf = 1;
  235.                                 break;
  236.                         case (KEY_PAGEDOWN):
  237.                                 listbox->current_item += listbox->num_items_displayed;
  238.                                 kf = 1;
  239.                                 break;
  240.                 }
  241.  
  242.                 if (kf==1)
  243.                 {
  244.                         listbox->moved = 1;
  245.                         rval = window_event_result::handled;
  246.  
  247.                         if (listbox->current_item<0)
  248.                                 listbox->current_item=0;
  249.  
  250.                         if (listbox->current_item>=listbox->num_items)
  251.                                 listbox->current_item = listbox->num_items-1;
  252.  
  253.                         if (listbox->current_item<listbox->first_item)
  254.                                 listbox->first_item = listbox->current_item;
  255.  
  256.                         if (listbox->current_item>=(listbox->first_item+listbox->num_items_displayed))
  257.                                 listbox->first_item = listbox->current_item-listbox->num_items_displayed+1;
  258.  
  259.                         if (listbox->num_items <= listbox->num_items_displayed )
  260.                                 listbox->first_item = 0;
  261.                         else
  262.                         {
  263.                                 oldfakepos = listbox->scrollbar->position;
  264.                                 listbox->scrollbar->position = listbox->first_item;
  265.  
  266.                                 listbox->scrollbar->fake_position = listbox->scrollbar->position-listbox->scrollbar->start;
  267.                                 listbox->scrollbar->fake_position *= listbox->scrollbar->height-listbox->scrollbar->fake_size;
  268.                                 listbox->scrollbar->fake_position /= (listbox->scrollbar->stop-listbox->scrollbar->start);
  269.  
  270.                                 if (listbox->scrollbar->fake_position<0)
  271.                                 {
  272.                                         listbox->scrollbar->fake_position = 0;
  273.                                 }
  274.                                 if (listbox->scrollbar->fake_position > (listbox->scrollbar->height-listbox->scrollbar->fake_size))
  275.                                 {
  276.                                         listbox->scrollbar->fake_position = (listbox->scrollbar->height-listbox->scrollbar->fake_size);
  277.                                 }
  278.  
  279.                                 if (oldfakepos != listbox->scrollbar->position )
  280.                                         listbox->scrollbar->status = 1;
  281.                         }
  282.                 }
  283.         }
  284.  
  285.  
  286.         if (selected_gadget==listbox)
  287.         {
  288.                 if (listbox->dragging)
  289.                 {
  290.                         int x, y, z;
  291.                        
  292.                         mouse_get_pos(&x, &y, &z);
  293.                         if (y < listbox->y1)
  294.                                 mitem = -1;
  295.                         else
  296.                                 mitem = (y - listbox->y1)/listbox->textheight;
  297.  
  298.                         if ((mitem < 0) && (timer_query() > listbox->last_scrolled + 1))
  299.                         {
  300.                                 listbox->current_item--;
  301.                                 listbox->last_scrolled = timer_query();
  302.                                 listbox->moved = 1;
  303.                         }
  304.  
  305.                         if ((mitem >= listbox->num_items_displayed) &&
  306.                                  (timer_query() > listbox->last_scrolled + 1))
  307.                         {
  308.                                 listbox->current_item++;
  309.                                 listbox->last_scrolled = timer_query();
  310.                                 listbox->moved = 1;
  311.                         }
  312.  
  313.                         if ((mitem>=0) && (mitem<listbox->num_items_displayed))
  314.                         {
  315.                                 listbox->current_item = mitem+listbox->first_item;
  316.                                 listbox->moved=1;
  317.                         }
  318.  
  319.                         if (listbox->current_item <0 )
  320.                                 listbox->current_item = 0;
  321.  
  322.                         if (listbox->current_item >= listbox->num_items )
  323.                                 listbox->current_item = listbox->num_items-1;
  324.  
  325.                         if (listbox->current_item<listbox->first_item)
  326.                                 listbox->first_item = listbox->current_item;
  327.  
  328.                         if (listbox->current_item>=(listbox->first_item+listbox->num_items_displayed))
  329.                                 listbox->first_item = listbox->current_item-listbox->num_items_displayed+1;
  330.  
  331.                         if (listbox->num_items <= listbox->num_items_displayed )
  332.                                 listbox->first_item = 0;
  333.                         else
  334.                         {
  335.                                 oldfakepos = listbox->scrollbar->position;
  336.                                 listbox->scrollbar->position = listbox->first_item;
  337.  
  338.                                 listbox->scrollbar->fake_position = listbox->scrollbar->position-listbox->scrollbar->start;
  339.                                 listbox->scrollbar->fake_position *= listbox->scrollbar->height-listbox->scrollbar->fake_size;
  340.                                 listbox->scrollbar->fake_position /= (listbox->scrollbar->stop-listbox->scrollbar->start);
  341.  
  342.                                 if (listbox->scrollbar->fake_position<0)
  343.                                 {
  344.                                         listbox->scrollbar->fake_position = 0;
  345.                                 }
  346.                                 if (listbox->scrollbar->fake_position > (listbox->scrollbar->height-listbox->scrollbar->fake_size))
  347.                                 {
  348.                                         listbox->scrollbar->fake_position = (listbox->scrollbar->height-listbox->scrollbar->fake_size);
  349.                                 }
  350.  
  351.                                 if (oldfakepos != listbox->scrollbar->position )
  352.                                         listbox->scrollbar->status = 1;
  353.                         }
  354.  
  355.                 }
  356.  
  357.                 if (B1_DOUBLE_CLICKED )
  358.                 {
  359.                         listbox->selected_item = listbox->current_item;
  360.                         rval = window_event_result::handled;
  361.                 }
  362.  
  363.         }
  364.        
  365.         if (listbox->moved || (listbox->selected_item > 0))
  366.         {
  367.                 rval = ui_gadget_send_event(dlg, (listbox->selected_item > 0) ? EVENT_UI_LISTBOX_SELECTED : EVENT_UI_LISTBOX_MOVED, listbox);
  368.                 if (rval == window_event_result::ignored)
  369.                         rval = window_event_result::handled;
  370.         }
  371.  
  372.         return rval;
  373. }
  374.  
  375. void ui_listbox_change(UI_DIALOG *, UI_GADGET_LISTBOX *listbox, uint_fast32_t numitems, const char *const *list)
  376. {
  377.         int stop, start;
  378.         UI_GADGET_SCROLLBAR * scrollbar;
  379.  
  380.         listbox->list = list;
  381.         listbox->num_items = numitems;
  382.         listbox->first_item = 0;
  383.         listbox->current_item = -1;
  384.         listbox->last_scrolled = timer_query();
  385.         listbox->dragging = 0;
  386.         listbox->selected_item = -1;
  387.         listbox->status = 1;
  388.         listbox->first_item = 0;
  389.         listbox->current_item = listbox->old_current_item = 0;
  390.         listbox->moved = 0;
  391.  
  392.         scrollbar = listbox->scrollbar.get();
  393.  
  394.         start=0;
  395.         stop= numitems - listbox->num_items_displayed;
  396.  
  397.         if (stop < start) stop = start;
  398.  
  399.         scrollbar->horz = 0;
  400.         scrollbar->start = start;
  401.         scrollbar->stop = stop;
  402.         scrollbar->fake_length = scrollbar->height;
  403.         scrollbar->fake_position =  0;
  404.         if (stop!=start)
  405.                 scrollbar->fake_size = (listbox->num_items_displayed * scrollbar->height)/(stop-start+1+listbox->num_items_displayed);
  406.         else
  407.                 scrollbar->fake_size = scrollbar->height;
  408.  
  409.         if (scrollbar->fake_size < 7) scrollbar->fake_size = 7;
  410.         scrollbar->dragging = 0;
  411.         scrollbar->moved=0;
  412.         scrollbar->status=1;
  413.  
  414.  
  415. }
  416.  
  417. }
  418.