DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2756
Version: 1.3-feature


Attached file "checkbox-browser-fix-hscroll.patch"...


Link: http://www.fltk.org/str.php?L2756
Version: 1.3-feature
Index: FL/Enumerations.H
===================================================================
--- FL/Enumerations.H   (revision 9180)
+++ FL/Enumerations.H   (working copy)
@@ -299,7 +299,7 @@
  */
 enum Fl_When { // Fl_Widget::when():
   FL_WHEN_NEVER                = 0,    ///< Never call the callback
-  FL_WHEN_CHANGED      = 1,    ///< Do the callback only when the widget value 
changes
+  FL_WHEN_CHANGED      = 1,    ///< Do the callback only when the widget value 
changes (or checkbox changes)
   FL_WHEN_NOT_CHANGED  = 2,    ///< Do the callback whenever the user 
interacts with the widget
   FL_WHEN_RELEASE      = 4,    ///< Do the callback when the button or key is 
released and the value changes
   FL_WHEN_RELEASE_ALWAYS= 6,   ///< Do the callback when the button or key is 
released, even if the value doesn't change
Index: FL/Fl_Browser.H
===================================================================
--- FL/Fl_Browser.H     (revision 9180)
+++ FL/Fl_Browser.H     (working copy)
@@ -29,8 +29,6 @@
 #include "Fl_Browser_.H"
 #include "Fl_Image.H"
 
-struct FL_BLINE;
-
 /**
   The Fl_Browser widget displays a scrolling list of text
   lines, and manages all the storage for the text.  This is not a text
@@ -78,7 +76,20 @@
   For more info, see find_item(int).
 */
 class FL_EXPORT Fl_Browser : public Fl_Browser_ {
+protected:
 
+  struct FL_BLINE {    // data is in a linked list of these
+    FL_BLINE* prev;
+    FL_BLINE* next;
+    void* data;
+    Fl_Image* icon;
+    short length;              // sizeof(txt)-1, may be longer than string
+    char flags;                // selected, displayed
+    char txt[1];               // start of allocated array
+  };
+
+private:
+
   FL_BLINE *first;             // the array of lines
   FL_BLINE *last;
   FL_BLINE *cache;
@@ -90,7 +101,11 @@
   char column_char_;           // alternative to tab
 
 protected:
+  static const int SELECTED =     1;
+  static const int NOTDISPLAYED = 2;
+  static const int CHECKED =      4;
 
+
   // required routines for Fl_Browser_ subclass:
   void* item_first() const ;
   void* item_next(void* item) const ;
Index: FL/Fl_Browser_.H
===================================================================
--- FL/Fl_Browser_.H    (revision 9180)
+++ FL/Fl_Browser_.H    (working copy)
@@ -34,6 +34,7 @@
 #define FL_SELECT_BROWSER      1       /**< type() of FL_Select_Browser */
 #define FL_HOLD_BROWSER                2       /**< type() of Fl_Hold_Browser 
*/
 #define FL_MULTI_BROWSER       3       /**< type() of Fl_Multi_Browser */
+#define FL_CHECKBOX_BROWSER    4       /**< type() of Fl_Multi_Browser */
 
 #define FL_SORT_ASCENDING      0       /**< sort browser items in ascending 
alphabetic order. */
 #define FL_SORT_DESCENDING     1       /**< sort in descending order */
@@ -71,11 +72,20 @@
   void *redraw1,*redraw2; // minimal update pointers
   void* max_width_item;        // which item has max_width_
   int scrollbar_size_; // size of scrollbar trough
+  int flags_ex_;  // extended flags for class
 
+
+
+  static const int FLAG_EX_CHECK_CHANGED=4;      // checkbox item check changed
+
   void update_top();
 
 protected:
 
+  inline int check_size(void) const { return textsize()-2; };
+  inline int check_pre_gap(void) const { return 2; };
+  inline int check_post_gap(void) const { return 5; };
+
   // All of the following must be supplied by the subclass:
   /**
     This method must be provided by the subclass 
@@ -200,6 +210,9 @@
   int select(void *item,int val=1,int docallbacks=0);
   int select_only(void *item,int docallbacks=0);
   int deselect(int docallbacks=0);
+
+  virtual void checked(void *item,int val);
+
   /**
     Gets the vertical scroll position of the list as a pixel position \p pos.
     The position returned is how many pixels of the list are scrolled off the 
top edge
@@ -360,6 +373,19 @@
   */
   void scrollbar_left() { scrollbar.align(FL_ALIGN_LEFT); }
   void sort(int flags=0);
+
+  /**
+    set/clear/check the checked status flag.  The internal handler
+    sets the check_changed() flag.  The application programmer
+    needs to clear_check_changed() if they want to monitor the
+    check_changed() flag.
+  */
+ protected:
+  void set_check_changed() { flags_ex_|=FLAG_EX_CHECK_CHANGED; };
+ public:
+  void clear_check_changed() { flags_ex_&=~FLAG_EX_CHECK_CHANGED; };
+  bool check_changed() { return (flags_ex_ & FLAG_EX_CHECK_CHANGED)!=0; };
+
 };
 
 #endif
Index: FL/Fl_Checkbox_Browser.H
===================================================================
--- FL/Fl_Checkbox_Browser.H    (revision 0)
+++ FL/Fl_Checkbox_Browser.H    (working copy)
@@ -0,0 +1,76 @@
+//
+// "$Id: Fl_Checkbox_Browser.H 8736 2011-05-24 20:00:56Z AlbrechtS $"
+//
+// Checkbox browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2011 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+/* \file
+   Fl_Checkbox_Browser widget . */
+
+#ifndef Fl_Checkbox_Browser_H
+#define Fl_Checkbox_Browser_H
+
+#include "Fl_Browser.H"
+
+/**
+  The Fl_Checkbox_Browser is a subclass of Fl_Browser
+  which lets the user select a single item, or no items by clicking on
+  the empty space as well as check boxes on items.  As long as the mouse
+  button is held down the item pointed to by it is highlighted, and this
+  highlighting remains on when the mouse button is released. Normally the
+  callback is done when the user releases the mouse, but you can change
+  this with when().
+  <P>See Fl_Browser for methods to add and remove lines from the browser.
+*/
+class FL_EXPORT Fl_Checkbox_Browser : public Fl_Browser {
+  int nchecked_;
+
+public:
+  /**
+    Creates a new Fl_Checkbox_Browser widget using the given
+    position, size, and label string. The default boxtype is FL_DOWN_BOX.
+    The constructor specializes Fl_Browser() by setting the type to 
FL_CHECKBOX_BROWSER.
+    The destructor destroys the widget and frees all memory that has been 
allocated.
+ */
+  Fl_Checkbox_Browser(int X,int Y,int W,int H,const char *L=0);
+
+  int nchecked() const { return nchecked_; }
+  void checked(void *item,int val);
+
+  /** Gets the current status of item item. */
+  int checked(int i) const;
+  /** Sets the check status of item item to b. */
+  void checked(int i, int b);
+  /**  Sets all the items checked.*/
+  void check_all();
+  /**  Sets all the items unchecked.*/
+  void check_none();
+
+};
+
+#endif
+
+//
+// End of "$Id: Fl_Checkbox_Browser.H 8736 2011-05-24 20:00:56Z AlbrechtS $".
+//
Index: src/Fl_Browser.cxx
===================================================================
--- src/Fl_Browser.cxx  (revision 9180)
+++ src/Fl_Browser.cxx  (working copy)
@@ -27,6 +27,7 @@
 #include <FL/Fl_Hold_Browser.H>
 #include <FL/Fl_Multi_Browser.H>
 #include <FL/Fl_Select_Browser.H>
+#include <FL/Fl_Checkbox_Browser.H>
 #endif
 
 // I modified this from the original Forms data to use a linked list
@@ -38,24 +39,6 @@
 // Also added the ability to "hide" a line. This sets its height to
 // zero, so the Fl_Browser_ cannot pick it.
 
-#define SELECTED 1
-#define NOTDISPLAYED 2
-
-// WARNING:
-//       Fl_File_Chooser.cxx also has a definition of this structure 
(FL_BLINE).
-//       Changes to FL_BLINE *must* be reflected in Fl_File_Chooser.cxx as 
well.
-//       This hack in Fl_File_Chooser should be solved.
-//
-struct FL_BLINE {      // data is in a linked list of these
-  FL_BLINE* prev;
-  FL_BLINE* next;
-  void* data;
-  Fl_Image* icon;
-  short length;                // sizeof(txt)-1, may be longer than string
-  char flags;          // selected, displayed
-  char txt[1];         // start of allocated array
-};
-
 /**
   Returns the very first item in the list.
   Example of use:
@@ -145,7 +128,7 @@
   \retval NULL if line is out of range.
   \see item_at(), find_line(), lineno()
 */
-FL_BLINE* Fl_Browser::find_line(int line) const {
+Fl_Browser::FL_BLINE* Fl_Browser::find_line(int line) const {
   int n; FL_BLINE* l;
   if (line == cacheline) return cache;
   if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) {
@@ -204,7 +187,7 @@
   \returns Pointer to browser item that was removed (and is no longer valid).
   \see add(), insert(), remove(), swap(int,int), clear()
 */
-FL_BLINE* Fl_Browser::_remove(int line) {
+Fl_Browser::FL_BLINE* Fl_Browser::_remove(int line) {
   FL_BLINE* ttt = find_line(line);
   deleting(ttt);
 
@@ -466,7 +449,15 @@
   if (*str == format_char_ && str[1])
     str ++;
 
-  if (ww==0 && l->icon) ww = l->icon->w();
+  // the icon and checkbox are part of column 1 otherwise we need
+  // to include their width when no columns exist.
+  if (ww==0) {
+    if (l->icon) ww = l->icon->w();
+    if (type()==FL_CHECKBOX_BROWSER) {
+      // -6 because the +6 seems to make things scroll too far
+      ww+=check_size()+check_pre_gap()+check_post_gap()-6;
+    }
+  }
 
   fl_font(font, tsize);
   return ww + int(fl_width(str)) + 6;
@@ -515,18 +506,67 @@
       e = strchr(str, column_char());
       if (e) {*e = 0; w1 = *i++;}
     }
-    // Icon drawing code
+
+    int tsize = textsize();
+    Fl_Color lcol = textcolor();
+
+    // Icon/Checkbox drawing code
     if (first) {
       first = false;
+      // Checkbox - ideally we should have the icon and checkbox
+      // dedicated to its own column (or not part of any column)
+      // so that changing column widths couldn't prevent those
+      // from showing.  In fact it may be better if each
+      // class had a virtual item_draw that took care of only
+      // what it needs, then adjusts X,W and passes to the base
+      // class.  however, i'm just adding checkboxes to the
+      // existing flow.
+      if (type()==FL_CHECKBOX_BROWSER) {
+        // ignore if won't fit
+        if (W<check_size()+check_pre_gap()) {
+          break;
+        }
+        // setup the colors for the checkbox (using same logical from below
+        // where text is drawn).
+        if (l->flags & SELECTED) {
+          lcol = fl_contrast(lcol, selection_color());
+        }
+        if (!active_r()) lcol = fl_inactive(lcol);
+        fl_color(lcol);
+        // using the checkbox drawing logic from Fl_Check_Browser
+        int cy = Y + ((textsize() + 1 - check_size()) / 2);
+        fl_loop(X+check_pre_gap(), cy, X+check_pre_gap(), cy + check_size(),
+                X + check_pre_gap()+check_size(), cy + check_size(), X + 
check_pre_gap()+check_size(), cy);
+        if (l->flags & CHECKED) {
+          int tx = X + check_pre_gap()+3;
+          int tw = check_size() - 4;
+          int d1 = tw/3;
+          int d2 = tw-d1;
+          int ty = cy + (check_size()+d2)/2-d1-2;
+          for (int n = 0; n < 3; n++, ty++) {
+            fl_line(tx, ty, tx+d1, ty+d1);
+            fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
+          }
+        }
+        // adjust available area for next item to be drawn on line
+        X+=check_pre_gap() + check_size() + check_post_gap();
+        W-=check_pre_gap()+check_size() + check_post_gap();
+        w1-=check_pre_gap()+check_size() + check_post_gap();
+        // shouldn't the width of the icon or text be checked and aborted or
+        // clipped if won't fit the column width since X, W and w1 is ajusted
+        // again with the icon then finally used with fldraw w1-6 which could
+        // end up negative (is that a problem for fl_draw?)
+      }
+      // Icon
       if (l->icon) {
        l->icon->draw(X+2,Y+1); // leave 2px left, 1px above
        int iconw = l->icon->w()+2;
        X += iconw; W -= iconw; w1 -= iconw;
       }
     }
-    int tsize = textsize();
+
+    lcol = textcolor();
     Fl_Font font = textfont();
-    Fl_Color lcol = textcolor();
     Fl_Align talign = FL_ALIGN_LEFT;
     // check for all the @-lines recognized by XForms:
     //#if defined(__GNUC__)
@@ -930,6 +970,9 @@
   Fl_Select_Browser::Fl_Select_Browser(int X,int Y,int W,int H,const char *L)
        : Fl_Browser(X,Y,W,H,L) {type(FL_SELECT_BROWSER);}
 
+  Fl_Checkbox_Browser::Fl_Checkbox_Browser(int X,int Y,int W,int H,const char 
*L)
+       : Fl_Browser(X,Y,W,H,L) {nchecked_=0; type(FL_CHECKBOX_BROWSER);}
+
 #endif // FL_DLL
 
 //
Index: src/Fl_Browser_.cxx
===================================================================
--- src/Fl_Browser_.cxx (revision 9180)
+++ src/Fl_Browser_.cxx (working copy)
@@ -708,7 +708,7 @@
     void* l1 = selection_;
     void* l = l1; if (!l) l = top_; if (!l) l = item_first();
     if (l) {
-      if (type()==FL_HOLD_BROWSER) {
+      if (type()==FL_HOLD_BROWSER || type()==FL_CHECKBOX_BROWSER) {
         switch (Fl::event_key()) {
         case FL_Down:
           while ((l = item_next(l)))
@@ -722,6 +722,11 @@
            }
          }
           return 1;
+          case ' ':
+            if (type()==FL_CHECKBOX_BROWSER) {
+              checked(l, -1);
+              return 1;
+            }
         } 
       } else  {
         switch (Fl::event_key()) {
@@ -801,13 +806,22 @@
     if (type() == FL_NORMAL_BROWSER || !top_)
       ;
     else if (type() != FL_MULTI_BROWSER) {
-      change = select_only(find_item(my), 0);
+      void *l=find_item(my);
+      change = select_only(l, 0);
       if (wp.deleted()) return 1;
       if (change && (when() & FL_WHEN_CHANGED)) {
        set_changed();
        do_callback();
        if (wp.deleted()) return 1;
       }
+      // handle check box clicks
+      if (l && type()==FL_CHECKBOX_BROWSER) {
+        // check for click within a checkbox
+        if (Fl::event_inside(X,Y, 
check_size()+check_pre_gap()+check_post_gap(), H)) {
+          checked(l, -1);
+          if (wp.deleted()) return 1;
+        }
+      }
     } else {
       void* l = find_item(my);
       whichway = 1;
@@ -974,6 +988,7 @@
   max_width_item = 0;
   scrollbar_size_ = 0;
   redraw1 = redraw2 = 0;
+  flags_ex_= 0;
   end();
 }
 
@@ -1093,6 +1108,15 @@
 */
 int Fl_Browser_::item_selected(void* item) const { return item==selection_ ? 1 
: 0; }
 
+/**
+  change the checked status of item
+
+  \param[in] item The item whose checked state is to be changed
+  \param[in] val The new checked state (1=checked, 0=not checked, -1=toggle)
+*/
+void Fl_Browser_::checked(void *item,int val) { }
+
+
 //
 // End of "$Id$".
 //
Index: src/Fl_Checkbox_Browser.cxx
===================================================================
--- src/Fl_Checkbox_Browser.cxx (revision 0)
+++ src/Fl_Checkbox_Browser.cxx (working copy)
@@ -0,0 +1,122 @@
+//
+// "$Id: Fl_Checkbox_Browser.cxx 8354 2011-02-01 15:41:04Z manolo $"
+//
+// Fl_Checkbox_Browser header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+#include <FL/fl_draw.H>
+#include <FL/Fl_Checkbox_Browser.H>
+
+Fl_Checkbox_Browser::Fl_Checkbox_Browser(int X,int Y,int W,int H,const char *L)
+                    : Fl_Browser(X,Y,W,H,L)
+{
+  nchecked_=0;
+  type(FL_CHECKBOX_BROWSER);
+}
+
+
+/** Gets the current status of item item. */
+int Fl_Checkbox_Browser::checked(int i) const {
+       FL_BLINE *p = find_line(i);
+
+       if (p) return (p->flags & CHECKED)!=0;
+       return 0;
+}
+
+/** Sets the check status of item item to b. */
+void Fl_Checkbox_Browser::checked(int i, int b) {
+  checked(find_line(i), b);
+}
+
+/**  Sets all the items checked.*/
+void Fl_Checkbox_Browser::check_all() {
+       FL_BLINE *p;
+
+       nchecked_ = size();
+       for (p = (FL_BLINE*)item_first(); p; p = p->next) {
+               p->flags |= CHECKED;
+       }
+       redraw();
+}
+
+/**  Sets all the items unchecked.*/
+void Fl_Checkbox_Browser::check_none() {
+       FL_BLINE *p;
+
+       nchecked_ = 0;
+       for (p = (FL_BLINE*)item_first(); p; p = p->next) {
+               p->flags &= ~CHECKED;
+       }
+       redraw();
+}
+
+/**
+  change the checked status of item
+
+  \param[in] item The item whose checked state is to be changed
+  \param[in] val The new checked state (1=checked, 0=not checked, -1=toggle)
+*/
+void Fl_Checkbox_Browser::checked(void *item,int val)
+{
+  FL_BLINE *p=(FL_BLINE*) item;
+
+       if (p) {
+         int updated=0;
+         if (val<0) {
+           updated=1;
+           if (p->flags & CHECKED) {
+             p->flags&=~CHECKED;
+             nchecked_--;
+           }
+           else {
+             p->flags|=CHECKED;
+             nchecked_++;
+           }
+         }
+         else if (val>0 && (p->flags & CHECKED)==0) {
+           updated=1;
+           p->flags |= CHECKED;
+           nchecked_++;
+         }
+         else if (val==0 && (p->flags & CHECKED)) {
+           updated=1;
+           p->flags &= ~CHECKED;
+           nchecked_--;
+         }
+         if (updated) {
+                 redraw();
+      set_check_changed();
+                 if (when() & FL_WHEN_CHANGED) {
+                   do_callback();
+                 }
+         }
+       }
+}
+
+//
+// End of "$Id: Fl_Checkbox_Browser.cxx 8354 2011-02-01 15:41:04Z manolo $".
+//
Index: src/Fl_File_Browser.cxx
===================================================================
--- src/Fl_File_Browser.cxx     (revision 9180)
+++ src/Fl_File_Browser.cxx     (working copy)
@@ -69,24 +69,7 @@
 #define SELECTED 1
 #define NOTDISPLAYED 2
 
-// TODO -- Warning: The definition of FL_BLINE here is a hack.
-//    Fl_File_Browser should not do this. PLEASE FIX.
-//    FL_BLINE should be private to Fl_Browser, and not re-defined here.
-//    For now, make sure this struct is precisely consistent with 
Fl_Browser.cxx.
 //
-struct FL_BLINE                        // data is in a linked list of these
-{
-  FL_BLINE     *prev;          // Previous item in list
-  FL_BLINE     *next;          // Next item in list
-  void         *data;          // Pointer to data (function)
-  Fl_Image      *icon;         // Pointer to optional icon
-  short                length;         // sizeof(txt)-1, may be longer than 
string
-  char         flags;          // selected, displayed
-  char         txt[1];         // start of allocated array
-};
-
-
-//
 // 'Fl_File_Browser::full_height()' - Return the height of the list.
 //
 
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to