themes: Workaround for bug where a background color of RGB 0,0,0 in Black color schem...
[ntk.git] / src / Fl_Check_Browser.cxx
blob4355119a74d401e9ea64b624255c30bdef7332c1
1 //
2 // "$Id: Fl_Check_Browser.cxx 8354 2011-02-01 15:41:04Z manolo $"
3 //
4 // Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include "flstring.h"
31 #include <FL/fl_draw.H>
32 #include <FL/Fl_Check_Browser.H>
34 /* This uses a cache for faster access when you're scanning the list
35 either forwards or backwards. */
37 Fl_Check_Browser::cb_item *Fl_Check_Browser::find_item(int n) const {
38 int i = n;
39 cb_item *p = first;
41 if (n <= 0 || n > nitems_ || p == 0) {
42 return 0;
45 if (n == cached_item) {
46 p = cache;
47 n = 1;
48 } else if (n == cached_item + 1) {
49 p = cache->next;
50 n = 1;
51 } else if (n == cached_item - 1) {
52 p = cache->prev;
53 n = 1;
56 while (--n) {
57 p = p->next;
60 /* Cast to not const and cache it. */
62 ((Fl_Check_Browser *)this)->cache = p;
63 ((Fl_Check_Browser *)this)->cached_item = i;
65 return p;
68 int Fl_Check_Browser::lineno(cb_item *p0) const {
69 cb_item *p = first;
71 if (p == 0) {
72 return 0;
75 int i = 1;
76 while (p) {
77 if (p == p0) {
78 return i;
80 i++;
81 p = p->next;
84 return 0;
87 Fl_Check_Browser::Fl_Check_Browser(int X, int Y, int W, int H, const char *l)
88 /** The constructor makes an empty browser.*/
89 : Fl_Browser_(X, Y, W, H, l) {
90 type(FL_SELECT_BROWSER);
91 when(FL_WHEN_NEVER);
92 first = last = 0;
93 nitems_ = nchecked_ = 0;
94 cached_item = -1;
97 void *Fl_Check_Browser::item_first() const {
98 return first;
101 void *Fl_Check_Browser::item_next(void *l) const {
102 return ((cb_item *)l)->next;
105 void *Fl_Check_Browser::item_prev(void *l) const {
106 return ((cb_item *)l)->prev;
109 int Fl_Check_Browser::item_height(void *) const {
110 return textsize() + 2;
113 #define CHECK_SIZE (textsize()-2)
115 int Fl_Check_Browser::item_width(void *v) const {
116 fl_font(textfont(), textsize());
117 return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8;
120 void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const {
121 cb_item *i = (cb_item *)v;
122 char *s = i->text;
123 int tsize = textsize();
124 Fl_Color col = active_r() ? textcolor() : fl_inactive(textcolor());
125 int cy = Y + (tsize + 1 - CHECK_SIZE) / 2;
126 X += 2;
128 fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR));
129 fl_loop(X, cy, X, cy + CHECK_SIZE,
130 X + CHECK_SIZE, cy + CHECK_SIZE, X + CHECK_SIZE, cy);
131 if (i->checked) {
132 int tx = X + 3;
133 int tw = CHECK_SIZE - 4;
134 int d1 = tw/3;
135 int d2 = tw-d1;
136 int ty = cy + (CHECK_SIZE+d2)/2-d1-2;
137 for (int n = 0; n < 3; n++, ty++) {
138 fl_line(tx, ty, tx+d1, ty+d1);
139 fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
142 fl_font(textfont(), tsize);
143 if (i->selected) {
144 col = fl_contrast(col, selection_color());
146 fl_color(col);
147 fl_draw(s, X + CHECK_SIZE + 8, Y + tsize - 1);
150 void Fl_Check_Browser::item_select(void *v, int state) {
151 cb_item *i = (cb_item *)v;
153 if (state) {
154 if (i->checked) {
155 i->checked = 0;
156 nchecked_--;
157 } else {
158 i->checked = 1;
159 nchecked_++;
164 int Fl_Check_Browser::item_selected(void *v) const {
165 cb_item *i = (cb_item *)v;
166 return i->selected;
169 Add a new unchecked line to the end of the browser.
170 \see add(char *s, int b)
172 int Fl_Check_Browser::add(char *s) {
173 return (add(s, 0));
176 /**
177 Add a new line to the end of the browser. The text is copied
178 using the strdup() function. It may also be NULL to make
179 a blank line. It can set the item checked if \p b is not 0.
181 int Fl_Check_Browser::add(char *s, int b) {
182 cb_item *p = (cb_item *)malloc(sizeof(cb_item));
183 p->next = 0;
184 p->prev = 0;
185 p->checked = b;
186 p->selected = 0;
187 p->text = strdup(s);
189 if (b) {
190 nchecked_++;
193 if (last == 0) {
194 first = last = p;
195 } else {
196 last->next = p;
197 p->prev = last;
198 last = p;
200 nitems_++;
202 return (nitems_);
206 Remove line n and make the browser one line shorter. Returns the
207 number of lines left in the browser.
209 int Fl_Check_Browser::remove(int item) {
210 cb_item *p = find_item(item);
212 // line at item exists
213 if(p) {
214 // tell the Browser_ what we will do
215 deleting(p);
217 // fix checked count
218 if(p->checked)
219 --nchecked_;
221 // remove the node
222 if (p->prev)
223 p->prev->next = p->next;
224 else
225 first = p->next;
226 if (p->next)
227 p->next->prev = p->prev;
228 else
229 last = p->prev;
231 free(p->text);
232 free(p);
234 --nitems_;
235 cached_item = -1;
238 return (nitems_);
241 /** Remove every item from the browser.*/
242 void Fl_Check_Browser::clear() {
243 cb_item *p = first;
244 cb_item *next;
246 if (p == 0) {
247 return;
250 new_list();
251 do {
252 next = p->next;
253 free(p->text);
254 free(p);
255 p = next;
256 } while (p);
258 first = last = 0;
259 nitems_ = nchecked_ = 0;
260 cached_item = -1;
263 /** Gets the current status of item item. */
264 int Fl_Check_Browser::checked(int i) const {
265 cb_item *p = find_item(i);
267 if (p) return p->checked;
268 return 0;
271 /** Sets the check status of item item to b. */
272 void Fl_Check_Browser::checked(int i, int b) {
273 cb_item *p = find_item(i);
275 if (p && (p->checked ^ b)) {
276 p->checked = b;
277 if (b) {
278 nchecked_++;
279 } else {
280 nchecked_--;
282 redraw();
286 /** Returns the index of the currently selected item.*/
287 int Fl_Check_Browser::value() const {
288 return lineno((cb_item *)selection());
291 /** Return a pointer to an internal buffer holding item item's text.*/
292 char *Fl_Check_Browser::text(int i) const {
293 cb_item *p = find_item(i);
295 if (p) return p->text;
296 return 0;
299 /** Sets all the items checked.*/
300 void Fl_Check_Browser::check_all() {
301 cb_item *p;
303 nchecked_ = nitems_;
304 for (p = first; p; p = p->next) {
305 p->checked = 1;
307 redraw();
310 /** Sets all the items unchecked.*/
311 void Fl_Check_Browser::check_none() {
312 cb_item *p;
314 nchecked_ = 0;
315 for (p = first; p; p = p->next) {
316 p->checked = 0;
318 redraw();
321 int Fl_Check_Browser::handle(int event) {
322 if (event==FL_PUSH)
323 deselect();
324 return Fl_Browser_::handle(event);
328 // End of "$Id: Fl_Check_Browser.cxx 8354 2011-02-01 15:41:04Z manolo $".