]> git.lyx.org Git - features.git/commitdiff
Visual feedback of inactive toolbar buttons.
authorAngus Leeming <leeming@lyx.org>
Fri, 30 Apr 2004 17:30:19 +0000 (17:30 +0000)
committerAngus Leeming <leeming@lyx.org>
Fri, 30 Apr 2004 17:30:19 +0000 (17:30 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8716 a592a061-630c-0410-9148-cb99ea01b6c8

src/frontends/xforms/ChangeLog
src/frontends/xforms/XFormsToolbar.C
src/frontends/xforms/XFormsToolbar.h

index d7a35da6ae278010dbf43c7e0e6d5f0673fb3b05..b5506326125a0f5b07a6e6e7c13289681d1a1461 100644 (file)
@@ -1,3 +1,9 @@
+2004-04-30  Angus Leeming  <leeming@lyx.org>
+
+       * XFormsToolbar.[Ch]: add code to generate an 'inactive' version
+       of the icon pixmap and use it when the toolbar button is
+       disabled.
+
 2004-04-29  Angus Leeming  <leeming@lyx.org>
 
        * FormGraphics.C (apply): don't get caught in a loop when mapping
index 0bbaf0d7416b118a7d309440d033f34fcd7fef79..87766a6093c5d4377d5c98c450a6b7d0093fb42c 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "XFormsToolbar.h"
 
+#include "Color.h"
 #include "Tooltips.h"
 #include "xforms_helpers.h"
 
 #include "gettext.h"
 #include "lyxfunc.h"
 
+#include "support/lstrings.h"
+
 #include "lyx_forms.h"
+#include "lyx_xpm.h"
 #include "combox.h"
 
 #include <boost/bind.hpp>
@@ -34,6 +38,8 @@
 using lyx::frontend::Box;
 using lyx::frontend::BoxList;
 
+using lyx::support::compare_ascii_no_case;
+
 using std::distance;
 using std::endl;
 using std::string;
@@ -70,27 +76,33 @@ LyXTextClass const & getTextClass(LyXView const & lv)
 
 
 XFormsToolbar::toolbarItem::toolbarItem()
-       : icon(0)
+       : icon(0),
+         unused_pixmap(0),
+         active_pixmap(0),
+         active_mask(0),
+         inactive_pixmap(0),
+         inactive_mask(0)
 {}
 
 
 XFormsToolbar::toolbarItem::~toolbarItem()
 {
-       // Lars said here that ~XFormsView() dealt with the icons.
-       // This is not true. But enabling this causes crashes,
-       // because somehow we kill the same icon twice :(
-       // FIXME
-       //kill_icon();
+       kill_icon();
 }
 
 
 void XFormsToolbar::toolbarItem::kill_icon()
 {
-       if (icon) {
-               fl_delete_object(icon);
-               fl_free_object(icon);
-               icon = 0;
-       }
+       if (unused_pixmap)
+               // XForms will take care of cleaning up the other pixmap
+               XFreePixmap(fl_get_display(), unused_pixmap);
+
+       unused_pixmap = 0;
+       active_pixmap = 0;
+       active_mask = 0;
+       inactive_pixmap = 0;
+       inactive_mask = 0;
+       icon = 0;
 }
 
 
@@ -110,6 +122,62 @@ XFormsToolbar::toolbarItem::operator=(toolbarItem const & ti)
 }
 
 
+void XFormsToolbar::toolbarItem::generateInactivePixmaps()
+{
+       if (!icon || icon->objclass != FL_PIXMAPBUTTON)
+               return;
+
+       // Store the existing (active) pixmap.
+       fl_get_pixmap_pixmap(icon, &active_pixmap, &active_mask);
+
+       if (active_pixmap == 0 || active_mask == 0)
+               return;
+
+       // Create an XpmImage of this (active) pixmap. It's this that
+       // we're going to manipulate.
+       XpmImage xpm_image;
+       XpmCreateXpmImageFromPixmap(fl_get_display(),
+                                   active_pixmap,
+                                   active_mask,
+                                   &xpm_image,
+                                   0);
+
+       // Produce a darker shade of the button background as the
+       // inactive color. Note the 'hsv.v - 0.2'.
+       unsigned int r, g, b;
+       fl_getmcolor(FL_PIXMAPBUTTON_COL1, &r, &g, &b);
+       HSVColor hsv(RGBColor(r, g, b));
+       hsv.v = std::max(0.0, hsv.v - 0.2);
+       string const inactive_color = X11hexname(RGBColor(hsv));
+
+       // Set all color table entries in xpm_image that aren't
+       // "none" to inactive_color
+       for (uint i = 0; i != xpm_image.ncolors; ++i) {
+               XpmColor & ct = xpm_image.colorTable[i];
+               if (ct.c_color &&
+                   compare_ascii_no_case("none", ct.c_color) == 0)
+                       continue;
+
+               // Note that this is a c-struct, so use c memory funcs.
+               if (ct.c_color)
+                       free(ct.c_color);
+               ct.c_color = (char *)malloc(inactive_color.size() + 1);
+               strcpy(ct.c_color, inactive_color.c_str());
+       }
+
+       // Generate pixmaps of this modified xpm_image.
+       Screen * screen = ScreenOfDisplay(fl_get_display(), fl_screen);
+
+       XpmCreatePixmapFromXpmImage(fl_get_display(),
+                                   XRootWindowOfScreen(screen),
+                                   &xpm_image,
+                                   &inactive_pixmap,
+                                   &inactive_mask,
+                                   0);
+
+       XpmFreeXpmImage(&xpm_image);
+}
+
 
 Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
                                  LyXView & owner)
@@ -290,8 +358,8 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
 
 void XFormsToolbar::update()
 {
-       ToolbarList::const_iterator p = toollist_.begin();
-       ToolbarList::const_iterator end = toollist_.end();
+       ToolbarList::iterator p = toollist_.begin();
+       ToolbarList::iterator end = toollist_.end();
        for (; p != end; ++p) {
                if (!p->icon)
                        continue;
@@ -311,13 +379,24 @@ void XFormsToolbar::update()
                        fl_set_object_color(p->icon, FL_MCOL, FL_BLUE);
                        fl_set_object_boxtype(p->icon, FL_UP_BOX);
                }
+
+               // This must go here rather than in XFormsToolbar::add, else
+               // LyX aborts with a BadPixmap error.
+               if (!p->active_pixmap)
+                       p->generateInactivePixmaps();
+
                if (status.enabled()) {
                        fl_activate_object(p->icon);
+                       fl_set_pixmap_pixmap(p->icon,
+                                            p->active_pixmap,
+                                            p->active_mask);
+                       p->unused_pixmap = p->inactive_pixmap;
                } else {
-                       // Is there a way here to specify a
-                       // mask in order to show that the
-                       // button is disabled? (JMarc)
                        fl_deactivate_object(p->icon);
+                       fl_set_pixmap_pixmap(p->icon,
+                                            p->inactive_pixmap,
+                                            p->inactive_mask);
+                       p->unused_pixmap = p->active_pixmap;
                }
        }
 
index 0229927b9341bbdccfbb457be2357e134248336e..95c91203bb8ca6e511cd1cf42463f55e702e2348 100644 (file)
@@ -76,6 +76,8 @@ public:
 
                toolbarItem & operator=(toolbarItem const & ti);
 
+               void generateInactivePixmaps();
+
                /// deallocate icon
                void kill_icon();
 
@@ -83,6 +85,12 @@ public:
                FuncRequest func;
                /// icon for this item
                FL_OBJECT * icon;
+               ///
+               Pixmap unused_pixmap;
+               Pixmap active_pixmap;
+               Pixmap active_mask;
+               Pixmap inactive_pixmap;
+               Pixmap inactive_mask;
        };
 
        ///