Manual pages: mcmcdiffmceditmcview

root/lib/widget/button.c

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

DEFINITIONS

This source file includes following definitions.
  1. button_get_columns
  2. button_default_callback
  3. button_mouse_default_callback
  4. button_new
  5. button_get_text
  6. button_set_text

   1 /*
   2    Widgets for the Midnight Commander
   3 
   4    Copyright (C) 1994-2026
   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 <https://www.gnu.org/licenses/>.
  29  */
  30 
  31 /** \file button.c
  32  *  \brief Source: WButton widget
  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/strutil.h"
  43 #include "lib/widget.h"
  44 
  45 /*** global variables ****************************************************************************/
  46 
  47 /*** file scope macro definitions ****************************************************************/
  48 
  49 /*** file scope type declarations ****************************************************************/
  50 
  51 /*** file scope variables ************************************************************************/
  52 
  53 /* --------------------------------------------------------------------------------------------- */
  54 /*** file scope functions ************************************************************************/
  55 /* --------------------------------------------------------------------------------------------- */
  56 
  57 static int
  58 button_get_columns (const WButton *b)
     /* [previous][next][first][last][top][bottom][index][help]  */
  59 {
  60     int ret;
  61 
  62     ret = hotkey_width (b->text);
  63 
  64     switch (b->flags)
  65     {
  66     case DEFPUSH_BUTTON:
  67         ret += 6;
  68         break;
  69     case NORMAL_BUTTON:
  70         ret += 4;
  71         break;
  72     case NARROW_BUTTON:
  73         ret += 2;
  74         break;
  75     case HIDDEN_BUTTON:
  76     default:
  77         return 0;
  78     }
  79 
  80     return ret;
  81 }
  82 
  83 /* --------------------------------------------------------------------------------------------- */
  84 /*** public functions ****************************************************************************/
  85 /* --------------------------------------------------------------------------------------------- */
  86 
  87 cb_ret_t
  88 button_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
  89 {
  90     WButton *b = BUTTON (w);
  91     WGroup *g = w->owner;
  92     WDialog *h = DIALOG (g);
  93     int off = 0;
  94 
  95     switch (msg)
  96     {
  97     case MSG_HOTKEY:
  98         /*
  99          * Don't let the default button steal Enter from the current
 100          * button.  This is a workaround for the flawed event model
 101          * when hotkeys are sent to all widgets before the key is
 102          * handled by the current widget.
 103          */
 104         if (parm == '\n' && WIDGET (g->current->data) == w)
 105         {
 106             send_message (w, sender, MSG_KEY, ' ', data);
 107             return MSG_HANDLED;
 108         }
 109 
 110         if (parm == '\n' && b->flags == DEFPUSH_BUTTON)
 111         {
 112             send_message (w, sender, MSG_KEY, ' ', data);
 113             return MSG_HANDLED;
 114         }
 115 
 116         if (b->text.hotkey != NULL && g_ascii_tolower ((gchar) b->text.hotkey[0]) == parm)
 117         {
 118             send_message (w, sender, MSG_KEY, ' ', data);
 119             return MSG_HANDLED;
 120         }
 121         return MSG_NOT_HANDLED;
 122 
 123     case MSG_KEY:
 124         if (parm != ' ' && parm != '\n')
 125             return MSG_NOT_HANDLED;
 126 
 127         h->ret_value = b->action;
 128         if (b->callback == NULL || b->callback (b, b->action) != 0)
 129             dlg_close (h);
 130 
 131         return MSG_HANDLED;
 132 
 133     case MSG_CURSOR:
 134         switch (b->flags)
 135         {
 136         case DEFPUSH_BUTTON:
 137             off = 3;
 138             break;
 139         case NORMAL_BUTTON:
 140             off = 2;
 141             break;
 142         case NARROW_BUTTON:
 143             off = 1;
 144             break;
 145         case HIDDEN_BUTTON:
 146         default:
 147             off = 0;
 148             break;
 149         }
 150         widget_gotoyx (w, 0, b->hotpos + off);
 151         return MSG_HANDLED;
 152 
 153     case MSG_DRAW:
 154     {
 155         gboolean focused;
 156 
 157         focused = widget_get_state (w, WST_FOCUSED);
 158 
 159         widget_selectcolor (w, focused, FALSE);
 160         widget_gotoyx (w, 0, 0);
 161 
 162         switch (b->flags)
 163         {
 164         case DEFPUSH_BUTTON:
 165             tty_print_string ("[< ");
 166             break;
 167         case NORMAL_BUTTON:
 168             tty_print_string ("[ ");
 169             break;
 170         case NARROW_BUTTON:
 171             tty_print_string ("[");
 172             break;
 173         case HIDDEN_BUTTON:
 174         default:
 175             return MSG_HANDLED;
 176         }
 177 
 178         hotkey_draw (w, b->text, focused);
 179 
 180         switch (b->flags)
 181         {
 182         case DEFPUSH_BUTTON:
 183             tty_print_string (" >]");
 184             break;
 185         case NORMAL_BUTTON:
 186             tty_print_string (" ]");
 187             break;
 188         case NARROW_BUTTON:
 189             tty_print_string ("]");
 190             break;
 191         default:
 192             break;
 193         }
 194 
 195         return MSG_HANDLED;
 196     }
 197 
 198     case MSG_DESTROY:
 199         hotkey_free (b->text);
 200         return MSG_HANDLED;
 201 
 202     default:
 203         return widget_default_callback (w, sender, msg, parm, data);
 204     }
 205 }
 206 
 207 /* --------------------------------------------------------------------------------------------- */
 208 
 209 void
 210 button_mouse_default_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
     /* [previous][next][first][last][top][bottom][index][help]  */
 211 {
 212     (void) event;
 213 
 214     switch (msg)
 215     {
 216     case MSG_MOUSE_DOWN:
 217         widget_select (w);
 218         break;
 219 
 220     case MSG_MOUSE_CLICK:
 221         send_message (w, NULL, MSG_KEY, ' ', NULL);
 222         send_message (w->owner, w, MSG_POST_KEY, ' ', NULL);
 223         break;
 224 
 225     default:
 226         break;
 227     }
 228 }
 229 
 230 /* --------------------------------------------------------------------------------------------- */
 231 
 232 WButton *
 233 button_new (int y, int x, int action, button_flags_t flags, const char *text, bcback_fn callback)
     /* [previous][next][first][last][top][bottom][index][help]  */
 234 {
 235     WRect r = { y, x, 1, 1 };
 236     WButton *b;
 237     Widget *w;
 238 
 239     b = g_new (WButton, 1);
 240     w = WIDGET (b);
 241 
 242     b->action = action;
 243     b->flags = flags;
 244     b->text = hotkey_new (text);
 245     r.cols = button_get_columns (b);
 246     widget_init (w, &r, button_default_callback, button_mouse_default_callback);
 247     w->options |= WOP_SELECTABLE | WOP_WANT_CURSOR | WOP_WANT_HOTKEY;
 248     b->callback = callback;
 249     b->hotpos = (b->text.hotkey != NULL) ? str_term_width1 (b->text.start) : -1;
 250 
 251     return b;
 252 }
 253 
 254 /* --------------------------------------------------------------------------------------------- */
 255 
 256 char *
 257 button_get_text (const WButton *b)
     /* [previous][next][first][last][top][bottom][index][help]  */
 258 {
 259     return hotkey_get_text (b->text);
 260 }
 261 
 262 /* --------------------------------------------------------------------------------------------- */
 263 
 264 void
 265 button_set_text (WButton *b, const char *text)
     /* [previous][next][first][last][top][bottom][index][help]  */
 266 {
 267     Widget *w = WIDGET (b);
 268     hotkey_t hk;
 269 
 270     hk = hotkey_new (text);
 271     if (hotkey_equal (b->text, hk))
 272     {
 273         hotkey_free (hk);
 274         return;
 275     }
 276 
 277     hotkey_free (b->text);
 278     b->text = hk;
 279     b->hotpos = (b->text.hotkey != NULL) ? str_term_width1 (b->text.start) : -1;
 280     w->rect.cols = button_get_columns (b);
 281     widget_draw (w);
 282 }
 283 
 284 /* --------------------------------------------------------------------------------------------- */

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