From 37978a2ce0d2e664644da3b9d8b90ff0adde996c Mon Sep 17 00:00:00 2001
From: Kamil W <istonar3@gmail.com>
Date: Mon, 26 Sep 2016 19:05:57 +0200
Subject: [PATCH] Add hotkey support to labels and groupboxes
---
lib/widget/groupbox.c | 25 +++++++++++++++++++------
lib/widget/groupbox.h | 2 +-
lib/widget/label.c | 45 +++++++++++++++++++++++++++++++++++----------
lib/widget/label.h | 2 +-
lib/widget/widget-common.c | 21 +++++++++++++++++++++
lib/widget/widget-common.h | 2 ++
6 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/lib/widget/groupbox.c b/lib/widget/groupbox.c
index 2d7a5b4..cf48996 100644
a
|
b
|
groupbox_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void |
62 | 62 | case MSG_INIT: |
63 | 63 | return MSG_HANDLED; |
64 | 64 | |
| 65 | case MSG_HOTKEY: |
| 66 | if (g->title.hotkey != NULL) |
| 67 | { |
| 68 | if (g_ascii_tolower ((gchar) g->title.hotkey[0]) == parm) |
| 69 | { |
| 70 | /* select next widget in this groupbox */ |
| 71 | dlg_select_by_id (w->owner, (w->id + 1)); |
| 72 | return MSG_HANDLED; |
| 73 | } |
| 74 | } |
| 75 | return MSG_NOT_HANDLED; |
| 76 | |
65 | 77 | case MSG_DRAW: |
66 | 78 | { |
67 | 79 | WDialog *h = w->owner; |
… |
… |
groupbox_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void |
72 | 84 | tty_setcolor (disabled ? DISABLED_COLOR : h->color[DLG_COLOR_NORMAL]); |
73 | 85 | tty_draw_box (w->y, w->x, w->lines, w->cols, TRUE); |
74 | 86 | |
75 | | if (g->title != NULL) |
| 87 | if ((get_hotkey_text (g->title)) != NULL) |
76 | 88 | { |
77 | 89 | tty_setcolor (disabled ? DISABLED_COLOR : h->color[DLG_COLOR_TITLE]); |
78 | 90 | widget_move (w, 0, 1); |
79 | | tty_print_string (g->title); |
| 91 | hotkey_draw (w, g->title, FALSE); |
80 | 92 | } |
81 | 93 | return MSG_HANDLED; |
82 | 94 | } |
83 | 95 | |
84 | 96 | case MSG_DESTROY: |
85 | | g_free (g->title); |
| 97 | release_hotkey (g->title); |
86 | 98 | return MSG_HANDLED; |
87 | 99 | |
88 | 100 | default: |
… |
… |
groupbox_new (int y, int x, int height, int width, const char *title) |
102 | 114 | |
103 | 115 | g = g_new (WGroupbox, 1); |
104 | 116 | w = WIDGET (g); |
| 117 | g->title = parse_hotkey (title); |
105 | 118 | widget_init (w, y, x, height, width, groupbox_callback, NULL); |
106 | 119 | |
107 | | g->title = NULL; |
| 120 | w->options |= WOP_WANT_HOTKEY; |
108 | 121 | groupbox_set_title (g, title); |
109 | 122 | |
110 | 123 | return g; |
… |
… |
groupbox_new (int y, int x, int height, int width, const char *title) |
115 | 128 | void |
116 | 129 | groupbox_set_title (WGroupbox * g, const char *title) |
117 | 130 | { |
118 | | MC_PTR_FREE (g->title); |
| 131 | release_hotkey (g->title); |
119 | 132 | |
120 | 133 | /* Strip existing spaces, add one space before and after the title */ |
121 | 134 | if (title != NULL && *title != '\0') |
… |
… |
groupbox_set_title (WGroupbox * g, const char *title) |
123 | 136 | char *t; |
124 | 137 | |
125 | 138 | t = g_strstrip (g_strdup (title)); |
126 | | g->title = g_strconcat (" ", t, " ", (char *) NULL); |
| 139 | g->title = parse_hotkey (g_strconcat (" ", t, " ", (char *) NULL)); |
127 | 140 | g_free (t); |
128 | 141 | } |
129 | 142 | |
diff --git a/lib/widget/groupbox.h b/lib/widget/groupbox.h
index 06fb0d3..e8b3fcc 100644
a
|
b
|
|
17 | 17 | typedef struct WGroupbox |
18 | 18 | { |
19 | 19 | Widget widget; |
20 | | char *title; |
| 20 | hotkey_t title; |
21 | 21 | } WGroupbox; |
22 | 22 | |
23 | 23 | /*** global variables defined in .c file *********************************************************/ |
diff --git a/lib/widget/label.c b/lib/widget/label.c
index 769a9c3..e471400 100644
a
|
b
|
label_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d |
67 | 67 | case MSG_INIT: |
68 | 68 | return MSG_HANDLED; |
69 | 69 | |
| 70 | case MSG_HOTKEY: |
| 71 | if (l->text.hotkey != NULL) |
| 72 | { |
| 73 | if (g_ascii_tolower ((gchar) l->text.hotkey[0]) == parm) |
| 74 | { |
| 75 | /* select next widget after this label */ |
| 76 | dlg_select_by_id (w->owner, (w->id + 1)); |
| 77 | return MSG_HANDLED; |
| 78 | } |
| 79 | } |
| 80 | return MSG_NOT_HANDLED; |
| 81 | |
70 | 82 | case MSG_DRAW: |
71 | 83 | { |
72 | | char *p = l->text; |
| 84 | char *p = get_hotkey_text (l->text); |
73 | 85 | int y = 0; |
74 | 86 | gboolean disabled; |
| 87 | gboolean focused; |
75 | 88 | align_crt_t align; |
76 | 89 | |
77 | | if (l->text == NULL) |
| 90 | if (p == NULL) |
78 | 91 | return MSG_HANDLED; |
79 | 92 | |
80 | 93 | disabled = widget_get_state (w, WST_DISABLED); |
| 94 | focused = widget_get_state (w, WST_FOCUSED); |
81 | 95 | |
82 | 96 | if (l->transparent) |
83 | 97 | tty_setcolor (disabled ? DISABLED_COLOR : DEFAULT_COLOR); |
84 | 98 | else |
85 | 99 | tty_setcolor (disabled ? DISABLED_COLOR : h->color[DLG_COLOR_NORMAL]); |
86 | 100 | |
| 101 | /* if there is a hotkey, we assume that text will be a one liner */ |
| 102 | if (l->text.hotkey != NULL) |
| 103 | { |
| 104 | widget_move (w, 0, 0); |
| 105 | hotkey_draw (w, l->text, focused); |
| 106 | return MSG_HANDLED; |
| 107 | } |
| 108 | |
87 | 109 | align = (w->pos_flags & WPOS_CENTER_HORZ) != 0 ? J_CENTER_LEFT : J_LEFT; |
88 | 110 | |
89 | 111 | while (TRUE) |
… |
… |
label_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d |
91 | 113 | char *q; |
92 | 114 | char c = '\0'; |
93 | 115 | |
94 | | |
95 | 116 | q = strchr (p, '\n'); |
96 | 117 | if (q != NULL) |
97 | 118 | { |
… |
… |
label_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d |
109 | 130 | p = q + 1; |
110 | 131 | y++; |
111 | 132 | } |
| 133 | |
112 | 134 | return MSG_HANDLED; |
113 | 135 | } |
114 | 136 | |
115 | 137 | case MSG_DESTROY: |
116 | | g_free (l->text); |
| 138 | release_hotkey (l->text); |
117 | 139 | return MSG_HANDLED; |
118 | 140 | |
119 | 141 | default: |
… |
… |
label_new (int y, int x, const char *text) |
138 | 160 | |
139 | 161 | l = g_new (WLabel, 1); |
140 | 162 | w = WIDGET (l); |
| 163 | l->text = parse_hotkey (text); |
141 | 164 | widget_init (w, y, x, lines, cols, label_callback, NULL); |
142 | | |
143 | | l->text = g_strdup (text); |
| 165 | w->options |= WOP_WANT_HOTKEY; |
144 | 166 | l->auto_adjust_cols = TRUE; |
145 | 167 | l->transparent = FALSE; |
146 | 168 | |
… |
… |
label_set_text (WLabel * label, const char *text) |
155 | 177 | Widget *w = WIDGET (label); |
156 | 178 | int newcols = w->cols; |
157 | 179 | int newlines; |
| 180 | char *temp_str = get_hotkey_text (label->text); |
158 | 181 | |
159 | | if (label->text != NULL && text != NULL && strcmp (label->text, text) == 0) |
| 182 | if (temp_str != NULL && text != NULL && strcmp (temp_str, text) == 0) |
160 | 183 | return; /* Flickering is not nice */ |
161 | 184 | |
162 | | g_free (label->text); |
| 185 | release_hotkey (label->text); |
163 | 186 | |
164 | 187 | if (text == NULL) |
165 | | label->text = NULL; |
| 188 | label->text = parse_hotkey (NULL); |
166 | 189 | else |
167 | 190 | { |
168 | | label->text = g_strdup (text); |
| 191 | label->text = parse_hotkey (text); |
169 | 192 | if (label->auto_adjust_cols) |
170 | 193 | { |
171 | 194 | str_msg_term_size (text, &newlines, &newcols); |
… |
… |
label_set_text (WLabel * label, const char *text) |
180 | 203 | |
181 | 204 | if (newcols < w->cols) |
182 | 205 | w->cols = newcols; |
| 206 | |
| 207 | g_free (temp_str); |
183 | 208 | } |
184 | 209 | |
185 | 210 | /* --------------------------------------------------------------------------------------------- */ |
diff --git a/lib/widget/label.h b/lib/widget/label.h
index 6d1607f..59d5281 100644
a
|
b
|
typedef struct |
18 | 18 | { |
19 | 19 | Widget widget; |
20 | 20 | gboolean auto_adjust_cols; /* compute widget.cols from strlen(text)? */ |
21 | | char *text; |
| 21 | hotkey_t text; |
22 | 22 | gboolean transparent; /* Paint in the default color fg/bg */ |
23 | 23 | } WLabel; |
24 | 24 | |
diff --git a/lib/widget/widget-common.c b/lib/widget/widget-common.c
index e97b526..17c8db1 100644
a
|
b
|
hotkey_width (const hotkey_t hotkey) |
173 | 173 | |
174 | 174 | /* --------------------------------------------------------------------------------------------- */ |
175 | 175 | |
| 176 | char * |
| 177 | get_hotkey_text (const hotkey_t hotkey) |
| 178 | { |
| 179 | int hk_width; |
| 180 | char *temp; |
| 181 | |
| 182 | hk_width = hotkey_width (hotkey); |
| 183 | temp = g_malloc (hk_width + 1); |
| 184 | |
| 185 | strcpy (temp, hotkey.start); |
| 186 | |
| 187 | if (hotkey.hotkey != NULL) |
| 188 | strcat (temp, hotkey.hotkey); |
| 189 | if (hotkey.end != NULL) |
| 190 | strcat (temp, hotkey.end); |
| 191 | |
| 192 | return temp; |
| 193 | } |
| 194 | |
| 195 | /* --------------------------------------------------------------------------------------------- */ |
| 196 | |
176 | 197 | void |
177 | 198 | hotkey_draw (Widget * w, const hotkey_t hotkey, gboolean focused) |
178 | 199 | { |
diff --git a/lib/widget/widget-common.h b/lib/widget/widget-common.h
index 540189a..9d93967 100644
a
|
b
|
hotkey_t parse_hotkey (const char *text); |
168 | 168 | void release_hotkey (const hotkey_t hotkey); |
169 | 169 | /* return width on terminal of hotkey */ |
170 | 170 | int hotkey_width (const hotkey_t hotkey); |
| 171 | /* get text of hotkey as one string */ |
| 172 | char * get_hotkey_text (const hotkey_t hotkey); |
171 | 173 | /* draw hotkey of widget */ |
172 | 174 | void hotkey_draw (Widget * w, const hotkey_t hotkey, gboolean focused); |
173 | 175 | |