diff options
Diffstat (limited to 'dw/fltkviewbase.cc')
-rw-r--r-- | dw/fltkviewbase.cc | 144 |
1 files changed, 82 insertions, 62 deletions
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc index b35b07df..7d519f05 100644 --- a/dw/fltkviewbase.cc +++ b/dw/fltkviewbase.cc @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -30,6 +29,7 @@ #include <fltk/run.h> #include <stdio.h> +#include "../lout/msg.h" using namespace fltk; using namespace lout::object; @@ -47,9 +47,8 @@ FltkViewBase::FltkViewBase (int x, int y, int w, int h, const char *label): canvasWidth = 1; canvasHeight = 1; bgColor = WHITE; - lastDraw = time(0); - drawDelay = 2; /* in seconds */ mouse_x = mouse_y = 0; + exposeArea = NULL; if (backBuffer == NULL) { backBuffer = new Image (); } @@ -74,10 +73,10 @@ void FltkViewBase::draw () int d = damage (); if ((d & DAMAGE_VALUE) && !(d & DAMAGE_EXPOSE)) { - container::typed::Iterator <core::Rectangle> it; + lout::container::typed::Iterator <core::Rectangle> it; for (it = drawRegion.rectangles (); it.hasNext (); ) { - drawRectangle (it.getNext (), true); + draw (it.getNext (), DRAW_BUFFERED); } drawRegion.clear (); @@ -96,16 +95,18 @@ void FltkViewBase::draw () w (), h ()); - drawRectangle (&rect, false); - - if (! (d & DAMAGE_SCROLL)) { + if (d == DAMAGE_SCROLL) { + // a clipping rectangle has already been set by fltk::scrollrect () + draw (&rect, DRAW_PLAIN); + } else { + draw (&rect, DRAW_CLIPPED); drawRegion.clear (); } } } -void FltkViewBase::drawRectangle (const core::Rectangle *rect, - bool doubleBuffer) +void FltkViewBase::draw (const core::Rectangle *rect, + DrawType type) { int offsetX = 0, offsetY = 0; @@ -116,7 +117,7 @@ void FltkViewBase::drawRectangle (const core::Rectangle *rect, translateCanvasXToViewX (rect->x) + offsetX, translateCanvasYToViewY (rect->y) + offsetY, rect->width, rect->height); - + ::fltk::intersect_with_clip (viewRect); viewRect.x (viewRect.x () - offsetX); @@ -129,14 +130,16 @@ void FltkViewBase::drawRectangle (const core::Rectangle *rect, viewRect.w (), viewRect.h ()); - if (doubleBuffer && backBuffer && !backBufferInUse) { + exposeArea = &viewRect; + + if (type == DRAW_BUFFERED && backBuffer && !backBufferInUse) { backBufferInUse = true; { GSave gsave; backBuffer->setsize (viewRect.w (), viewRect.h ()); backBuffer->make_current (); - translate (-viewRect.x (), -viewRect.y ()); + translate (-viewRect.x (), -viewRect.y ()); setcolor (bgColor); fillrect (viewRect); @@ -147,19 +150,21 @@ void FltkViewBase::drawRectangle (const core::Rectangle *rect, viewRect); backBufferInUse = false; - } else if (doubleBuffer) { + } else if (type == DRAW_BUFFERED || type == DRAW_CLIPPED) { + // if type == DRAW_BUFFERED but we do not have backBuffer available + // we fall back to clipped drawing push_clip (viewRect); setcolor (bgColor); fillrect (viewRect); theLayout->expose (this, &r); pop_clip (); } else { - // if doubleBuffer is false we assume that a clipping - // rectangle has been set already setcolor (bgColor); fillrect (viewRect); theLayout->expose (this, &r); } + + exposeArea = NULL; } } @@ -178,13 +183,13 @@ core::ButtonState getDwButtonState () { int s1 = event_state (); int s2 = (core::ButtonState)0; - - if(s1 & SHIFT) s2 |= core::SHIFT_MASK; - if(s1 & CTRL) s2 |= core::CONTROL_MASK; - if(s1 & ALT) s2 |= core::META_MASK; - if(s1 & BUTTON1) s2 |= core::BUTTON1_MASK; - if(s1 & BUTTON2) s2 |= core::BUTTON2_MASK; - if(s1 & BUTTON3) s2 |= core::BUTTON3_MASK; + + if (s1 & SHIFT) s2 |= core::SHIFT_MASK; + if (s1 & CTRL) s2 |= core::CONTROL_MASK; + if (s1 & ALT) s2 |= core::META_MASK; + if (s1 & BUTTON1) s2 |= core::BUTTON1_MASK; + if (s1 & BUTTON2) s2 |= core::BUTTON2_MASK; + if (s1 & BUTTON3) s2 |= core::BUTTON3_MASK; return (core::ButtonState)s2; } @@ -194,7 +199,7 @@ int FltkViewBase::handle (int event) bool processed; /** - * \todo Consider, whether this from the FLTK documentation has any + * \todo Consider, whether this from the FLTK documentation has any * impacts: "To receive fltk::RELEASE events you must return non-zero * when passed a fltk::PUSH event. " */ @@ -205,7 +210,11 @@ int FltkViewBase::handle (int event) translateViewXToCanvasX (event_x ()), translateViewYToCanvasY (event_y ()), getDwButtonState (), event_button ()); - //printf ("PUSH => %s\n", processed ? "true" : "false"); + _MSG("PUSH => %s\n", processed ? "true" : "false"); + if (processed) { + /* pressed dw content; give focus to the view */ + ::fltk::focus(this); + } return processed ? true : Group::handle (event); case RELEASE: @@ -214,7 +223,7 @@ int FltkViewBase::handle (int event) translateViewXToCanvasX (event_x ()), translateViewYToCanvasY (event_y ()), getDwButtonState (), event_button ()); - //printf ("RELEASE => %s\n", processed ? "true" : "false"); + _MSG("RELEASE => %s\n", processed ? "true" : "false"); return processed ? true : Group::handle (event); case MOVE: @@ -225,7 +234,7 @@ int FltkViewBase::handle (int event) translateViewXToCanvasX (mouse_x), translateViewYToCanvasY (mouse_y), getDwButtonState ()); - //printf ("MOVE => %s\n", processed ? "true" : "false"); + _MSG("MOVE => %s\n", processed ? "true" : "false"); return processed ? true : Group::handle (event); case DRAG: @@ -234,7 +243,7 @@ int FltkViewBase::handle (int event) translateViewXToCanvasX (event_x ()), translateViewYToCanvasY (event_y ()), getDwButtonState ()); - //printf ("DRAG => %s\n", processed ? "true" : "false"); + _MSG("DRAG => %s\n", processed ? "true" : "false"); return processed ? true : Group::handle (event); case ENTER: @@ -246,7 +255,7 @@ int FltkViewBase::handle (int event) case LEAVE: theLayout->leaveNotify (this, getDwButtonState ()); return Group::handle (event); - + default: return Group::handle (event); } @@ -269,7 +278,7 @@ void FltkViewBase::setCursor (core::style::Cursor cursor) { static Cursor *mapDwToFltk[] = { CURSOR_CROSS, - CURSOR_ARROW, + CURSOR_DEFAULT, CURSOR_HAND, CURSOR_MOVE, CURSOR_WE, @@ -288,7 +297,7 @@ void FltkViewBase::setCursor (core::style::Cursor cursor) /* static char *cursorName[] = { "CURSOR_CROSS", - "CURSOR_ARROW", + "CURSOR_DEFAULT", "CURSOR_HAND", "CURSOR_MOVE", "CURSOR_WE", @@ -304,7 +313,7 @@ void FltkViewBase::setCursor (core::style::Cursor cursor) "CURSOR_HELP" }; - printf ("Cursor changes to '%s'.\n", cursorName[cursor]); + MSG("Cursor changes to '%s'.\n", cursorName[cursor]); */ /** \bug Does not work */ @@ -333,33 +342,13 @@ void FltkViewBase::queueDraw (core::Rectangle *area) redraw (DAMAGE_VALUE); } -static void drawTotalTimeout (void *data) -{ - FltkViewBase *view = (FltkViewBase*) data; - if (time(0) >= view->lastDraw + view->drawDelay) { - view->drawTotal (); - } else { - ::fltk::add_timeout (0.2f, drawTotalTimeout, data); - } -} - -void FltkViewBase::drawTotal () -{ - //static int calls = 0; - //printf(" FltkViewBase::drawTotal calls = %d\n", ++calls); - redraw (DAMAGE_EXPOSE); - lastDraw = time (0); - cancelQueueDraw (); -} - void FltkViewBase::queueDrawTotal () { - drawTotal (); + redraw (DAMAGE_EXPOSE); } void FltkViewBase::cancelQueueDraw () { - ::fltk::remove_timeout (drawTotalTimeout, this); } void FltkViewBase::drawPoint (core::style::Color *color, @@ -383,10 +372,26 @@ void FltkViewBase::drawRectangle (core::style::Color *color, int x, int y, int width, int height) { setcolor(((FltkColor*)color)->colors[shading]); + if (width < 0) { + x += width; + width = -width; + } + if (height < 0) { + y += height; + height = -height; + } + int x1 = translateCanvasXToViewX (x); int y1 = translateCanvasYToViewY (y); int x2 = translateCanvasXToViewX (x + width); int y2 = translateCanvasYToViewY (y + height); + + // We only support rectangles with line width 1px, so we clip with + // a rectangle 1px wider and higher than what we actually expose. + // This is only really necessary for non-filled rectangles. + clipPoint (&x1, &y1, 1); + clipPoint (&x2, &y2, 1); + ::fltk::Rectangle rect (x1, y1, x2 - x1, y2 - y1); if (filled) fillrect (rect); @@ -396,13 +401,13 @@ void FltkViewBase::drawRectangle (core::style::Color *color, void FltkViewBase::drawArc (core::style::Color *color, core::style::Color::Shading shading, bool filled, - int x, int y, int width, int height, + int centerX, int centerY, int width, int height, int angle1, int angle2) { setcolor(((FltkColor*)color)->colors[shading]); - int x1 = translateCanvasXToViewX (x); - int y1 = translateCanvasYToViewY (y); - ::fltk::Rectangle rect (x1, y1, width, height); + int x = translateCanvasXToViewX (centerX) - width / 2; + int y = translateCanvasYToViewY (centerY) - height / 2; + ::fltk::Rectangle rect (x, y, width, height); addchord(rect, angle1, angle2); closepath(); if (filled) @@ -427,7 +432,7 @@ void FltkViewBase::drawPolygon (core::style::Color *color, fillpath(); else strokepath(); - } + } } core::View *FltkViewBase::getClippingView (int x, int y, int width, int height) @@ -456,7 +461,7 @@ FltkWidgetView::~FltkWidgetView () void FltkWidgetView::layout () { /** - * pass layout to child widgets. This is needed for complex fltk + * pass layout to child widgets. This is needed for complex fltk * widgets as TextEditor. * We can't use Group::layout() as that would rearrange the widgets. */ @@ -477,8 +482,23 @@ void FltkWidgetView::drawText (core::style::Font *font, FltkFont *ff = (FltkFont*)font; setfont(ff->font, ff->size); setcolor(((FltkColor*)color)->colors[shading]); - drawtext(text, len, - translateCanvasXToViewX (x), translateCanvasYToViewY (y)); + + if (!font->letterSpacing) { + drawtext(text, len, + translateCanvasXToViewX (x), translateCanvasYToViewY (y)); + } else { + /* Nonzero letter spacing adjustment, draw each glyph individually */ + int viewX = translateCanvasXToViewX (x), + viewY = translateCanvasYToViewY (y); + int curr = 0, next = 0; + + while (next < len) { + next = theLayout->nextGlyph(text, curr); + drawtext(text + curr, next - curr, viewX, viewY); + viewX += font->letterSpacing + (int)getwidth(text + curr,next - curr); + curr = next; + } + } } void FltkWidgetView::drawImage (core::Imgbuf *imgbuf, int xRoot, int yRoot, |