1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 //              David Freese, W1HKJ
4 //
5 //
6 // This is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This software is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 // ----------------------------------------------------------------------------
19 
20 #ifndef _FL_COMBOBOX_H
21 #define _FL_COMBOBOX_H
22 
23 #include <string>
24 
25 #include <FL/Fl_Window.H>
26 #include <FL/Fl_Group.H>
27 #include <FL/Fl_Button.H>
28 #include <FL/Fl_Select_Browser.H>
29 #include <FL/Fl_Input.H>
30 #include <FL/Fl_Return_Button.H>
31 #include <FL/Fl_Box.H>
32 
33 #define FL_COMBO_UNIQUE 1
34 #define FL_COMBO_UNIQUE_NOCASE 2
35 #define FL_COMBO_LIST_INCR 100
36 
37 class Fl_ComboBox;
38 
39 enum {COMBOBOX, LISTBOX};
40 
41 struct datambr {
42   char *s;
43   void *d;
44 };
45 
46 class Fl_PopBrowser : public Fl_Window {
47 
48 friend void popbrwsr_cb(Fl_Widget *, long);
49 
50 	Fl_Select_Browser *popbrwsr;
51 	int hRow;
52 	int wRow;
53 	std::string keystrokes;
54 
55 public:
56 	Fl_PopBrowser (int x, int y, int w, int h, const char *label);
57 	~Fl_PopBrowser ();
58 	void popshow (int, int);
59 	void pophide ();
60 	void popbrwsr_cb_i (Fl_Widget *, long);
61 
62 	void add (char *s, void *d = 0);
63 	void clear ();
64 	void sort ();
65 	int  handle (int);
clear_kbd()66 	void clear_kbd() { keystrokes.clear(); }
67 
68 	Fl_ComboBox *parentCB;
69 	Fl_Widget *parentWindow;
70 
71 };
72 
73 class Fl_ComboBox : public Fl_Group  {
74   friend int DataCompare (const void *, const void *);
75   friend class Fl_PopBrowser;
76   friend void val_callback(Fl_Widget *, void *);
77 
78 	Fl_Button		*btn;
79 	Fl_Box			*valbox;
80 	Fl_Input		*val;
81 	Fl_PopBrowser	*Brwsr;
82 	datambr			**datalist;
83 	int				listsize;
84 	int				maxsize;
85 	int				listtype;
86 	int				numrows_;
87 	int				type_;
88 
89 	int				width;
90 	int				height;
91 	void			*retdata;
92 	int				idx;
93 	Fl_Color		_color;
94 	void			insert(const char *, void *);
95 
96 public:
97 
98 	Fl_ComboBox (int x, int y, int w, int h, const char *lbl = 0,
99 		int wtype = COMBOBOX);
100 	~Fl_ComboBox();
101 
102 	const char *value ();
103 	void value (std::string);
104 	void put_value( const char *);
105 	void fl_popbrwsr(Fl_Widget *);
106 
107 	void type (int = 0);
108 	void add (const char *s, void *d = 0);
109 	void clear ();
clear_entry()110 	void clear_entry() {
111 		if (type_ == LISTBOX) {
112 			valbox->label("");
113 			valbox->redraw_label();
114 		} else {
115 			val->value("");
116 			val->redraw();
117 		}
118 	}
119 	void sort ();
120 	int  index ();
121 	void index (int i);
122 	int  find_index(const char *str);
123 	void *data ();
124 	void textfont (int);
125 	void textsize (uchar);
126 	void textcolor (Fl_Color c);
127 	void color (Fl_Color c);
128 	void readonly(bool yes = true);
numrows()129 	int  numrows() { return numrows_; }
numrows(int n)130 	void numrows(int n) { numrows_ = n; }
lsize()131 	int  lsize() { return listsize; }
set_focus()132 	void set_focus() { Fl::focus(btn); };
133 	void position(int n);
labelfont(Fl_Font fnt)134 	void labelfont(Fl_Font fnt) { Fl_Group::labelfont(fnt); }
labelfont()135 	Fl_Font labelfont() { return Fl_Group::labelfont(); }
labelsize(Fl_Fontsize n)136 	void labelsize(Fl_Fontsize n) { Fl_Group::labelsize(n); }
labelsize()137 	Fl_Fontsize labelsize() { return Fl_Group::labelsize(); }
138 
139 	int handle(int);
140 
141 // Custom resize behavior -- input stretches, button doesn't
val_x()142 	inline int val_x() { return x(); }
val_y()143 	inline int val_y() { return y(); }
val_w()144 	inline int val_w() { return w() - h(); }
val_h()145 	inline int val_h() { return h(); }
146 
btn_x()147 	inline int btn_x() { return x() + w() - h(); }
btn_y()148 	inline int btn_y() { return y(); }
btn_w()149 	inline int btn_w() { return h(); }
btn_h()150 	inline int btn_h() { return h(); }
151 
resize(int X,int Y,int W,int H)152 	void resize(int X, int Y, int W, int H) {
153 		Fl_Group::resize(X,Y,W,H);
154 		if (type_ == LISTBOX)
155 			valbox->resize(val_x(), val_y(), val_w(), val_h());
156 		else
157 			val->resize(val_x(), val_y(), val_w(), val_h());
158 		btn->resize(btn_x(), btn_y(), btn_w(), btn_h());
159 	}
160 
161 };
162 
163 class Fl_ListBox : public Fl_ComboBox {
164 public:
165 	Fl_ListBox (int x, int y, int w, int h, const char *lbl = 0) :
Fl_ComboBox(x,y,w,h,lbl,LISTBOX)166 		Fl_ComboBox(x,y,w,h,lbl,LISTBOX) {};
~Fl_ListBox()167 	~Fl_ListBox() {};
168 };
169 
170 #endif
171