*/
#include <config.h>
-#include <gtkmm.h>
-#include <X11/Xft/Xft.h>
+
+// Too hard to make concept checks work with this file
+#ifdef _GLIBCXX_CONCEPT_CHECKS
+#undef _GLIBCXX_CONCEPT_CHECKS
+#endif
+#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 "BufferView.h"
+#include "debug.h"
+#include "funcrequest.h"
+#include "LColor.h"
+#include "WorkArea.h"
+#include "Gui.h"
+#include "Selection.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) {
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) {
}
-GWorkArea::GWorkArea(int width, int height)
- : workAreaPixmap_(0), painter_(*this), draw_(0), colorHandler_(*this)
+GWorkArea::GWorkArea(LyXView & owner, int width, int height)
+ : view_(owner), workAreaPixmap_(0), painter_(*this), draw_(0), colorHandler_(*this),
+ adjusting_(false)
{
workArea_.set_size_request(width, height);
workArea_.set_double_buffered(false);
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),
}
+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(
gtk_im_context_set_client_window(
imContext_, workArea_.get_window()->gobj());
}
- workAreaResize();
+ view_.workArea()->resizeBufferView();
return true;
}
void GWorkArea::setScrollbarParams(int height, int pos, int line_height)
{
+ if (adjusting_)
+ return;
+
+ adjusting_ = true;
+
Gtk::Adjustment * adjustment = vscrollbar_.get_adjustment();
adjustment->set_lower(0);
int workAreaHeight = workHeight();
adjustment->set_page_size(workAreaHeight);
adjustment->set_value(0);
adjustment->changed();
+ adjusting_ = false;
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 / 4);
adjustment->set_page_size(workAreaHeight);
adjustment->set_value(pos);
adjustment->changed();
+ adjusting_ = false;
}
void GWorkArea::onScroll()
{
+ if (adjusting_)
+ return;
+
+ adjusting_ = true;
+
double val = vscrollbar_.get_adjustment()->get_value();
- scrollDocView(static_cast<int>(val));
+ view_.workArea()->scrollBufferView(static_cast<int>(val));
+ adjusting_ = false;
+}
+
+
+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;
}
default:
break;
}
- dispatch(FuncRequest(ka,
+ view_.workArea()->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;
}
bool GWorkArea::onButtonRelease(GdkEventButton * event)
{
- dispatch(FuncRequest(LFUN_MOUSE_RELEASE,
+ view_.workArea()->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;
}
}
timeBefore = event->time;
}
- dispatch(FuncRequest(LFUN_MOUSE_MOTION,
+ view_.workArea()->dispatch(FuncRequest(LFUN_MOUSE_MOTION,
static_cast<int>(event->x),
static_cast<int>(event->y),
gtkButtonState(event->state)));
bool GWorkArea::onKeyPress(GdkEventKey * event)
{
-#ifdef I18N
- inputCache_ = "";
- bool inputGet = gtk_im_context_filter_keypress(imContext_, event);
- // cope with ascii
- if ((inputGet && inputCache_.size() == 1 && inputCache_[0] < 128) ||
- !inputGet) {
-#endif
+// #ifdef I18N
+// inputCache_ = "";
+// bool inputGet = gtk_im_context_filter_keypress(imContext_, event);
+// // cope with ascii
+// if ((inputGet && inputCache_.size() == 1 && inputCache_[0] < 128) ||
+// !inputGet) {
+// #endif
GLyXKeySym *glk = new GLyXKeySym(event->keyval);
- workAreaKeyPress(LyXKeySymPtr(glk),
- gtkKeyState(event->state));
-#ifdef I18N
- } else if (!inputCache_.empty())
- workAreaCJK_IMprocess(inputCache_.size(), inputCache_.data());
-#endif
+ view_.workArea()->processKeySym(LyXKeySymPtr(glk),
+ gtkKeyState(event->state));
+// #ifdef I18N
+// } else if (!inputCache_.empty())
+// workAreaCJK_IMprocess(inputCache_.size(), inputCache_.data());
+// #endif
return true;
}
-
-void GWorkArea::onClipboardGet(Gtk::SelectionData & /*selection_data*/,
- guint /*info*/)
-{
- selectionRequested();
-}
-
-
-void GWorkArea::onClipboardClear()
-{
-// selectionLost();
-}
-
-
-void GWorkArea::haveSelection(bool toHave) const
-{
- if (toHave) {
- Glib::RefPtr<Gtk::Clipboard> clipboard =
- Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
- std::vector<Gtk::TargetEntry> listTargets;
- listTargets.push_back(Gtk::TargetEntry("UTF8_STRING"));
- clipboard->set(listTargets,
- SigC::slot(const_cast<GWorkArea&>(*this),
- &GWorkArea::onClipboardGet),
- SigC::slot(const_cast<GWorkArea&>(*this),
- &GWorkArea::onClipboardClear));
- }
-}
-
-
-string const GWorkArea::getClipboard() const
-{
- Glib::RefPtr<Gtk::Clipboard> clipboard =
- Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
- return Glib::locale_from_utf8(clipboard->wait_for_text());
-}
-
-
-void GWorkArea::putClipboard(string const & str) const
-{
- Glib::RefPtr<Gtk::Clipboard> clipboard =
- Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
- clipboard->set_text(Glib::locale_to_utf8(str));
-}
+} // namespace frontend
+} // namespace lyx