|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_Check_Browser.cxx 7903 2010-11-28 21:06:39Z matt $" 00003 // 00004 // Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 #include <stdio.h> 00029 #include <stdlib.h> 00030 #include "flstring.h" 00031 #include <FL/fl_draw.H> 00032 #include <FL/Fl_Check_Browser.H> 00033 00034 /* This uses a cache for faster access when you're scanning the list 00035 either forwards or backwards. */ 00036 00037 Fl_Check_Browser::cb_item *Fl_Check_Browser::find_item(int n) const { 00038 int i = n; 00039 cb_item *p = first; 00040 00041 if (n <= 0 || n > nitems_ || p == 0) { 00042 return 0; 00043 } 00044 00045 if (n == cached_item) { 00046 p = cache; 00047 n = 1; 00048 } else if (n == cached_item + 1) { 00049 p = cache->next; 00050 n = 1; 00051 } else if (n == cached_item - 1) { 00052 p = cache->prev; 00053 n = 1; 00054 } 00055 00056 while (--n) { 00057 p = p->next; 00058 } 00059 00060 /* Cast to not const and cache it. */ 00061 00062 ((Fl_Check_Browser *)this)->cache = p; 00063 ((Fl_Check_Browser *)this)->cached_item = i; 00064 00065 return p; 00066 } 00067 00068 int Fl_Check_Browser::lineno(cb_item *p0) const { 00069 cb_item *p = first; 00070 00071 if (p == 0) { 00072 return 0; 00073 } 00074 00075 int i = 1; 00076 while (p) { 00077 if (p == p0) { 00078 return i; 00079 } 00080 i++; 00081 p = p->next; 00082 } 00083 00084 return 0; 00085 } 00086 00087 Fl_Check_Browser::Fl_Check_Browser(int X, int Y, int W, int H, const char *l) 00089 : Fl_Browser_(X, Y, W, H, l) { 00090 type(FL_SELECT_BROWSER); 00091 when(FL_WHEN_NEVER); 00092 first = last = 0; 00093 nitems_ = nchecked_ = 0; 00094 cached_item = -1; 00095 } 00096 00097 void *Fl_Check_Browser::item_first() const { 00098 return first; 00099 } 00100 00101 void *Fl_Check_Browser::item_next(void *l) const { 00102 return ((cb_item *)l)->next; 00103 } 00104 00105 void *Fl_Check_Browser::item_prev(void *l) const { 00106 return ((cb_item *)l)->prev; 00107 } 00108 00109 int Fl_Check_Browser::item_height(void *) const { 00110 return textsize() + 2; 00111 } 00112 00113 #define CHECK_SIZE (textsize()-2) 00114 00115 int Fl_Check_Browser::item_width(void *v) const { 00116 fl_font(textfont(), textsize()); 00117 return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8; 00118 } 00119 00120 void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const { 00121 cb_item *i = (cb_item *)v; 00122 char *s = i->text; 00123 int tsize = textsize(); 00124 Fl_Color col = active_r() ? textcolor() : fl_inactive(textcolor()); 00125 int cy = Y + (tsize + 1 - CHECK_SIZE) / 2; 00126 X += 2; 00127 00128 fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); 00129 fl_loop(X, cy, X, cy + CHECK_SIZE, 00130 X + CHECK_SIZE, cy + CHECK_SIZE, X + CHECK_SIZE, cy); 00131 if (i->checked) { 00132 int tx = X + 3; 00133 int tw = CHECK_SIZE - 4; 00134 int d1 = tw/3; 00135 int d2 = tw-d1; 00136 int ty = cy + (CHECK_SIZE+d2)/2-d1-2; 00137 for (int n = 0; n < 3; n++, ty++) { 00138 fl_line(tx, ty, tx+d1, ty+d1); 00139 fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); 00140 } 00141 } 00142 fl_font(textfont(), tsize); 00143 if (i->selected) { 00144 col = fl_contrast(col, selection_color()); 00145 } 00146 fl_color(col); 00147 fl_draw(s, X + CHECK_SIZE + 8, Y + tsize - 1); 00148 } 00149 00150 void Fl_Check_Browser::item_select(void *v, int state) { 00151 cb_item *i = (cb_item *)v; 00152 00153 if (state) { 00154 if (i->checked) { 00155 i->checked = 0; 00156 nchecked_--; 00157 } else { 00158 i->checked = 1; 00159 nchecked_++; 00160 } 00161 } 00162 } 00163 00164 int Fl_Check_Browser::item_selected(void *v) const { 00165 cb_item *i = (cb_item *)v; 00166 return i->selected; 00167 } 00173 int Fl_Check_Browser::add(char *s) { 00174 return (add(s, 0)); 00175 } 00176 00178 int Fl_Check_Browser::add(char *s, int b) { 00179 cb_item *p = (cb_item *)malloc(sizeof(cb_item)); 00180 p->next = 0; 00181 p->prev = 0; 00182 p->checked = b; 00183 p->selected = 0; 00184 p->text = strdup(s); 00185 00186 if (b) { 00187 nchecked_++; 00188 } 00189 00190 if (last == 0) { 00191 first = last = p; 00192 } else { 00193 last->next = p; 00194 p->prev = last; 00195 last = p; 00196 } 00197 nitems_++; 00198 00199 return (nitems_); 00200 } 00201 00206 int Fl_Check_Browser::remove(int item) { 00207 cb_item *p = find_item(item); 00208 00209 // line at item exists 00210 if(p) { 00211 // tell the Browser_ what we will do 00212 deleting(p); 00213 00214 // fix checked count 00215 if(p->checked) 00216 --nchecked_; 00217 00218 // remove the node 00219 if (p->prev) 00220 p->prev->next = p->next; 00221 else 00222 first = p->next; 00223 if (p->next) 00224 p->next->prev = p->prev; 00225 else 00226 last = p->prev; 00227 00228 free(p->text); 00229 free(p); 00230 00231 --nitems_; 00232 cached_item = -1; 00233 } 00234 00235 return (nitems_); 00236 } 00237 00239 void Fl_Check_Browser::clear() { 00240 cb_item *p = first; 00241 cb_item *next; 00242 00243 if (p == 0) { 00244 return; 00245 } 00246 00247 new_list(); 00248 do { 00249 next = p->next; 00250 free(p->text); 00251 free(p); 00252 p = next; 00253 } while (p); 00254 00255 first = last = 0; 00256 nitems_ = nchecked_ = 0; 00257 cached_item = -1; 00258 } 00259 00261 int Fl_Check_Browser::checked(int i) const { 00262 cb_item *p = find_item(i); 00263 00264 if (p) return p->checked; 00265 return 0; 00266 } 00267 00269 void Fl_Check_Browser::checked(int i, int b) { 00270 cb_item *p = find_item(i); 00271 00272 if (p && (p->checked ^ b)) { 00273 p->checked = b; 00274 if (b) { 00275 nchecked_++; 00276 } else { 00277 nchecked_--; 00278 } 00279 redraw(); 00280 } 00281 } 00282 00284 int Fl_Check_Browser::value() const { 00285 return lineno((cb_item *)selection()); 00286 } 00287 00289 char *Fl_Check_Browser::text(int i) const { 00290 cb_item *p = find_item(i); 00291 00292 if (p) return p->text; 00293 return 0; 00294 } 00295 00297 void Fl_Check_Browser::check_all() { 00298 cb_item *p; 00299 00300 nchecked_ = nitems_; 00301 for (p = first; p; p = p->next) { 00302 p->checked = 1; 00303 } 00304 redraw(); 00305 } 00306 00308 void Fl_Check_Browser::check_none() { 00309 cb_item *p; 00310 00311 nchecked_ = 0; 00312 for (p = first; p; p = p->next) { 00313 p->checked = 0; 00314 } 00315 redraw(); 00316 } 00317 00318 int Fl_Check_Browser::handle(int event) { 00319 if (event==FL_PUSH) 00320 deselect(); 00321 return Fl_Browser_::handle(event); 00322 } 00323 00324 // 00325 // End of "$Id: Fl_Check_Browser.cxx 7903 2010-11-28 21:06:39Z matt $". 00326 //