]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/gtk/GWorkArea.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / gtk / GWorkArea.C
index a407f549f8251392c810794677dcfc643d5e6b17..4442e4b0c8ec6ec35246d89faa34996026291604 100644 (file)
@@ -9,33 +9,89 @@
  */
 
 #include <config.h>
-#include <gtkmm.h>
-#include <X11/Xft/Xft.h>
+
+// Too hard to make concept checks work with this file
+#ifdef _GLIBCPP_CONCEPT_CHECKS
+#undef _GLIBCPP_CONCEPT_CHECKS
+#endif
 
 #include "GWorkArea.h"
-#include "debug.h"
-#include "funcrequest.h"
 #include "GView.h"
 #include "GtkmmX.h"
 #include "GLyXKeySym.h"
 
+#include "debug.h"
+#include "funcrequest.h"
+#include "LColor.h"
+
+using boost::shared_ptr;
+
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+namespace {
+
+mouse_button::state gButtonToLyx(guint gdkbutton)
+{
+       // GDK uses int 1,2,3 but lyx uses enums (1,2,4)
+       switch (gdkbutton) {
+       case 1:
+               return mouse_button::button1;
+       case 2:
+               return mouse_button::button2;
+       case 3:
+               return mouse_button::button3;
+       case 4:
+               return mouse_button::button4;
+       case 5:
+               return mouse_button::button5;
+       }
+
+       // This shouldn't happen, according to gdk docs
+       lyxerr << "gButtonToLyx: unhandled button index\n";
+       return mouse_button::button1;
+}
+
+} // namespace anon
+
 ColorCache colorCache;
 
+Gdk::Color * ColorCache::getColor(LColor_color clr)
+{
+       MapIt it = cache_.find(clr);
+       return it == cache_.end() ? 0 : it->second.get();
+}
+
+
+XftColor * ColorCache::getXftColor(LColor_color clr)
+{
+       MapIt2 it = cache2_.find(clr);
+       return it == cache2_.end() ? 0 : it->second.get();
+}
+
+
+void ColorCache::cacheColor(LColor_color clr, Gdk::Color * gclr)
+{
+       cache_[clr] = shared_ptr<Gdk::Color>(gclr);
+}
+
+
+void ColorCache::cacheXftColor(LColor_color clr, XftColor * xclr)
+{
+       cache2_[clr] = shared_ptr<XftColor>(xclr);
+}
+
 
 void ColorCache::clear()
 {
-       MapIt it = cache_.begin();
-       for (; it != cache_.end(); ++it)
-               delete it->second;
        cache_.clear();
-       MapIt2 it2 = cache2_.begin();
-       for (; it2 != cache2_.end(); ++it2)
-               delete it2->second;
        cache2_.clear();
 }
 
 
-XftColor * ColorHandler::getXftColor(LColor::color clr)
+XftColor * ColorHandler::getXftColor(LColor_color clr)
 {
        XftColor * xclr = colorCache.getXftColor(clr);
        if (!xclr) {
@@ -45,14 +101,16 @@ XftColor * ColorHandler::getXftColor(LColor::color clr)
                Visual * visual = GDK_VISUAL_XVISUAL(
                        owner_.getColormap()->get_visual()->gobj());
                XftColorAllocName(owner_.getDisplay(), visual, colormap,
-                                 lcolor.getX11Name(clr).c_str(), xclr);
+                                 const_cast<char*>(
+                                         lcolor.getX11Name(clr).c_str())
+                                 , xclr);
                colorCache.cacheXftColor(clr, xclr);
        }
        return xclr;
 }
 
 
-Gdk::Color * ColorHandler::getGdkColor(LColor::color clr)
+Gdk::Color * ColorHandler::getGdkColor(LColor_color clr)
 {
        Gdk::Color * gclr = colorCache.getColor(clr);
        if (!gclr) {
@@ -110,7 +168,7 @@ void inputCommitRelay(GtkIMContext */*imcontext*/, gchar * str, GWorkArea * area
 }
 
 
-GWorkArea::GWorkArea(int width, int height)
+GWorkArea::GWorkArea(LyXView & owner, int width, int height)
        : workAreaPixmap_(0), painter_(*this), draw_(0), colorHandler_(*this)
 {
        workArea_.set_size_request(width, height);
@@ -119,31 +177,36 @@ GWorkArea::GWorkArea(int width, int height)
                             Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
                             Gdk::KEY_PRESS_MASK | Gdk::BUTTON1_MOTION_MASK);
        workArea_.signal_expose_event().connect(
-               SigC::slot(*this, &GWorkArea::onExpose));
+               sigc::mem_fun(*this, &GWorkArea::onExpose));
        workArea_.signal_configure_event().connect(
-               SigC::slot(*this, &GWorkArea::onConfigure));
+               sigc::mem_fun(*this, &GWorkArea::onConfigure));
        workArea_.signal_button_press_event().connect(
-               SigC::slot(*this, &GWorkArea::onButtonPress));
+               sigc::mem_fun(*this, &GWorkArea::onButtonPress));
        workArea_.signal_button_release_event().connect(
-               SigC::slot(*this, &GWorkArea::onButtonRelease));
+               sigc::mem_fun(*this, &GWorkArea::onButtonRelease));
        workArea_.signal_key_press_event().connect(
-               SigC::slot(*this, &GWorkArea::onKeyPress));
+               sigc::mem_fun(*this, &GWorkArea::onKeyPress));
        workArea_.signal_motion_notify_event().connect(
-               SigC::slot(*this, &GWorkArea::onMotionNotify));
+               sigc::mem_fun(*this, &GWorkArea::onMotionNotify));
        workArea_.show();
        vscrollbar_.get_adjustment()->signal_value_changed().connect(
-               SigC::slot(*this, &GWorkArea::onScroll));
+               sigc::mem_fun(*this, &GWorkArea::onScroll));
+       workArea_.signal_scroll_event().connect(
+               sigc::mem_fun(*this, &GWorkArea::onScrollWheel));
        vscrollbar_.show();
        hbox_.children().push_back(Gtk::Box_Helpers::Element(workArea_));
        hbox_.children().push_back(
                Gtk::Box_Helpers::Element(vscrollbar_,Gtk::PACK_SHRINK));
        hbox_.show();
-       GView::instance()->getVBox().children().push_back(
+
+       GView & gview = static_cast<GView &>(owner);
+       gview.getBox(GView::Center).children().push_back(
                Gtk::Box_Helpers::Element(hbox_));
+
        workArea_.set_flags(workArea_.get_flags() | Gtk::CAN_DEFAULT |
                            Gtk::CAN_FOCUS);
        workArea_.grab_default();
-       GView::instance()->setGWorkArea(&workArea_);
+       gview.setGWorkArea(&workArea_);
        imContext_ = GTK_IM_CONTEXT(gtk_im_multicontext_new());
        g_signal_connect(G_OBJECT(imContext_), "commit",
                         G_CALLBACK(&inputCommitRelay),
@@ -157,6 +220,79 @@ GWorkArea::~GWorkArea()
 }
 
 
+Painter & GWorkArea::getPainter()
+{
+       return painter_;
+}
+
+
+int GWorkArea::workWidth() const
+{
+       return workArea_.get_width();
+}
+
+
+int GWorkArea::workHeight() const
+{
+       return workArea_.get_height();
+}
+
+
+int GWorkArea::xpos() const
+{
+       return 0;
+}
+
+
+int GWorkArea::ypos() const
+{
+       return 0;
+}
+
+
+Glib::RefPtr<Gdk::Window> GWorkArea::getWindow()
+{
+       return workArea_.get_window();
+}
+
+
+Display * GWorkArea::getDisplay() const
+{
+       return GDK_WINDOW_XDISPLAY(
+               const_cast<GdkWindow*>(workArea_.get_window()->gobj()));
+}
+
+
+Glib::RefPtr<Gdk::Pixmap> GWorkArea::getPixmap()
+{
+       return workAreaPixmap_;
+}
+
+
+Glib::RefPtr<Gdk::GC> GWorkArea::getGC()
+{
+       return workAreaGC_;
+}
+
+
+Glib::RefPtr<Gdk::Colormap> GWorkArea::getColormap()
+{
+       return workArea_.get_colormap();
+}
+
+
+XftDraw * GWorkArea::getXftDraw()
+{
+       return draw_;
+}
+
+
+ColorHandler & GWorkArea::getColorHandler()
+{
+       return colorHandler_;
+}
+
+
 bool GWorkArea::onExpose(GdkEventExpose * event)
 {
        workArea_.get_window()->draw_drawable(
@@ -208,9 +344,11 @@ void GWorkArea::setScrollbarParams(int height, int pos, int line_height)
                adjustment->changed();
                return;
        }
-       adjustment->set_step_increment(line_height);
+       adjustment->set_step_increment(line_height * 3);
        adjustment->set_page_increment(workAreaHeight - line_height);
-       adjustment->set_upper(height);
+       // Allow the user half a screen of blank at the end
+       // to make scrollbar consistant with centering the cursor
+       adjustment->set_upper(height + workAreaHeight / 2);
        adjustment->set_page_size(workAreaHeight);
        adjustment->set_value(pos);
        adjustment->changed();
@@ -224,6 +362,31 @@ void GWorkArea::onScroll()
 }
 
 
+bool GWorkArea::onScrollWheel(GdkEventScroll * event)
+{
+       Gtk::Adjustment * adjustment = vscrollbar_.get_adjustment();
+
+       double step;
+       if (event->state & GDK_CONTROL_MASK)
+               step = adjustment->get_page_increment();
+       else
+               step = adjustment->get_step_increment();
+
+       if (event->direction == GDK_SCROLL_UP)
+               step *= -1.0f;
+
+       double target = adjustment->get_value() + step;
+       // Prevent the user getting a whole screen of blank when they
+       // try to scroll past the end of the doc
+       double max = adjustment->get_upper() - workHeight();
+       if (target > max)
+               target = max;
+
+       adjustment->set_value(target);
+       return true;
+}
+
+
 bool GWorkArea::onButtonPress(GdkEventButton * event)
 {
        kb_action ka = LFUN_MOUSE_PRESS;
@@ -243,7 +406,7 @@ bool GWorkArea::onButtonPress(GdkEventButton * event)
        dispatch(FuncRequest(ka,
                             static_cast<int>(event->x),
                             static_cast<int>(event->y),
-                            static_cast<mouse_button::state>(event->button)));
+                            gButtonToLyx(event->button)));
        workArea_.grab_focus();
        return true;
 }
@@ -254,7 +417,7 @@ bool GWorkArea::onButtonRelease(GdkEventButton * event)
        dispatch(FuncRequest(LFUN_MOUSE_RELEASE,
                             static_cast<int>(event->x),
                             static_cast<int>(event->y),
-                            static_cast<mouse_button::state>(event->button)));
+                            gButtonToLyx(event->button)));
        return true;
 }
 
@@ -331,9 +494,9 @@ void GWorkArea::haveSelection(bool toHave) const
                std::vector<Gtk::TargetEntry> listTargets;
                listTargets.push_back(Gtk::TargetEntry("UTF8_STRING"));
                clipboard->set(listTargets,
-                              SigC::slot(const_cast<GWorkArea&>(*this),
+                              sigc::mem_fun(const_cast<GWorkArea&>(*this),
                                          &GWorkArea::onClipboardGet),
-                              SigC::slot(const_cast<GWorkArea&>(*this),
+                              sigc::mem_fun(const_cast<GWorkArea&>(*this),
                                          &GWorkArea::onClipboardClear));
        }
 }
@@ -353,3 +516,6 @@ void GWorkArea::putClipboard(string const & str) const
                Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
        clipboard->set_text(Glib::locale_to_utf8(str));
 }
+
+} // namespace frontend
+} // namespace lyx