]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/XFormsToolbar.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / xforms / XFormsToolbar.C
index 87766a6093c5d4377d5c98c450a6b7d0093fb42c..ccee31a916989d0a83ffd05f9378ebc8ebea209e 100644 (file)
 
 #include <boost/bind.hpp>
 
-using lyx::frontend::Box;
-using lyx::frontend::BoxList;
+#include <sstream>
+#include <vector>
 
-using lyx::support::compare_ascii_no_case;
+using boost::shared_ptr;
 
 using std::distance;
 using std::endl;
 using std::string;
+using std::vector;
 
+namespace lyx {
+
+using support::compare_ascii_no_case;
+
+namespace frontend {
 
 // some constants
 const int standardspacing = 2; // the usual space between items
@@ -79,9 +85,8 @@ XFormsToolbar::toolbarItem::toolbarItem()
        : icon(0),
          unused_pixmap(0),
          active_pixmap(0),
-         active_mask(0),
          inactive_pixmap(0),
-         inactive_mask(0)
+         mask(0)
 {}
 
 
@@ -99,9 +104,8 @@ void XFormsToolbar::toolbarItem::kill_icon()
 
        unused_pixmap = 0;
        active_pixmap = 0;
-       active_mask = 0;
        inactive_pixmap = 0;
-       inactive_mask = 0;
+       mask = 0;
        icon = 0;
 }
 
@@ -128,19 +132,21 @@ void XFormsToolbar::toolbarItem::generateInactivePixmaps()
                return;
 
        // Store the existing (active) pixmap.
-       fl_get_pixmap_pixmap(icon, &active_pixmap, &active_mask);
+       fl_get_pixmap_pixmap(icon, &active_pixmap, &mask);
 
-       if (active_pixmap == 0 || active_mask == 0)
+       if (active_pixmap == 0 || 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);
+       // Ascertain the width and height of the pixmap.
+       Display * display = fl_get_display();
+       unsigned int width;
+       unsigned int height;
+       unsigned int uidummy;
+       int idummy;
+       Window win;
+
+       XGetGeometry(display, active_pixmap, &win, &idummy, &idummy,
+                    &width, &height, &uidummy, &uidummy);
 
        // Produce a darker shade of the button background as the
        // inactive color. Note the 'hsv.v - 0.2'.
@@ -150,52 +156,59 @@ void XFormsToolbar::toolbarItem::generateInactivePixmaps()
        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);
+       // Generate an XPM dataset for a uniformly-colored pixmap with
+       // the same dimensions as active_pixmap.
+
+       // The data set has the form:
+       // "<width> <height> <ncolors> <chars per pixel>",
+       // "o c <inactive_color>",
+       // "oooooooooooooooo", // <width> 'o' chars.
+       // repeated <height> times.
+       std::ostringstream line1_ss;
+       line1_ss << width << ' ' << height << " 1 1";
+       string const line1 = line1_ss.str();
+       string const line2 = "o c " + inactive_color;
+       string const data(width, 'o');
+       vector<char *> inactive_data(height + 2,
+                                    const_cast<char *>(data.c_str()));
+       inactive_data[0] = const_cast<char *>(line1.c_str());
+       inactive_data[1] = const_cast<char *>(line2.c_str());
+
+       char ** raw_inactive_data = &*inactive_data.begin();
+
+       // Generate a pixmap of this data set.
+       // Together with 'mask' above, this is sufficient to display
+       // an inactive version of our active_pixmap.
+       Screen * screen = ScreenOfDisplay(display, fl_screen);
+
+       XpmCreatePixmapFromData(display, XRootWindowOfScreen(screen),
+                               raw_inactive_data, &inactive_pixmap, 0, 0);
 }
 
+} // namespace frontend
+} // namespace lyx
+
 
 Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
                                  LyXView & owner)
 {
+       using lyx::frontend::XFormsToolbar;
        return Toolbars::ToolbarPtr(new XFormsToolbar(tbb, owner));
 }
 
 
+namespace lyx {
+namespace frontend {
+
 XFormsToolbar::XFormsToolbar(ToolbarBackend::Toolbar const & tbb,
                             LyXView & o)
-       : toolbar_(0),
-         toolbar_buttons_(0),
+       : toolbar_buttons_(0),
          owner_(static_cast<XFormsView &>(o)),
          tooltip_(new Tooltips)
 {
        position_ = getPosition(tbb.flags);
-       BoxList & boxlist = owner_.getBox(position_).children();
-       toolbar_ = &boxlist.push_back(Box(0,0));
+       BoxList & boxlist = owner_.getBox(position_)->children();
+       toolbar_ = boxlist.push_back(Box(0,0));
 
        // If the toolbar is horizontal, then it contains three
        // vertically-aligned Boxes,the center one of which is to
@@ -223,13 +236,12 @@ XFormsToolbar::XFormsToolbar(ToolbarBackend::Toolbar const & tbb,
 
        toolbar_->children().push_back(Box(padding, padding));
 
-       Box & toolbar_center = toolbar_->children().push_back(Box(0,0));
-       toolbar_center.set(toolbar_orientation);
-       toolbar_buttons_ = &toolbar_center.children();
+       shared_ptr<Box> toolbar_center = toolbar_->children().push_back(Box(0,0));
+       toolbar_center->set(toolbar_orientation);
+       toolbar_buttons_ = &toolbar_center->children();
 
        toolbar_->children().push_back(Box(padding, padding));
 
-       using lyx::frontend::WidgetMap;
        owner_.metricsUpdated.connect(boost::bind(&WidgetMap::updateMetrics,
                                                  &widgets_));
 
@@ -238,7 +250,6 @@ XFormsToolbar::XFormsToolbar(ToolbarBackend::Toolbar const & tbb,
        ToolbarBackend::item_iterator end = tbb.items.end();
        for (; it != end; ++it)
                add(it->first, it->second);
-
 }
 
 
@@ -265,7 +276,7 @@ void C_ToolbarCB(FL_OBJECT * ob, long ac)
 
        XFormsToolbar * ptr = static_cast<XFormsToolbar *>(ob->u_vdata);
        XFormsView & owner = ptr->owner_;
-       owner.getLyXFunc().dispatch(ptr->funcs[ac], true);
+       owner.getLyXFunc().dispatch(ptr->funcs[ac]);
 }
 
 } // extern "C"
@@ -275,7 +286,10 @@ void C_ToolbarCB(FL_OBJECT * ob, long ac)
 
 void XFormsToolbar::hide(bool update_metrics)
 {
-       toolbar_->set(Box::Invisible);
+       if (!toolbar_->visible())
+               return;
+
+       toolbar_->set(Box::Invisible);
        if (update_metrics)
                owner_.updateMetrics();
 }
@@ -283,7 +297,10 @@ void XFormsToolbar::hide(bool update_metrics)
 
 void XFormsToolbar::show(bool update_metrics)
 {
-       toolbar_->set(Box::Visible);
+       if (toolbar_->visible())
+               return;
+
+       toolbar_->set(Box::Visible);
        toolbar_->show();
        if (update_metrics)
                owner_.updateMetrics();
@@ -332,7 +349,7 @@ void XFormsToolbar::add(FuncRequest const & func, string const & tooltip)
                        gravity = NorthEastGravity;
                else if (position_ == XFormsView::Bottom)
                        gravity = SouthWestGravity;
-               
+
                fl_set_object_gravity(obj, gravity, gravity);
 
                Funcs::iterator fit = funcs.insert(funcs.end(), func);
@@ -389,13 +406,13 @@ void XFormsToolbar::update()
                        fl_activate_object(p->icon);
                        fl_set_pixmap_pixmap(p->icon,
                                             p->active_pixmap,
-                                            p->active_mask);
+                                            p->mask);
                        p->unused_pixmap = p->inactive_pixmap;
                } else {
                        fl_deactivate_object(p->icon);
                        fl_set_pixmap_pixmap(p->icon,
                                             p->inactive_pixmap,
-                                            p->inactive_mask);
+                                            p->mask);
                        p->unused_pixmap = p->active_pixmap;
                }
        }
@@ -496,7 +513,7 @@ void XLayoutBox::open()
 
 void XLayoutBox::setEnabled(bool enable)
 {
-       ::setEnabled(combox_, enable);
+       lyx::frontend::setEnabled(combox_, enable);
 }
 
 
@@ -504,18 +521,8 @@ void XLayoutBox::selected()
 {
        string const layoutguiname = getString(combox_);
 
-       LyXTextClass const & tc = getTextClass(owner_);
-
-       LyXTextClass::const_iterator it  = tc.begin();
-       LyXTextClass::const_iterator const end = tc.end();
-       for (; it != end; ++it) {
-               string const & name = (*it)->name();
-               if (_(name) == layoutguiname) {
-                       owner_.getLyXFunc()
-                               .dispatch(FuncRequest(LFUN_LAYOUT, name),
-                                         true);
-                       return;
-               }
-       }
-       lyxerr << "ERROR (XLayoutBox::selected): layout not found!" << endl;
+       layoutSelected(owner_, layoutguiname);
 }
+
+} // namespace frontend
+} // namespace lyx