Painter and scrollbar API patches

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4386 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
John Levon 2002-06-12 15:01:32 +00:00
parent 37b0280356
commit 0db59752e2
17 changed files with 546 additions and 609 deletions

View File

@ -101,9 +101,9 @@ void BufferView::updateScrollbar()
}
void BufferView::scrollCB(double value)
void BufferView::scrollDocView(int value)
{
pimpl_->scrollCB(value);
pimpl_->scrollDocView(value);
}

View File

@ -185,8 +185,8 @@ public:
bool focus() const;
///
void focus(bool);
/// A callback for the slider in the scrollbar.
void scrollCB(double);
/// Scroll the view by a number of pixels
void scrollDocView(int);
///
void setState();

View File

@ -142,15 +142,14 @@ void SetXtermCursor(Window win)
BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o,
int xpos, int ypos, int width, int height)
: bv_(b), owner_(o), buffer_(0),
current_scrollbar_value(0), cursor_timeout(400),
: bv_(b), owner_(o), buffer_(0), cursor_timeout(400),
using_xterm_cursor(false)
{
workarea_.reset(new WorkArea(xpos, ypos, width, height));
screen_.reset(new LScreen(workarea()));
// Setup the signals
workarea().scrollCB.connect(boost::bind(&BufferView::Pimpl::scrollCB, this, _1));
workarea().scrollDocView.connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1));
workarea().workAreaExpose
.connect(boost::bind(&BufferView::Pimpl::workAreaExpose, this));
workarea().workAreaButtonPress
@ -417,51 +416,23 @@ void BufferView::Pimpl::updateScrollbar()
{
if (!bv_->text) {
lyxerr[Debug::GUI] << "no text in updateScrollbar" << endl;
workarea().setScrollbar(0, 1.0);
workarea().setScrollbarParams(0, 0, 0);
return;
}
long const text_height = bv_->text->height;
long const work_height = workarea().workHeight();
double const lineh = bv_->text->defaultHeight();
double const slider_size =
(text_height == 0) ? 1.0 : 1.0 / double(text_height);
lyxerr[Debug::GUI] << "text_height now " << text_height << endl;
lyxerr[Debug::GUI] << "work_height " << work_height << endl;
/* If the text is smaller than the working area, the scrollbar
* maximum must be the working area height. No scrolling will
* be possible */
if (text_height <= work_height) {
lyxerr[Debug::GUI] << "doc smaller than workarea !" << endl;
workarea().setScrollbarBounds(0.0, 0.0);
current_scrollbar_value = bv_->text->first_y;
workarea().setScrollbar(current_scrollbar_value, 1.0);
return;
}
workarea().setScrollbarBounds(0.0, text_height - work_height);
workarea().setScrollbarIncrements(lineh);
current_scrollbar_value = bv_->text->first_y;
workarea().setScrollbar(current_scrollbar_value, slider_size);
LyXText const & t = *bv_->text;
workarea().setScrollbarParams(t.height, t.first_y, t.defaultHeight());
}
// Callback for scrollbar slider
void BufferView::Pimpl::scrollCB(double value)
void BufferView::Pimpl::scrollDocView(int value)
{
lyxerr[Debug::GUI] << "scrollCB of " << value << endl;
lyxerr[Debug::GUI] << "scrollDocView of " << value << endl;
if (!buffer_) return;
current_scrollbar_value = long(value);
if (current_scrollbar_value < 0)
current_scrollbar_value = 0;
screen().draw(bv_->text, bv_, current_scrollbar_value);
screen().draw(bv_->text, bv_, value);
if (!lyxrc.cursor_follows_scrollbar) {
waitForX();
@ -483,77 +454,25 @@ void BufferView::Pimpl::scrollCB(double value)
}
int BufferView::Pimpl::scrollUp(long time)
int BufferView::Pimpl::scroll(long time)
{
if (!buffer_)
return 0;
double value = workarea().getScrollbarValue();
if (value == 0)
return 0;
#if 1
float add_value = (bv_->text->defaultHeight()
+ float(time) * float(time) * 0.125);
if (add_value > workarea().workHeight())
add_value = float(workarea().workHeight() -
bv_->text->defaultHeight());
#else
float add_value = float(workarea().workHeight()) * float(time) / 100;
#endif
value -= add_value;
if (value < 0)
value = 0;
workarea().setScrollbarValue(value);
scrollCB(value);
LyXText const * t = bv_->text;
double const diff = t->defaultHeight()
+ double(time) * double(time) * 0.125;
scrollDocView(int(diff));
workarea().setScrollbarParams(t->height, t->first_y, t->defaultHeight());
return 0;
}
int BufferView::Pimpl::scrollDown(long time)
void BufferView::Pimpl::workAreaKeyPress(KeySym key, key_modifier::state state)
{
if (!buffer_)
return 0;
double value = workarea().getScrollbarValue();
pair<float, float> p = workarea().getScrollbarBounds();
double const max = p.second;
if (value == max)
return 0;
#if 1
float add_value = (bv_->text->defaultHeight()
+ float(time) * float(time) * 0.125);
if (add_value > workarea().workHeight())
add_value = float(workarea().workHeight() -
bv_->text->defaultHeight());
#else
float add_value = float(workarea().workHeight()) * float(time) / 100;
#endif
value += add_value;
if (value > max)
value = max;
workarea().setScrollbarValue(value);
scrollCB(value);
return 0;
}
void BufferView::Pimpl::workAreaKeyPress(KeySym keysym, key_modifier::state state)
{
bv_->owner()->getLyXFunc()->processKeySym(keysym, state);
bv_->owner()->getLyXFunc()->processKeySym(key, state);
}
@ -629,15 +548,14 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos,
return;
// ok ok, this is a hack (for xforms)
if (button == mouse_button::button4) {
scrollUp(lyxrc.wheel_jump);
scroll(-lyxrc.wheel_jump);
// We shouldn't go further down as we really should only do the
// scrolling and be done with this. Otherwise we may open some
// dialogs (Jug 20020424).
return;
} else if (button == mouse_button::button5) {
scrollDown(lyxrc.wheel_jump);
scroll(lyxrc.wheel_jump);
// We shouldn't go further down as we really should only do the
// scrolling and be done with this. Otherwise we may open some
// dialogs (Jug 20020424).

View File

@ -69,19 +69,17 @@ struct BufferView::Pimpl : public boost::signals::trackable {
///
void updateScrollbar();
///
void scrollCB(double value);
void scrollDocView(int value);
/**
* Returns an inset if inset was hit, or 0 if not.
*
* If hit, the coordinates are changed relative to the inset.
*/
Inset * checkInsetHit(LyXText *, int & x, int & y);
/// wheel mouse scroll
int scroll(long time);
///
int scrollUp(long time);
///
int scrollDown(long time);
///
void workAreaKeyPress(KeySym, key_modifier::state state);
void workAreaKeyPress(KeySym key, key_modifier::state state);
///
void workAreaMotionNotify(int x, int y, mouse_button::state state);
///
@ -178,8 +176,6 @@ private:
///
boost::scoped_ptr<WorkArea> workarea_;
///
long current_scrollbar_value;
///
Timeout cursor_timeout;
///
void pasteClipboard(bool asPara);
@ -210,4 +206,4 @@ private:
///
void MenuInsertLyXFile(string const & filen);
};
#endif
#endif // BUFFERVIEW_PIMPL_H

View File

@ -1,3 +1,11 @@
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* BufferView.h:
* BufferView.C:
* BufferView_pimpl.h:
* BufferView_pimpl.C: move bogus scrolling logic
to xforms
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* lyxfunc.C:

View File

@ -1,3 +1,8 @@
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* Painter.h:
* Painter.C: s/PainterBase/Painter, remove dead code
2002-06-12 Angus Leeming <leeming@lyx.org>
* lyx_gui.h: remove trailing semi-colon after the brace closing

View File

@ -1,11 +1,11 @@
/* This file is part of
* ======================================================
/**
* \file Painter.C
* Copyright 1998-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1998-2001 The LyX Team
*
*======================================================*/
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#include <config.h>
@ -16,43 +16,11 @@
#include "Painter.h"
#include "lyxfont.h"
#include "WorkArea.h"
#include "font_metrics.h"
int PainterBase::paperMargin() const
{
return 20;
}
int PainterBase::paperWidth() const
{
return owner.workWidth();
}
int PainterBase::paperHeight() const
{
return owner.workHeight();
}
PainterBase & PainterBase::circle(int x, int y, unsigned int d,
LColor::color col)
{
return ellipse(x, y, d, d, col);
}
PainterBase & PainterBase::ellipse(int x, int y,
unsigned int w, unsigned int h,
LColor::color col)
{
return arc(x, y, w, h, 0, 0, col);
}
PainterBase & PainterBase::button(int x, int y, int w, int h)
#include "frontends/font_metrics.h"
using std::max;
Painter & Painter::button(int x, int y, int w, int h)
{
fillRectangle(x, y, w, h, LColor::buttonbg);
buttonFrame(x, y, w, h);
@ -60,17 +28,17 @@ PainterBase & PainterBase::button(int x, int y, int w, int h)
}
PainterBase & PainterBase::buttonFrame(int x, int y, int w, int h)
Painter & Painter::buttonFrame(int x, int y, int w, int h)
{
// Width of a side of the button
int d = 2;
int const d = 2;
fillRectangle(x, y, w, d, LColor::top);
fillRectangle(x, (y+h-d), w, d, LColor::bottom);
fillRectangle(x, (y + h - d), w, d, LColor::bottom);
// Now a couple of trapezoids
int x1[4], y1[4];
x1[0] = x + d; y1[0] = y + d;
x1[1] = x + d; y1[1] = (y + h - d);
x1[2] = x; y1[2] = y + h;
@ -87,35 +55,51 @@ PainterBase & PainterBase::buttonFrame(int x, int y, int w, int h)
}
PainterBase & PainterBase::rectText(int x, int baseline,
string const & str,
LyXFont const & font,
LColor::color back,
LColor::color frame)
Painter & Painter::rectText(int x, int baseline,
string const & str,
LyXFont const & font,
LColor::color back,
LColor::color frame)
{
int width;
int ascent;
int descent;
font_metrics::rectText(str, font, width, ascent, descent);
rectangle(x, baseline - ascent, width, ascent + descent, frame);
fillRectangle(x + 1, baseline - ascent + 1, width - 1,
fillRectangle(x + 1, baseline - ascent + 1, width - 1,
ascent + descent - 1, back);
text(x + 3, baseline, str, font);
return *this;
}
PainterBase & PainterBase::buttonText(int x, int baseline,
string const & str,
LyXFont const & font)
Painter & Painter::buttonText(int x, int baseline,
string const & str,
LyXFont const & font)
{
int width;
int ascent;
int descent;
font_metrics::buttonText(str, font, width, ascent, descent);
button(x, baseline - ascent, width, descent + ascent);
text(x + 4, baseline, str, font);
return *this;
}
void Painter::underline(LyXFont const & f, int x, int y, int width)
{
int const below = max(font_metrics::maxDescent(f) / 2, 2);
int const height = max((font_metrics::maxDescent(f) / 4) - 1, 1);
if (height < 2) {
line(x, y + below, x + width, y + below, f.color());
} else {
fillRectangle(x, y + below, width, below + height,
f.color());
}
}

View File

@ -1,15 +1,15 @@
// -*- C++ -*-
/* This file is part of
* ======================================================
/**
* \file Painter.h
* Copyright 1998-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1998-2001 The LyX Team
*
*======================================================*/
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#ifndef PAINTERBASE_H
#define PAINTERBASE_H
#ifndef PAINTER_H
#define PAINTER_H
#ifdef __GNUG__
#pragma interface
@ -18,161 +18,158 @@
#include "LString.h"
#include "LColor.h"
class WorkArea;
class LyXFont;
namespace grfx {
class GImage;
}
/** A painter class to encapsulate all graphics parameters and operations
Every graphics operation in LyX should be made by this class. It will
be initialized and managed by the Screen class, and will be passed
as a parameter to inset.
It hides low level windows system parameters so insets and other
clients don't have to worry about them and we can control graphics and
GUI toolkit dependent drawing functions inside this single class.
/**
* Painter - A painter class to encapsulate all graphics parameters and operations
*
* Every graphics operation in LyX should be made by this class. The
* painter is used for drawing on the WorkArea, and is passed around
* during draw operations.
*
* It hides low level windows system parameters so insets and other
* clients don't have to worry about them and we can control graphics and
* GUI toolkit dependent drawing functions inside this single class.
*
* The intention for a toolkit is that it uses these methods to paint
* onto a backing pixmap. Only when expose events arrive via the event
* queue (perhaps generated via Screen::expose), does the copy onto
* the actual WorkArea widget take place. Paints are wrapped in (possibly
* recursive) calls to start() and end() to facilitate the backing pixmap
* management.
*
* Note that the methods return *this for convenience.
*/
class PainterBase {
class Painter {
public:
///
/// possible line widths
enum line_width {
///
line_thin,
///
line_thick
line_thin, //< thin line
line_thick //< thick line
};
///
/// possible line styles
enum line_style {
///
line_solid,
///
line_doubledash,
///
line_onoffdash
line_solid, //< solid line
line_onoffdash //< dashes with spaces
};
///
explicit PainterBase(WorkArea & wa) : owner(wa) {}
virtual ~Painter() {}
///
virtual ~PainterBase() {}
/// begin painting
virtual void start() {}
/// end painting
virtual void end() {}
/// return the width of the work area in pixels
virtual int paperWidth() const = 0;
/// return the height of the work area in pixels
virtual int paperHeight() const = 0;
/* Screen geometry */
///
int paperMargin() const;
///
int paperWidth() const;
///
int paperHeight() const;
/// Draw a line from point to point
virtual PainterBase & line(
int x1, int y1, int x2, int y2,
/// draw a line from point to point
virtual Painter & line(
int x1, int y1,
int x2, int y2,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin) = 0;
line_style = line_solid,
line_width = line_thin) = 0;
/** Draw the lines between the lines in xp and yp.
xp and yp are arrays of points, and np is the
number of them. */
virtual PainterBase & lines(
int const * xp, int const * yp, int np,
/**
* lines - draw a set of lines
* @param xp array of points' x co-ords
* @param yp array of points' y co-ords
* @param np size of the points array
*/
virtual Painter & lines(
int const * xp,
int const * yp,
int np,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin) = 0;
line_style = line_solid,
line_width = line_thin) = 0;
/// Here xp and yp are arrays of points
virtual PainterBase & fillPolygon(
int const * xp, int const * yp,
/// draw a rectangle
virtual Painter & rectangle(
int x, int y,
int w, int h,
LColor::color = LColor::foreground,
line_style = line_solid,
line_width = line_thin) = 0;
/// draw a filled rectangle
virtual Painter & fillRectangle(
int x, int y,
int w, int h,
LColor::color) = 0;
/// draw a filled (irregular) polygon
virtual Painter & fillPolygon(
int const * xp,
int const * yp,
int np,
LColor::color = LColor::foreground) = 0;
/// Draw lines from x1,y1 to x2,y2. They are arrays
virtual PainterBase & segments(
int const * x1, int const * y1,
int const * x2, int const * y2, int ns,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin) = 0;
/// Draw a rectangle
virtual PainterBase & rectangle(
int x, int y, int w, int h,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin) = 0;
/// Draw a circle, d is the diameter, not the radious
virtual PainterBase & circle(
int x, int y, unsigned int d,
LColor::color = LColor::foreground);
/// Draw an ellipse
virtual PainterBase & ellipse(
int x, int y,
unsigned int w, unsigned int h,
LColor::color = LColor::foreground);
/// Draw an arc
virtual PainterBase & arc(
/// draw an arc
virtual Painter & arc(
int x, int y,
unsigned int w, unsigned int h,
int a1, int a2,
LColor::color = LColor::foreground) = 0;
/// Draw a pixel
virtual PainterBase & point(
/// draw a pixel
virtual Painter & point(
int x, int y,
LColor::color = LColor::foreground) = 0;
/// draw a filled rectangle with the shape of a 3D button
virtual Painter & button(int x, int y,
int w, int h);
/// Fill a rectangle
virtual PainterBase & fillRectangle(
int x, int y, int w, int h,
LColor::color) = 0;
/// draw an image from the image cache
virtual Painter & image(int x, int y,
int w, int h,
grfx::GImage const & image) = 0;
/// draw a string at position x, y (y is the baseline)
virtual Painter & text(int x, int y,
string const & str, LyXFont const & f) = 0;
/// A filled rectangle with the shape of a 3D button
virtual PainterBase & button(int x, int y, int w, int h);
/**
* Draw a string at position x, y (y is the baseline)
* This is just for fast drawing
*/
virtual Painter & text(int x, int y,
char const * str, size_t l,
LyXFont const & f) = 0;
///
virtual PainterBase & buttonFrame(int x, int y, int w, int h);
/// draw a char at position x, y (y is the baseline)
virtual Painter & text(int x, int y,
char c, LyXFont const & f) = 0;
/// draw a string and enclose it inside a rectangle
Painter & rectText(int x, int baseline,
string const & string,
LyXFont const & font,
LColor::color back,
LColor::color frame);
// For the figure inset
virtual PainterBase & image(int x, int y, int w, int h,
grfx::GImage const & image) = 0;
/// draw a string and enclose it inside a button frame
Painter & buttonText(int x,
int baseline, string const & s,
LyXFont const & font);
/// Draw a string at position x, y (y is the baseline)
virtual PainterBase & text(int x, int y,
string const & str, LyXFont const & f) = 0;
/** Draw a string at position x, y (y is the baseline)
This is just for fast drawing */
virtual PainterBase & text(int x, int y, char const * str, size_t l,
LyXFont const & f) = 0;
/// Draw a char at position x, y (y is the baseline)
virtual PainterBase & text(int x, int y, char c, LyXFont const & f)=0;
/** Draws a string and encloses it inside a rectangle. */
PainterBase & rectText(int x, int baseline,
string const & string,
LyXFont const & font,
LColor::color back,
LColor::color frame);
/** Draw a string and encloses it inside a button frame. */
PainterBase & buttonText(int x, int baseline, string const & s,
LyXFont const & font);
protected:
///
WorkArea & owner;
/// check the font, and if set, draw an underline
void underline(LyXFont const & f,
int x, int y, int width);
/// draw a bevelled button border
Painter & buttonFrame(int x, int y, int w, int h);
};
// VERY temporary
#include "xforms/XPainter.h"
#endif
#endif // PAINTER_H

View File

@ -1,3 +1,14 @@
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* XWorkArea.h:
* XWorkArea.C: move scrolling logic into here
* ColorHandler.h:
* ColorHandler.C:
* XPainter.h:
* XPainter.C: remove unused stuff, s/PainterBase/Painter/,
s/Painter/XPainter/
2002-06-12 Angus Leeming <leeming@lyx.org>
* lyx_gui.C (parse_init): exit isn't in namespace lyx_gui!

View File

@ -21,7 +21,7 @@
#include <cmath>
#include <boost/scoped_array.hpp>
#ifndef CXX_GLOBAL_CSTD
using std::pow;
#endif
@ -73,10 +73,6 @@ unsigned long LyXColorHandler::colorPixel(LColor::color c)
// Uses caching
GC LyXColorHandler::getGCForeground(LColor::color c)
{
//if (lyxerr.debugging()) {
// lyxerr << "Painter drawable: " << drawable() << endl;
//}
if (colorGCcache[c] != 0)
return colorGCcache[c];
@ -166,13 +162,13 @@ GC LyXColorHandler::getGCForeground(LColor::color c)
// Gets GC for line
GC LyXColorHandler::getGCLinepars(PainterBase::line_style ls,
PainterBase::line_width lw, LColor::color c)
GC LyXColorHandler::getGCLinepars(Painter::line_style ls,
Painter::line_width lw, LColor::color c)
{
//if (lyxerr.debugging()) {
// lyxerr << "Painter drawable: " << drawable() << endl;
//}
int index = lw + (ls << 1) + (c << 6);
LineGCCache::iterator it = lineGCcache.find(index);
@ -181,26 +177,23 @@ GC LyXColorHandler::getGCLinepars(PainterBase::line_style ls,
XGCValues val;
XGetGCValues(display, getGCForeground(c), GCForeground, &val);
switch (lw) {
case PainterBase::line_thin:
case Painter::line_thin:
val.line_width = 0;
break;
case PainterBase::line_thick:
case Painter::line_thick:
val.line_width = 2;
break;
}
switch (ls) {
case PainterBase::line_solid:
case Painter::line_solid:
val.line_style = LineSolid;
break;
case PainterBase::line_onoffdash:
case Painter::line_onoffdash:
val.line_style = LineOnOffDash;
break;
case PainterBase::line_doubledash:
val.line_style = LineDoubleDash;
break;
}
@ -236,8 +229,8 @@ void LyXColorHandler::updateColor (LColor::color c)
gc = it->second;
XFreeGC(display, gc);
lineGCcache.erase(it);
getGCLinepars(PainterBase::line_style(ls),
PainterBase::line_width(lw), c);
getGCLinepars(Painter::line_style(ls),
Painter::line_width(lw), c);
}
}

View File

@ -39,8 +39,8 @@ public:
///
GC getGCForeground(LColor::color c);
///
GC getGCLinepars(PainterBase::line_style,
PainterBase::line_width, LColor::color c);
GC getGCLinepars(Painter::line_style,
Painter::line_width, LColor::color c);
/// update the cache after a color definition change
void updateColor(LColor::color c);

View File

@ -1,11 +1,11 @@
/* This file is part of
* ======================================================
/**
* \file XPainter.C
* Copyright 1998-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1998-2001 The LyX Team
*
*======================================================*/
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#include <config.h>
@ -13,11 +13,10 @@
#pragma implementation
#endif
#include "frontends/Painter.h"
#include "XPainter.h"
#include "LString.h"
#include "debug.h"
#include "lyxfont.h"
#include "frontends/xforms/XWorkArea.h"
#include "XWorkArea.h"
#include "xfont_metrics.h"
#include "ColorHandler.h"
#include "lyxrc.h"
@ -33,52 +32,54 @@
#include <cmath>
using std::endl;
using std::max;
namespace {
inline
Display * display()
XPainter::XPainter(WorkArea & xwa)
: Painter(), owner_(xwa)
{
return fl_get_display();
}
}
Painter::Painter(WorkArea & wa)
: PainterBase(wa)
{}
// Basic drawing routines
PainterBase & Painter::point(int x, int y, LColor::color c)
int XPainter::paperWidth() const
{
XDrawPoint(display(), owner.getPixmap(),
lyxColorHandler->getGCForeground(c), x, y);
return owner_.workWidth();
}
int XPainter::paperHeight() const
{
return owner_.workHeight();
}
Painter & XPainter::point(int x, int y, LColor::color c)
{
XDrawPoint(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCForeground(c), x, y);
return *this;
}
PainterBase & Painter::line(int x1, int y1, int x2, int y2,
LColor::color col,
enum line_style ls,
enum line_width lw)
Painter & XPainter::line(int x1, int y1,
int x2, int y2,
LColor::color col,
line_style ls,
line_width lw)
{
XDrawLine(display(), owner.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
x1, y1, x2, y2);
XDrawLine(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
x1, y1, x2, y2);
return *this;
}
PainterBase & Painter::lines(int const * xp, int const * yp, int np,
LColor::color col,
enum line_style ls,
enum line_width lw)
Painter & XPainter::lines(int const * xp, int const * yp,
int np,
LColor::color col,
line_style ls,
line_width lw)
{
boost::scoped_array<XPoint> points(new XPoint[np]);
@ -87,37 +88,39 @@ PainterBase & Painter::lines(int const * xp, int const * yp, int np,
points[i].y = yp[i];
}
XDrawLines(display(), owner.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
points.get(), np, CoordModeOrigin);
XDrawLines(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
points.get(), np, CoordModeOrigin);
return *this;
}
}
PainterBase & Painter::rectangle(int x, int y, int w, int h,
LColor::color col,
enum line_style ls,
enum line_width lw)
Painter & XPainter::rectangle(int x, int y,
int w, int h,
LColor::color col,
line_style ls,
line_width lw)
{
XDrawRectangle(display(), owner.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
x, y, w, h);
XDrawRectangle(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
x, y, w, h);
return *this;
}
PainterBase & Painter::fillRectangle(int x, int y, int w, int h,
LColor::color col)
Painter & XPainter::fillRectangle(int x, int y,
int w, int h,
LColor::color col)
{
XFillRectangle(display(), owner.getPixmap(),
lyxColorHandler->getGCForeground(col), x, y, w, h);
XFillRectangle(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCForeground(col), x, y, w, h);
return *this;
}
PainterBase & Painter::fillPolygon(int const * xp, int const * yp, int np,
LColor::color col)
Painter & XPainter::fillPolygon(int const * xp, int const * yp,
int np, LColor::color col)
{
boost::scoped_array<XPoint> points(new XPoint[np]);
@ -125,77 +128,59 @@ PainterBase & Painter::fillPolygon(int const * xp, int const * yp, int np,
points[i].x = xp[i];
points[i].y = yp[i];
}
XFillPolygon(display(), owner.getPixmap(),
lyxColorHandler->getGCForeground(col), points.get(), np,
Nonconvex, CoordModeOrigin);
XFillPolygon(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCForeground(col), points.get(),
np, Nonconvex, CoordModeOrigin);
return *this;
}
PainterBase & Painter::arc(int x, int y,
unsigned int w, unsigned int h,
int a1, int a2, LColor::color col)
Painter & XPainter::arc(int x, int y,
unsigned int w, unsigned int h,
int a1, int a2, LColor::color col)
{
XDrawArc(display(), owner.getPixmap(),
lyxColorHandler->getGCForeground(col),
x, y, w, h, a1, a2);
return *this;
XDrawArc(fl_get_display(), owner_.getPixmap(),
lyxColorHandler->getGCForeground(col),
x, y, w, h, a1, a2);
return *this;
}
/// Draw lines from x1,y1 to x2,y2. They are arrays
PainterBase & Painter::segments(int const * x1, int const * y1,
int const * x2, int const * y2, int ns,
LColor::color col,
enum line_style ls, enum line_width lw)
{
boost::scoped_array<XSegment> s(new XSegment[ns]);
for (int i = 0; i < ns; ++i) {
s[i].x1 = x1[i];
s[i].y1 = y1[i];
s[i].x2 = x2[i];
s[i].y2 = y2[i];
}
XDrawSegments(display(), owner.getPixmap(),
lyxColorHandler->getGCLinepars(ls, lw, col),
s.get(), ns);
return *this;
}
PainterBase & Painter::image(int x, int y, int w, int h,
grfx::GImage const & image)
Painter & XPainter::image(int x, int y,
int w, int h,
grfx::GImage const & image)
{
XGCValues val;
val.function = GXcopy;
GC gc = XCreateGC(display(), owner.getPixmap(),
GCFunction, &val);
XCopyArea(display(), image.getPixmap(), owner.getPixmap(), gc,
0, 0, w, h, x, y);
XFreeGC(display(), gc);
GC gc = XCreateGC(fl_get_display(), owner_.getPixmap(),
GCFunction, &val);
XCopyArea(fl_get_display(), image.getPixmap(), owner_.getPixmap(),
gc, 0, 0, w, h, x, y);
XFreeGC(fl_get_display(), gc);
return *this;
}
PainterBase & Painter::text(int x, int y, string const & s, LyXFont const & f)
Painter & XPainter::text(int x, int y,
string const & s, LyXFont const & f)
{
return text(x, y, s.data(), s.length(), f);
}
PainterBase & Painter::text(int x, int y, char c, LyXFont const & f)
Painter & XPainter::text(int x, int y,
char c, LyXFont const & f)
{
char s[2] = { c, '\0' };
return text(x, y, s, 1, f);
}
PainterBase & Painter::text(int x, int y, char const * s, size_t ls,
LyXFont const & f)
Painter & XPainter::text(int x, int y,
char const * s, size_t ls,
LyXFont const & f)
{
if (lyxrc.font_norm_type == LyXRC::ISO_10646_1) {
boost::scoped_array<XChar2b> xs(new XChar2b[ls]);
@ -219,8 +204,8 @@ PainterBase & Painter::text(int x, int y, char const * s, size_t ls,
GC gc = lyxColorHandler->getGCForeground(f.realColor());
if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
xfont_metrics::XSetFont(display(), gc, f);
XDrawString(display(), owner.getPixmap(), gc, x, y, s, ls);
xfont_metrics::XSetFont(fl_get_display(), gc, f);
XDrawString(fl_get_display(), owner_.getPixmap(), gc, x, y, s, ls);
} else {
LyXFont smallfont(f);
smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
@ -228,14 +213,14 @@ PainterBase & Painter::text(int x, int y, char const * s, size_t ls,
for (size_t i = 0; i < ls; ++i) {
char const c = uppercase(s[i]);
if (c != s[i]) {
xfont_metrics::XSetFont(display(), gc, smallfont);
XDrawString(display(), owner.getPixmap(), gc,
tmpx, y, &c, 1);
xfont_metrics::XSetFont(fl_get_display(), gc, smallfont);
XDrawString(fl_get_display(), owner_.getPixmap(), gc,
tmpx, y, &c, 1);
tmpx += xfont_metrics::XTextWidth(smallfont, &c, 1);
} else {
xfont_metrics::XSetFont(display(), gc, f);
XDrawString(display(), owner.getPixmap(), gc,
tmpx, y, &c, 1);
xfont_metrics::XSetFont(fl_get_display(), gc, f);
XDrawString(fl_get_display(), owner_.getPixmap(), gc,
tmpx, y, &c, 1);
tmpx += xfont_metrics::XTextWidth(f, &c, 1);
}
}
@ -244,24 +229,25 @@ PainterBase & Painter::text(int x, int y, char const * s, size_t ls,
if (f.underbar() == LyXFont::ON) {
underline(f, x, y, font_metrics::width(s, ls, f));
}
return *this;
}
PainterBase & Painter::text(int x, int y, XChar2b const * s, int ls,
LyXFont const & f)
Painter & XPainter::text(int x, int y,
XChar2b const * s, size_t ls,
LyXFont const & f)
{
GC gc = lyxColorHandler->getGCForeground(f.realColor());
if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
xfont_metrics::XSetFont(display(), gc, f);
XDrawString16(display(), owner.getPixmap(), gc, x, y, s, ls);
xfont_metrics::XSetFont(fl_get_display(), gc, f);
XDrawString16(fl_get_display(), owner_.getPixmap(), gc, x, y, s, ls);
} else {
LyXFont smallfont(f);
smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
static XChar2b c;
int tmpx = x;
for (int i = 0; i < ls; ++i) {
for (size_t i = 0; i < ls; ++i) {
if (s[i].byte1)
c = s[i];
else {
@ -269,34 +255,22 @@ PainterBase & Painter::text(int x, int y, XChar2b const * s, int ls,
c.byte2 = uppercase(s[i].byte2);
}
if (c.byte2 != s[i].byte2) {
xfont_metrics::XSetFont(display(), gc, smallfont);
XDrawString16(display(), owner.getPixmap(), gc,
tmpx, y, &c, 1);
xfont_metrics::XSetFont(fl_get_display(), gc, smallfont);
XDrawString16(fl_get_display(), owner_.getPixmap(), gc,
tmpx, y, &c, 1);
tmpx += xfont_metrics::XTextWidth16(smallfont, &c, 1);
} else {
xfont_metrics::XSetFont(display(), gc, f);
XDrawString16(display(), owner.getPixmap(), gc,
tmpx, y, &c, 1);
xfont_metrics::XSetFont(fl_get_display(), gc, f);
XDrawString16(fl_get_display(), owner_.getPixmap(), gc,
tmpx, y, &c, 1);
tmpx += xfont_metrics::XTextWidth16(f, &c, 1);
}
}
}
if (f.underbar() == LyXFont::ON) {
underline(f, x, y, xfont_metrics::width(s, ls, f));
}
return *this;
}
void Painter::underline(LyXFont const & f, int x, int y, int width)
{
int const below = max(font_metrics::maxDescent(f) / 2, 2);
int const height = max((font_metrics::maxDescent(f) / 4) - 1, 1);
if (height < 2)
line(x, y + below, x + width, y + below, f.color());
else
fillRectangle(x, y + below, width, below + height,
f.color());
}

View File

@ -1,101 +1,126 @@
// -*- C++ -*-
/* This file is part of
* ======================================================
/**
* \file XPainter.h
* Copyright 1995-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1995-2001 The LyX Team
*
* ======================================================*/
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#ifndef PAINTER_H
#define PAINTER_H
#ifndef XPAINTER_H
#define XPAINTER_H
#ifdef __GNUG__
#pragma interface
#endif
#include <config.h>
#include "frontends/Painter.h"
#include "LString.h"
// This is only included to provide stuff for the non-public sections
#include <X11/Xlib.h>
#include "frontends/Painter.h"
class LyXFont;
class WorkArea;
/** An inplementation for the X Window System. Xlib.
Classes similar to this one can be made for gtk+, Qt, etc.
*/
class Painter : public PainterBase {
/**
* XPainter - a painter implementation for Xlib
*/
class XPainter : public Painter {
public:
/// Constructor
explicit Painter(WorkArea &);
XPainter(WorkArea &);
/// return the width of the work area in pixels
virtual int paperWidth() const;
/// return the height of the work area in pixels
virtual int paperHeight() const;
/// Draw a line from point to point
PainterBase & line(int x1, int y1, int x2, int y2,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin);
/// draw a line from point to point
virtual Painter & line(
int x1, int y1,
int x2, int y2,
LColor::color = LColor::foreground,
line_style = line_solid,
line_width = line_thin);
/// Here xp and yp are arrays of points
PainterBase & lines(int const * xp, int const * yp, int np,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin);
/**
* lines - draw a set of lines
* @param xp array of points' x co-ords
* @param yp array of points' y co-ords
* @param np size of the points array
*/
virtual Painter & lines(
int const * xp,
int const * yp,
int np,
LColor::color = LColor::foreground,
line_style = line_solid,
line_width = line_thin);
/// Here xp and yp are arrays of points
PainterBase & fillPolygon(int const * xp, int const * yp, int np,
LColor::color = LColor::foreground);
/// Draw lines from x1,y1 to x2,y2. They are arrays
PainterBase & segments(int const * x1, int const * y1,
int const * x2, int const * y2, int ns,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin);
/// Draw a rectangle
PainterBase & rectangle(int x, int y, int w, int h,
LColor::color = LColor::foreground,
enum line_style = line_solid,
enum line_width = line_thin);
/// Draw an arc
PainterBase & arc(int x, int y, unsigned int w, unsigned int h,
int a1, int a2,
LColor::color = LColor::foreground);
/// Draw a pixel
PainterBase & point(int x, int y, LColor::color = LColor::foreground);
/// Fill a rectangle
PainterBase & fillRectangle(int x, int y, int w, int h,
LColor::color);
/// For the graphics inset.
PainterBase & image(int x, int y, int w, int h,
grfx::GImage const & image);
/// Draw a string at position x, y (y is the baseline)
PainterBase & text(int x, int y,
string const & str, LyXFont const & f);
/// draw a rectangle
virtual Painter & rectangle(
int x, int y,
int w, int h,
LColor::color = LColor::foreground,
line_style = line_solid,
line_width = line_thin);
/// draw a filled rectangle
virtual Painter & fillRectangle(
int x, int y,
int w, int h,
LColor::color);
/// draw a filled (irregular) polygon
virtual Painter & fillPolygon(
int const * xp,
int const * yp,
int np,
LColor::color = LColor::foreground);
/// draw an arc
virtual Painter & arc(
int x, int y,
unsigned int w, unsigned int h,
int a1, int a2,
LColor::color = LColor::foreground);
/// draw a pixel
virtual Painter & point(
int x, int y,
LColor::color = LColor::foreground);
/// draw an image from the image cache
virtual Painter & image(int x, int y,
int w, int h,
grfx::GImage const & image);
/// draw a string at position x, y (y is the baseline)
virtual Painter & text(int x, int y,
string const & str, LyXFont const & f);
/** Draw a string at position x, y (y is the baseline)
This is just for fast drawing */
PainterBase & text(int x, int y, char const * str, size_t l,
LyXFont const & f);
* This is just for fast drawing
*/
virtual Painter & text(int x, int y,
char const * str, size_t l,
LyXFont const & f);
/// Draw a char at position x, y (y is the baseline)
PainterBase & text(int x, int y, char c, LyXFont const & f);
/// draw a char at position x, y (y is the baseline)
virtual Painter & text(int x, int y,
char c, LyXFont const & f);
/// Draw a wide string at position x, y
PainterBase & text(int x, int y, XChar2b const * str, int l,
LyXFont const & f);
/// draw a wide string at position x, y
Painter & text(int x, int y,
XChar2b const * str, size_t l,
LyXFont const & f);
private:
/// Check the font, and if set, draw an underline
void underline(LyXFont const & f, int x, int y, int width);
/// our owner who we paint upon
WorkArea & owner_;
};
#endif
#endif // XPAINTER_H

View File

@ -1,12 +1,11 @@
/* This file is part of
* ======================================================
/**
* \file XWorkArea.C
* Copyright 1995-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1995 Matthias Ettrich
* Copyright 1995-2001 The LyX Team.
*
* ====================================================== */
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#include <config.h>
@ -16,12 +15,12 @@
#include "XWorkArea.h"
#include "debug.h"
#include "frontends/LyXView.h"
#include "LyXView.h"
#include "lyxrc.h" // lyxrc.show_banner
#include "version.h" // lyx_version
#if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5))
#include "frontends/xforms/lyxlookup.h"
#include "lyxlookup.h"
#endif
#include "support/filetools.h" // LibFileSearch
@ -34,7 +33,7 @@
// xforms doesn't define this (but it should be in <forms.h>).
extern "C"
FL_APPEVENT_CB fl_set_preemptive_callback(Window, FL_APPEVENT_CB, void *);
using std::endl;
using std::abs;
using std::hex;
@ -47,6 +46,21 @@ void waitForX()
XSync(fl_get_display(), 0);
}
void setXtermCursor(Window win)
{
static Cursor cursor;
static bool cursor_undefined = true;
if (cursor_undefined) {
cursor = XCreateFontCursor(fl_get_display(), XC_xterm);
XFlush(fl_get_display());
cursor_undefined = false;
}
XDefineCursor(fl_get_display(), win, cursor);
XFlush(fl_get_display());
}
// FIXME !
mouse_button::state x_button_state(unsigned int button)
{
@ -111,9 +125,10 @@ key_modifier::state x_key_state(unsigned int state)
extern "C" {
// Just a bunch of C wrappers around static members of WorkArea
static
void C_WorkArea_scroll_cb(FL_OBJECT * ob, long buf)
void C_WorkArea_scroll_cb(FL_OBJECT * ob, long)
{
WorkArea::scroll_cb(ob, buf);
WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
area->scroll_cb();
}
@ -150,7 +165,7 @@ WorkArea::WorkArea(int x, int y, int w, int h)
backgroundbox = obj = fl_add_box(FL_BORDER_BOX,
x, y,
w - 15,
h,"");
h, "");
fl_set_object_resize(obj, FL_RESIZE_ALL);
fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
@ -193,13 +208,15 @@ WorkArea::WorkArea(int x, int y, int w, int h)
fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity);
obj->u_vdata = this;
fl_set_object_callback(obj, C_WorkArea_scroll_cb, 0);
setScrollbarBounds(0.0, 0.0);
fl_set_scrollbar_bounds(scrollbar, 0.0, 0.0);
fl_set_scrollbar_value(scrollbar, 0.0);
fl_set_scrollbar_size(scrollbar, scrollbar->h);
///
/// The free object
int const bw = int(abs(fl_get_border_width()));
// Create the workarea pixmap
createPixmap(w - 15 - 2 * bw, h - 2 * bw);
@ -334,33 +351,53 @@ void WorkArea::setFocus() const
}
void WorkArea::setScrollbar(double pos, double length_fraction) const
void WorkArea::setScrollbarParams(int height, int pos, int line_height)
{
// we need to cache this for scroll_cb
doc_height_ = height;
if (height == 0) {
fl_set_scrollbar_value(scrollbar, 0.0);
fl_set_scrollbar_size(scrollbar, scrollbar->h);
return;
}
long const work_height = workHeight();
lyxerr[Debug::GUI] << "scroll: height now " << height << endl;
lyxerr[Debug::GUI] << "scroll: work_height " << work_height << endl;
/* If the text is smaller than the working area, the scrollbar
* maximum must be the working area height. No scrolling will
* be possible */
if (height <= work_height) {
lyxerr[Debug::GUI] << "scroll: doc smaller than workarea !" << endl;
fl_set_scrollbar_bounds(scrollbar, 0.0, 0.0);
fl_set_scrollbar_value(scrollbar, pos);
fl_set_scrollbar_size(scrollbar, scrollbar->h);
return;
}
fl_set_scrollbar_bounds(scrollbar, 0.0, height - work_height);
fl_set_scrollbar_increment(scrollbar, work_area->h - line_height, line_height);
fl_set_scrollbar_value(scrollbar, pos);
fl_set_scrollbar_size(scrollbar, scrollbar->h * length_fraction);
double const slider_size =
(height == 0) ? 1.0 : 1.0 / double(height);
fl_set_scrollbar_size(scrollbar, scrollbar->h * slider_size);
}
void WorkArea::setScrollbarBounds(double l1, double l2) const
// callback for scrollbar slider
void WorkArea::scroll_cb()
{
fl_set_scrollbar_bounds(scrollbar, l1, l2);
}
void WorkArea::setScrollbarIncrements(double inc) const
{
fl_set_scrollbar_increment(scrollbar, work_area->h - inc, inc);
}
// Callback for scrollbar slider
void WorkArea::scroll_cb(FL_OBJECT * ob, long)
{
WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
// If we really want the accellerating scroll we can do that
// from here. IMHO that is a waste of effort since we already
// have other ways to move fast around in the document. (Lgb)
area->scrollCB(fl_get_scrollbar_value(ob));
double const val = fl_get_scrollbar_value(scrollbar);
lyxerr[Debug::GUI] << "scroll: val: " << val << endl;
lyxerr[Debug::GUI] << "scroll: height: " << scrollbar->h << endl;
lyxerr[Debug::GUI] << "scroll: docheight: " << doc_height_ << endl;
scrollDocView(int(val));
waitForX();
}

View File

@ -1,13 +1,12 @@
// -*- C++ -*-
/* This file is part of
* ======================================================
/**
* \file XWorkArea.h
* Copyright 1995-2002 the LyX Team
* Read the file COPYING
*
* LyX, The Document Processor
*
* Copyright 1995 Matthias Ettrich
* Copyright 1995-2001 The LyX Team.
*
* ======================================================*/
* \author unknown
* \author John Levon <moz@compsoc.man.ac.uk>
*/
#ifndef XWORKAREA_H
#define XWORKAREA_H
@ -17,7 +16,7 @@
#endif
#include FORMS_H_LOCATION
#include "frontends/Painter.h"
#include "XPainter.h"
#include "frontends/mouse_state.h"
#include "frontends/key_state.h"
@ -67,34 +66,17 @@ public:
bool visible() const { return work_area->form->visible; }
///
void greyOut() const;
///
void setScrollbar(double pos, double length_fraction) const;
///
void setScrollbarValue(double y) const {
fl_set_scrollbar_value(scrollbar, y);
}
///
void setScrollbarBounds(double, double) const;
///
void setScrollbarIncrements(double inc) const;
///
double getScrollbarValue() const {
return fl_get_scrollbar_value(scrollbar);
}
///
std::pair<float, float> const getScrollbarBounds() const {
std::pair<float, float> p;
fl_get_scrollbar_bounds(scrollbar, &p.first, &p.second);
return p;
}
///
void setScrollbarParams(int height, int pos, int line_height);
///
Pixmap getPixmap() const { return workareapixmap; }
/// xforms callback
static int work_area_handler(FL_OBJECT *, int event,
FL_Coord, FL_Coord,
int /*key*/, void * xev);
/// xforms callback
static void scroll_cb(FL_OBJECT *, long);
/// xforms callback from scrollbar
void scroll_cb();
/// a selection exists
void haveSelection(bool) const;
///
@ -105,7 +87,7 @@ public:
///
boost::signal0<void> workAreaExpose;
///
boost::signal1<void, double> scrollCB;
boost::signal1<void, int> scrollDocView;
///
boost::signal2<void, KeySym, key_modifier::state> workAreaKeyPress;
///
@ -146,8 +128,11 @@ private:
/// The pixmap overlay on the workarea
Pixmap workareapixmap;
///
Painter painter_;
XPainter painter_;
/// if we call redraw with true needed for locking-insets
bool screen_cleared;
/// the current document's height (for scrollbar)
int doc_height_;
};
#endif
#endif // XWORKAREA_H

View File

@ -1,3 +1,7 @@
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* insettabular.C: s/scrollCB/scrollDocView/
2002-06-12 John Levon <moz@compsoc.man.ac.uk>
* insettext.C: change of topCursorVisible()

View File

@ -1054,7 +1054,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
if (bv->text->first_y + bv->painter().paperHeight() <
(top_baseline + tabular->GetHeightOfTabular()))
{
bv->scrollCB(bv->text->first_y + bv->painter().paperHeight());
bv->scrollDocView(bv->text->first_y + bv->painter().paperHeight());
code = FULL;
actcell = tabular->GetCellBelow(first_visible_cell) + column;
} else {
@ -1073,7 +1073,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
int column = actcol;
unlockInsetInInset(bv, the_locking_inset);
if (top_baseline < 0) {
bv->scrollCB(bv->text->first_y - bv->painter().paperHeight());
bv->scrollDocView(bv->text->first_y - bv->painter().paperHeight());
code = FULL;
if (top_baseline > 0)
actcell = column;