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