Visual feedback of inactive toolbar buttons.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8716 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2004-04-30 17:30:19 +00:00
parent 750bcd9858
commit 9c57aa5277
3 changed files with 109 additions and 16 deletions

View 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> 2004-04-29 Angus Leeming <leeming@lyx.org>
* FormGraphics.C (apply): don't get caught in a loop when mapping * FormGraphics.C (apply): don't get caught in a loop when mapping

View File

@ -15,6 +15,7 @@
#include "XFormsToolbar.h" #include "XFormsToolbar.h"
#include "Color.h"
#include "Tooltips.h" #include "Tooltips.h"
#include "xforms_helpers.h" #include "xforms_helpers.h"
@ -26,7 +27,10 @@
#include "gettext.h" #include "gettext.h"
#include "lyxfunc.h" #include "lyxfunc.h"
#include "support/lstrings.h"
#include "lyx_forms.h" #include "lyx_forms.h"
#include "lyx_xpm.h"
#include "combox.h" #include "combox.h"
#include <boost/bind.hpp> #include <boost/bind.hpp>
@ -34,6 +38,8 @@
using lyx::frontend::Box; using lyx::frontend::Box;
using lyx::frontend::BoxList; using lyx::frontend::BoxList;
using lyx::support::compare_ascii_no_case;
using std::distance; using std::distance;
using std::endl; using std::endl;
using std::string; using std::string;
@ -70,27 +76,33 @@ LyXTextClass const & getTextClass(LyXView const & lv)
XFormsToolbar::toolbarItem::toolbarItem() 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() XFormsToolbar::toolbarItem::~toolbarItem()
{ {
// Lars said here that ~XFormsView() dealt with the icons. kill_icon();
// This is not true. But enabling this causes crashes,
// because somehow we kill the same icon twice :(
// FIXME
//kill_icon();
} }
void XFormsToolbar::toolbarItem::kill_icon() void XFormsToolbar::toolbarItem::kill_icon()
{ {
if (icon) { if (unused_pixmap)
fl_delete_object(icon); // XForms will take care of cleaning up the other pixmap
fl_free_object(icon); XFreePixmap(fl_get_display(), unused_pixmap);
icon = 0;
} 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, Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
LyXView & owner) LyXView & owner)
@ -290,8 +358,8 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
void XFormsToolbar::update() void XFormsToolbar::update()
{ {
ToolbarList::const_iterator p = toollist_.begin(); ToolbarList::iterator p = toollist_.begin();
ToolbarList::const_iterator end = toollist_.end(); ToolbarList::iterator end = toollist_.end();
for (; p != end; ++p) { for (; p != end; ++p) {
if (!p->icon) if (!p->icon)
continue; continue;
@ -311,13 +379,24 @@ void XFormsToolbar::update()
fl_set_object_color(p->icon, FL_MCOL, FL_BLUE); fl_set_object_color(p->icon, FL_MCOL, FL_BLUE);
fl_set_object_boxtype(p->icon, FL_UP_BOX); 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()) { if (status.enabled()) {
fl_activate_object(p->icon); fl_activate_object(p->icon);
fl_set_pixmap_pixmap(p->icon,
p->active_pixmap,
p->active_mask);
p->unused_pixmap = p->inactive_pixmap;
} else { } 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_deactivate_object(p->icon);
fl_set_pixmap_pixmap(p->icon,
p->inactive_pixmap,
p->inactive_mask);
p->unused_pixmap = p->active_pixmap;
} }
} }

View File

@ -76,6 +76,8 @@ public:
toolbarItem & operator=(toolbarItem const & ti); toolbarItem & operator=(toolbarItem const & ti);
void generateInactivePixmaps();
/// deallocate icon /// deallocate icon
void kill_icon(); void kill_icon();
@ -83,6 +85,12 @@ public:
FuncRequest func; FuncRequest func;
/// icon for this item /// icon for this item
FL_OBJECT * icon; FL_OBJECT * icon;
///
Pixmap unused_pixmap;
Pixmap active_pixmap;
Pixmap active_mask;
Pixmap inactive_pixmap;
Pixmap inactive_mask;
}; };
/// ///