root/lib/widget/label.c

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

DEFINITIONS

This source file includes following definitions.
  1. label_callback
  2. label_new
  3. label_set_text
  4. label_set_textv

   1 /*
   2    Widgets for the Midnight Commander
   3 
   4    Copyright (C) 1994-2025
   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 label.c
  32  *  \brief Source: WLabel widget
  33  */
  34 
  35 #include <config.h>
  36 
  37 #include <stdarg.h>
  38 #include <stdlib.h>
  39 #include <string.h>
  40 
  41 #include "lib/global.h"
  42 
  43 #include "lib/tty/tty.h"
  44 #include "lib/tty/color.h"
  45 #include "lib/skin.h"
  46 #include "lib/strutil.h"
  47 #include "lib/widget.h"
  48 
  49 /*** global variables ****************************************************************************/
  50 
  51 /*** file scope macro definitions ****************************************************************/
  52 
  53 /*** file scope type declarations ****************************************************************/
  54 
  55 /*** forward declarations (file scope functions) *************************************************/
  56 
  57 /*** file scope variables ************************************************************************/
  58 
  59 /* --------------------------------------------------------------------------------------------- */
  60 /*** file scope functions ************************************************************************/
  61 /* --------------------------------------------------------------------------------------------- */
  62 
  63 static cb_ret_t
  64 label_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
  65 {
  66     WLabel *l = LABEL (w);
  67 
  68     switch (msg)
  69     {
  70     case MSG_DRAW:
  71     {
  72         char *p = l->text;
  73         int y = 0;
  74         gboolean disabled;
  75         align_crt_t align;
  76 
  77         if (l->text == NULL)
  78             return MSG_HANDLED;
  79 
  80         disabled = widget_get_state (w, WST_DISABLED);
  81 
  82         if (l->transparent)
  83             tty_setcolor (disabled ? DISABLED_COLOR : DEFAULT_COLOR);
  84         else
  85         {
  86             const int *colors;
  87 
  88             colors = widget_get_colors (w);
  89             tty_setcolor (disabled ? DISABLED_COLOR : colors[DLG_COLOR_NORMAL]);
  90         }
  91 
  92         align = (w->pos_flags & WPOS_CENTER_HORZ) != 0 ? J_CENTER_LEFT : J_LEFT;
  93 
  94         while (TRUE)
  95         {
  96             char *q;
  97             char c = '\0';
  98 
  99             q = strchr (p, '\n');
 100             if (q != NULL)
 101             {
 102                 c = q[0];
 103                 q[0] = '\0';
 104             }
 105 
 106             widget_gotoyx (w, y, 0);
 107             tty_print_string (str_fit_to_term (p, w->rect.cols, align));
 108 
 109             if (q == NULL)
 110                 break;
 111 
 112             q[0] = c;
 113             p = q + 1;
 114             y++;
 115         }
 116         return MSG_HANDLED;
 117     }
 118 
 119     case MSG_DESTROY:
 120         g_free (l->text);
 121         return MSG_HANDLED;
 122 
 123     default:
 124         return widget_default_callback (w, sender, msg, parm, data);
 125     }
 126 }
 127 
 128 /* --------------------------------------------------------------------------------------------- */
 129 /*** public functions ****************************************************************************/
 130 /* --------------------------------------------------------------------------------------------- */
 131 
 132 WLabel *
 133 label_new (int y, int x, const char *text)
     /* [previous][next][first][last][top][bottom][index][help]  */
 134 {
 135     WRect r = { y, x, 1, 1 };
 136     WLabel *l;
 137     Widget *w;
 138 
 139     if (text != NULL)
 140         str_msg_term_size (text, &r.lines, &r.cols);
 141 
 142     l = g_new (WLabel, 1);
 143     w = WIDGET (l);
 144     widget_init (w, &r, label_callback, NULL);
 145 
 146     l->text = g_strdup (text);
 147     l->auto_adjust_cols = TRUE;
 148     l->transparent = FALSE;
 149 
 150     return l;
 151 }
 152 
 153 /* --------------------------------------------------------------------------------------------- */
 154 
 155 void
 156 label_set_text (WLabel *label, const char *text)
     /* [previous][next][first][last][top][bottom][index][help]  */
 157 {
 158     Widget *w = WIDGET (label);
 159     int newcols = w->rect.cols;
 160     int newlines;
 161 
 162     if (label->text != NULL && text != NULL && strcmp (label->text, text) == 0)
 163         return;  // Flickering is not nice
 164 
 165     g_free (label->text);
 166 
 167     if (text == NULL)
 168         label->text = NULL;
 169     else
 170     {
 171         label->text = g_strdup (text);
 172         if (label->auto_adjust_cols)
 173         {
 174             str_msg_term_size (text, &newlines, &newcols);
 175             w->rect.cols = MAX (newcols, w->rect.cols);
 176             w->rect.lines = MAX (newlines, w->rect.lines);
 177         }
 178     }
 179 
 180     widget_draw (w);
 181 
 182     w->rect.cols = MIN (newcols, w->rect.cols);
 183 }
 184 
 185 /* --------------------------------------------------------------------------------------------- */
 186 
 187 void
 188 label_set_textv (WLabel *label, const char *format, ...)
     /* [previous][next][first][last][top][bottom][index][help]  */
 189 {
 190     va_list args;
 191     char buf[BUF_1K];  // FIXME: is it enough?
 192 
 193     va_start (args, format);
 194     g_vsnprintf (buf, sizeof (buf), format, args);
 195     va_end (args);
 196 
 197     label_set_text (label, buf);
 198 }
 199 
 200 /* --------------------------------------------------------------------------------------------- */

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