root/lib/widget/radio.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. radio_execute_cmd
  2. radio_key
  3. radio_callback
  4. radio_mouse_callback
  5. radio_new

   1 /*
   2    Widgets for the Midnight Commander
   3 
   4    Copyright (C) 1994-2024
   5    Free Software Foundation, Inc.
   6 
   7    Authors:
   8    Radek Doulik, 1994, 1995
   9    Miguel de Icaza, 1994, 1995
  10    Jakub Jelinek, 1995
  11    Andrej Borsenkow, 1996
  12    Norbert Warmuth, 1997
  13    Andrew Borodin <aborodin@vmail.ru>, 2009-2022
  14 
  15    This file is part of the Midnight Commander.
  16 
  17    The Midnight Commander is free software: you can redistribute it
  18    and/or modify it under the terms of the GNU General Public License as
  19    published by the Free Software Foundation, either version 3 of the License,
  20    or (at your option) any later version.
  21 
  22    The Midnight Commander is distributed in the hope that it will be useful,
  23    but WITHOUT ANY WARRANTY; without even the implied warranty of
  24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25    GNU General Public License for more details.
  26 
  27    You should have received a copy of the GNU General Public License
  28    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  29  */
  30 
  31 /** \file radio.c
  32  *  \brief Source: WRadui widget (radiobuttons)
  33  */
  34 
  35 #include <config.h>
  36 
  37 #include <stdlib.h>
  38 
  39 #include "lib/global.h"
  40 
  41 #include "lib/tty/tty.h"
  42 #include "lib/widget.h"
  43 
  44 /*** global variables ****************************************************************************/
  45 
  46 const global_keymap_t *radio_map = NULL;
  47 
  48 /*** file scope macro definitions ****************************************************************/
  49 
  50 /*** file scope type declarations ****************************************************************/
  51 
  52 /*** forward declarations (file scope functions) *************************************************/
  53 
  54 /*** file scope variables ************************************************************************/
  55 
  56 /* --------------------------------------------------------------------------------------------- */
  57 /*** file scope functions ************************************************************************/
  58 /* --------------------------------------------------------------------------------------------- */
  59 
  60 static cb_ret_t
  61 radio_execute_cmd (WRadio *r, long command)
     /* [previous][next][first][last][top][bottom][index][help]  */
  62 {
  63     cb_ret_t ret = MSG_HANDLED;
  64     Widget *w = WIDGET (r);
  65 
  66     switch (command)
  67     {
  68     case CK_Up:
  69     case CK_Top:
  70         if (r->pos == 0)
  71             return MSG_NOT_HANDLED;
  72 
  73         if (command == CK_Top)
  74             r->pos = 0;
  75         else
  76             r->pos--;
  77         widget_draw (w);
  78         return MSG_HANDLED;
  79 
  80     case CK_Down:
  81     case CK_Bottom:
  82         if (r->pos == r->count - 1)
  83             return MSG_NOT_HANDLED;
  84 
  85         if (command == CK_Bottom)
  86             r->pos = r->count - 1;
  87         else
  88             r->pos++;
  89         widget_draw (w);
  90         return MSG_HANDLED;
  91 
  92     case CK_Select:
  93         r->sel = r->pos;
  94         widget_set_state (w, WST_FOCUSED, TRUE);        /* Also draws the widget */
  95         send_message (w->owner, w, MSG_NOTIFY, 0, NULL);
  96         return MSG_HANDLED;
  97 
  98     default:
  99         ret = MSG_NOT_HANDLED;
 100         break;
 101     }
 102 
 103     return ret;
 104 }
 105 
 106 /* --------------------------------------------------------------------------------------------- */
 107 
 108 /* Return MSG_HANDLED if we want a redraw */
 109 static cb_ret_t
 110 radio_key (WRadio *r, int key)
     /* [previous][next][first][last][top][bottom][index][help]  */
 111 {
 112     long command;
 113 
 114     command = widget_lookup_key (WIDGET (r), key);
 115     if (command == CK_IgnoreKey)
 116         return MSG_NOT_HANDLED;
 117     return radio_execute_cmd (r, command);
 118 }
 119 
 120 /* --------------------------------------------------------------------------------------------- */
 121 
 122 static cb_ret_t
 123 radio_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 124 {
 125     WRadio *r = RADIO (w);
 126     int i;
 127 
 128     switch (msg)
 129     {
 130     case MSG_HOTKEY:
 131         for (i = 0; i < r->count; i++)
 132         {
 133             if (r->texts[i].hotkey != NULL)
 134             {
 135                 int c;
 136 
 137                 c = g_ascii_tolower ((gchar) r->texts[i].hotkey[0]);
 138                 if (c != parm)
 139                     continue;
 140                 r->pos = i;
 141 
 142                 /* Take action */
 143                 send_message (w, sender, MSG_ACTION, CK_Select, data);
 144                 return MSG_HANDLED;
 145             }
 146         }
 147         return MSG_NOT_HANDLED;
 148 
 149     case MSG_KEY:
 150         return radio_key (r, parm);
 151 
 152     case MSG_ACTION:
 153         return radio_execute_cmd (r, parm);
 154 
 155     case MSG_CURSOR:
 156         widget_gotoyx (r, r->pos, 1);
 157         return MSG_HANDLED;
 158 
 159     case MSG_DRAW:
 160         {
 161             gboolean focused;
 162 
 163             focused = widget_get_state (w, WST_FOCUSED);
 164 
 165             for (i = 0; i < r->count; i++)
 166             {
 167                 widget_selectcolor (w, i == r->pos && focused, FALSE);
 168                 widget_gotoyx (w, i, 0);
 169                 tty_draw_hline (w->rect.y + i, w->rect.x, ' ', w->rect.cols);
 170                 tty_print_string ((r->sel == i) ? "(*) " : "( ) ");
 171                 hotkey_draw (w, r->texts[i], i == r->pos && focused);
 172             }
 173 
 174             return MSG_HANDLED;
 175         }
 176 
 177     case MSG_DESTROY:
 178         for (i = 0; i < r->count; i++)
 179             hotkey_free (r->texts[i]);
 180         g_free (r->texts);
 181         return MSG_HANDLED;
 182 
 183     default:
 184         return widget_default_callback (w, sender, msg, parm, data);
 185     }
 186 }
 187 
 188 /* --------------------------------------------------------------------------------------------- */
 189 
 190 static void
 191 radio_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
     /* [previous][next][first][last][top][bottom][index][help]  */
 192 {
 193     switch (msg)
 194     {
 195     case MSG_MOUSE_DOWN:
 196         RADIO (w)->pos = event->y;
 197         widget_select (w);
 198         break;
 199 
 200     case MSG_MOUSE_CLICK:
 201         RADIO (w)->pos = event->y;
 202         send_message (w, NULL, MSG_ACTION, CK_Select, NULL);
 203         send_message (w->owner, w, MSG_POST_KEY, ' ', NULL);
 204         break;
 205 
 206     default:
 207         break;
 208     }
 209 }
 210 
 211 /* --------------------------------------------------------------------------------------------- */
 212 /*** public functions ****************************************************************************/
 213 /* --------------------------------------------------------------------------------------------- */
 214 
 215 WRadio *
 216 radio_new (int y, int x, int count, const char **texts)
     /* [previous][next][first][last][top][bottom][index][help]  */
 217 {
 218     WRect r0 = { y, x, count, 1 };
 219     WRadio *r;
 220     Widget *w;
 221     int i, wmax = 0;
 222 
 223     r = g_new (WRadio, 1);
 224     w = WIDGET (r);
 225 
 226     /* Compute the longest string */
 227     r->texts = g_new (hotkey_t, count);
 228 
 229     for (i = 0; i < count; i++)
 230     {
 231         int width;
 232 
 233         r->texts[i] = hotkey_new (texts[i]);
 234         width = hotkey_width (r->texts[i]);
 235         wmax = MAX (width, wmax);
 236     }
 237 
 238     /* 4 is width of "(*) " */
 239     r0.cols = 4 + wmax;
 240     widget_init (w, &r0, radio_callback, radio_mouse_callback);
 241     w->options |= WOP_SELECTABLE | WOP_WANT_CURSOR | WOP_WANT_HOTKEY;
 242     w->keymap = radio_map;
 243 
 244     r->pos = 0;
 245     r->sel = 0;
 246     r->count = count;
 247 
 248     return r;
 249 }
 250 
 251 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */