1
// ----------------------------------------------------------------------------
5
// Stelios Bounanos, M0GLD
7
// This file is part of fldigi.
9
// fldigi is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 3 of the License, or
12
// (at your option) any later version.
14
// fldigi is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
// GNU General Public License for more details.
19
// You should have received a copy of the GNU General Public License
20
// along with the program; if not, write to the Free Software
22
// 59 Temple Place, Suite 330
23
// Boston, MA 02111-1307 USA
25
// =====================================================================
26
// ----------------------------------------------------------------------------
33
#include <FL/Fl_Menu_Item.H>
34
#include <FL/Fl_Widget.H>
35
#include <FL/Fl_Group.H>
42
# include <FL/Fl_Multi_Label.H>
43
# include <FL/Fl_Image.H>
44
# include <FL/Fl_Pixmap.H>
52
typedef map<Fl_Multi_Label*, Fl_Image**> imap_t;
53
static imap_t* imap = 0;
56
#define FL_EMPTY_LABEL FL_FREE_LABELTYPE
57
static void draw_empty(const Fl_Label*, int, int, int, int, Fl_Align) { }
58
static void measure_empty(const Fl_Label*, int& w, int& h) { w = h = 0; }
60
// The following functions create image+text menu item labels.
61
// You've had too much FLTK if you already know how to do that.
64
// Return a multi_label pointer, cast to a string, for `text' and
65
// `pixmap'. This goes into the label pointer of a widget or menu
66
// item. The text label is copied if we are using multi labels. You must
67
// call set_icon_label on the widget or menu item before its draw()
68
// function is called for the first time.
70
// A NULL pixmap means that the caller wants an empty, transparent, icon.
71
const char* make_icon_label(const char* text, const char** pixmap)
74
static imap_t* imap_ = 0;
75
if (unlikely(!imap_)) {
76
imap = imap_ = new imap_t;
77
Fl::set_labeltype(FL_EMPTY_LABEL, draw_empty, measure_empty);
80
// Create a multi label and associate it with an Fl_Image* array
81
Fl_Multi_Label* mlabel = new Fl_Multi_Label;
82
Fl_Image** images = new Fl_Image*[2];
83
images[0] = new Fl_Pixmap(pixmap ? pixmap : clear_row_icon);
84
images[1] = 0; // we create this on demand
85
// set_icon_label_ will set mlabel->labela later
86
mlabel->typea = _FL_IMAGE_LABEL;
90
size_t len = strlen(text);
91
char* s = new char[len + 2];
93
memcpy(s + 1, text, len + 1);
95
mlabel->typeb = FL_NORMAL_LABEL;
97
(*imap)[mlabel] = images;
99
return (const char*)mlabel;
106
// Find the item's label, which should be something that was returned by
107
// make_icon_label, and set the active or inactive image.
108
template <typename T>
109
void set_icon_label_(T* item)
111
imap_t::iterator j = imap->find((Fl_Multi_Label*)(item->label()));
112
if (j == imap->end())
115
Fl_Multi_Label* mlabel = j->first;
116
Fl_Image** images = j->second;
117
unsigned char i = !item->active();
119
if (!images[i]) { // create inactive version of other image
120
images[i] = images[!i]->copy();
121
images[i]->inactive();
123
if (mlabel->typea == _FL_IMAGE_LABEL)
124
mlabel->labela = (const char*)images[i];
126
mlabel->labelb = (const char*)images[i];
127
item->image(images[i]);
129
item->labeltype(_FL_MULTI_LABEL);
133
void set_icon_label(Fl_Menu_Item* item)
136
set_icon_label_(item);
138
// this isn't needed but it simplifies fldigi's UI setup code
139
if (item->labeltype() == _FL_MULTI_LABEL)
140
item->labeltype(FL_NORMAL_LABEL);
144
void set_icon_label(Fl_Widget* w)
150
if (w->labeltype() == _FL_MULTI_LABEL)
151
w->labeltype(FL_NORMAL_LABEL);
155
void toggle_icon_labels(void)
158
for (imap_t::iterator i = imap->begin(); i != imap->end(); ++i) {
160
const char* l = i->first->labela;
161
i->first->labela = i->first->labelb;
162
i->first->labelb = l;
163
if (i->first->typea == _FL_IMAGE_LABEL) {
164
i->first->typea = FL_NORMAL_LABEL;
165
i->first->typeb = FL_EMPTY_LABEL;
169
i->first->typea = _FL_IMAGE_LABEL;
170
i->first->typeb = FL_NORMAL_LABEL;
178
template <typename T>
179
const char* get_icon_label_text_(T* item)
182
if (item->labeltype() == _FL_MULTI_LABEL) {
183
imap_t::iterator i = imap->find((Fl_Multi_Label*)(item->label()));
184
if (i == imap->end())
186
if (i->first->typeb == FL_NORMAL_LABEL)
187
return i->first->labelb + 1;
188
else // disabled icons
189
return i->first->labela;
193
return item->label();
196
const char* get_icon_label_text(Fl_Menu_Item* item)
198
return get_icon_label_text_(item);
200
const char* get_icon_label_text(Fl_Widget* w)
202
return get_icon_label_text_(w);
205
template <typename T>
206
void free_icon_label_(T* item)
209
if (item->labeltype() == FL_NORMAL_LABEL) {
210
delete [] item->label();
215
imap_t::iterator i = imap->find((Fl_Multi_Label*)item->label());
216
if (i == imap->end())
226
// delete the multi label
227
delete [] ((i->first->typeb == FL_NORMAL_LABEL) ? i->first->labelb : i->first->labela-1);
234
void free_icon_label(Fl_Menu_Item* item) { free_icon_label_(item); }
235
void free_icon_label(Fl_Widget* w) { free_icon_label_(w); }
237
template <typename T>
238
void set_active_(T* t, bool v) {
243
if (t->labeltype() == _FL_MULTI_LABEL)
247
void set_active(Fl_Menu_Item* item, bool v) { set_active_(item, v); }
248
void set_active(Fl_Widget* w, bool v) { set_active_(w, v); }
250
static Fl_Image* msg_icon;
251
void set_message_icon(const char** pixmap)
253
if (msg_icon && msg_icon->data() == pixmap)
257
Fl_Widget* msg = fl_message_icon();
259
msg->align(FL_ALIGN_TOP_LEFT | FL_ALIGN_INSIDE);
260
msg->color(msg->parent()->color());
262
msg->image(msg_icon = new Fl_Pixmap(pixmap));