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)  

Fl_Check_Browser.cxx

Go to the documentation of this file.
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 //