aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
Diffstat (limited to 'dw')
-rw-r--r--dw/findtext.cc10
-rw-r--r--dw/fltkcomplexbutton.cc345
-rw-r--r--dw/fltkcomplexbutton.hh54
-rw-r--r--dw/fltkcore.hh2
-rw-r--r--dw/fltkflatview.cc20
-rw-r--r--dw/fltkflatview.hh3
-rw-r--r--dw/fltkimgbuf.cc14
-rw-r--r--dw/fltkimgbuf.hh2
-rw-r--r--dw/fltkmisc.cc11
-rw-r--r--dw/fltkplatform.cc370
-rw-r--r--dw/fltkplatform.hh33
-rw-r--r--dw/fltkpreview.cc56
-rw-r--r--dw/fltkpreview.hh15
-rw-r--r--dw/fltkui.cc792
-rw-r--r--dw/fltkui.hh134
-rw-r--r--dw/fltkviewbase.cc542
-rw-r--r--dw/fltkviewbase.hh61
-rw-r--r--dw/fltkviewport.cc284
-rw-r--r--dw/fltkviewport.hh22
-rw-r--r--dw/image.cc15
-rw-r--r--dw/layout.cc77
-rw-r--r--dw/layout.hh10
-rw-r--r--dw/platform.hh5
-rw-r--r--dw/selection.cc132
-rw-r--r--dw/selection.hh40
-rw-r--r--dw/style.cc339
-rw-r--r--dw/table.cc10
-rw-r--r--dw/textblock.cc110
-rw-r--r--dw/textblock.hh4
-rw-r--r--dw/types.cc11
-rw-r--r--dw/types.hh3
-rw-r--r--dw/ui.cc4
-rw-r--r--dw/ui.hh2
-rw-r--r--dw/view.hh14
-rw-r--r--dw/widget.hh14
35 files changed, 1868 insertions, 1692 deletions
diff --git a/dw/findtext.cc b/dw/findtext.cc
index f3e0ba20..9793db91 100644
--- a/dw/findtext.cc
+++ b/dw/findtext.cc
@@ -37,7 +37,7 @@ FindtextState::FindtextState ()
FindtextState::~FindtextState ()
{
if (key)
- delete key;
+ free(key);
if (nexttab)
delete[] nexttab;
if (iterator)
@@ -52,7 +52,7 @@ void FindtextState::setWidget (Widget *widget)
// A widget change will restart the search.
if (key)
- delete key;
+ free(key);
key = NULL;
if (nexttab)
delete[] nexttab;
@@ -81,7 +81,7 @@ FindtextState::Result FindtextState::search (const char *key, bool caseSens,
strcmp (this->key, key) != 0) {
newKey = true;
if (this->key)
- delete this->key;
+ free(this->key);
this->key = strdup (key);
this->caseSens = caseSens;
@@ -106,7 +106,7 @@ FindtextState::Result FindtextState::search (const char *key, bool caseSens,
bool firstTrial = !wasHighlighted || newKey;
if (search0 (backwards, firstTrial)) {
- // Highlighlighting is done with a clone.
+ // Highlighting is done with a clone.
hlIterator = iterator->cloneCharIterator ();
for (int i = 0; key[i]; i++)
hlIterator->next ();
@@ -147,7 +147,7 @@ void FindtextState::resetSearch ()
unhighlight ();
if (key)
- delete key;
+ free(key);
key = NULL;
}
diff --git a/dw/fltkcomplexbutton.cc b/dw/fltkcomplexbutton.cc
index f80d0eb0..89295190 100644
--- a/dw/fltkcomplexbutton.cc
+++ b/dw/fltkcomplexbutton.cc
@@ -1,7 +1,5 @@
-
-// fltkcomplexbutton.cc contains code from FLTK2's src/Button.cxx
-// that is Copyright 1998-2006 by Bill Spitzak and others.
-// (see http://svn.easysw.com/public/fltk/fltk/trunk/src/Button.cxx)
+// fltkcomplexbutton.cc contains code from FLTK 1.3's src/Fl_Button.cxx
+// that is Copyright 1998-2010 by Bill Spitzak and others.
/*
* This program is free software; you can redistribute it and/or modify
@@ -18,263 +16,128 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <fltk/events.h>
-#include <fltk/damage.h>
-#include <fltk/Group.h>
-#include <fltk/Box.h>
-#include <stdlib.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Window.H>
#include "fltkcomplexbutton.hh"
-using namespace fltk;
using namespace dw::fltk::ui;
-/*! \class fltk::ComplexButton
-
- ComplexButtons generate callbacks when they are clicked by the user. You
- control exactly when and how by changing the values for when():
- - fltk::WHEN_NEVER: The callback is not done, instead changed() is
- turned on.
- - fltk::WHEN_RELEASE: This is the default, the callback is done
- after the user successfully clicks the button (i.e. they let it go
- with the mouse still pointing at it), or when a shortcut is typed.
- - fltk::WHEN_CHANGED : The callback is done each time the value()
- changes (when the user pushes and releases the button, and as the
- mouse is dragged around in and out of the button).
-
- ComplexButtons can also generate callbacks in response to fltk::SHORTCUT
- events. The button can either have an explicit shortcut() value or a
- letter shortcut can be indicated in the label() with an '&'
- character before it. For the label shortcut it does not matter if
- Alt is held down, but if you have an input field in the same window,
- the user will have to hold down the Alt key so that the input field
- does not eat the event first as an fltk::KEY event.
-
- \image html buttons.gif
-*/
-
-/*! \fn bool ComplexButton::value() const
- The current value. True means it is pushed down, false means it is
- not pushed down. The ToggleComplexButton subclass provides the ability for
- the user to change this value permanently, otherwise it is just
- temporary while the user is holding the button down.
-
- This is the same as Widget::state().
-*/
-
-/*! \fn bool ComplexButton::value(bool)
- Change the value(). Redraws the button and returns true if the new
- value is different. This is the same function as Widget::state().
- See also Widget::set(), Widget::clear(), and Widget::setonly().
-
- If you turn it on, a normal button will draw pushed-in, until
- the user clicks it and releases it.
-*/
-
-static bool initial_state;
+/**
+ Sets the current value of the button.
+ A non-zero value sets the button to 1 (ON), and zero sets it to 0 (OFF).
+ \param[in] v button value.
+ */
+int ComplexButton::value(int v) {
+ v = v ? 1 : 0;
+ oldval = v;
+ clear_changed();
+ if (value_ != v) {
+ value_ = v;
+ if (box()) redraw();
+ return 1;
+ } else {
+ return 0;
+ }
+}
-int ComplexButton::handle(int event) {
- return handle(event, Rectangle(w(),h()));
+void ComplexButton::draw() {
+ Fl_Color col = value() ? selection_color() : color();
+ draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
+ if (Fl::focus() == this) draw_focus();
+
+ // ComplexButton is a Group; draw its children
+ for (int i = children () - 1; i >= 0; i--) {
+ // set absolute coordinates for fltk-1.3 --jcid
+ child (i)->position(x()+(w()-child(i)->w())/2,y()+(h()-child(i)->h())/2);
+ draw_child (*child (i));
+ }
}
-int ComplexButton::handle(int event, const Rectangle& rectangle) {
+int ComplexButton::handle(int event) {
+ int newval;
switch (event) {
- case ENTER:
- case LEAVE:
- redraw_highlight();
- case MOVE:
+ case FL_ENTER: /* FALLTHROUGH */
+ case FL_LEAVE:
return 1;
- case PUSH:
- if (pushed()) return 1; // ignore extra pushes on currently-pushed button
- initial_state = state();
- clear_flag(PUSHED);
- /* do_callback(); */
- case DRAG: {
- bool inside = event_inside(rectangle);
- if (inside) {
- if (!flag(PUSHED)) {
- set_flag(PUSHED);
- redraw(DAMAGE_VALUE);
- }
- } else {
- if (flag(PUSHED)) {
- clear_flag(PUSHED);
- redraw(DAMAGE_VALUE);
- }
- }
- if (when() & WHEN_CHANGED) { // momentary button must record state()
- if (state(inside ? !initial_state : initial_state))
- do_callback();
+ case FL_PUSH:
+ if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+ case FL_DRAG:
+ if (Fl::event_inside(this)) {
+ newval = !oldval;
+ } else
+ {
+ clear_changed();
+ newval = oldval;
}
- return 1;}
- case RELEASE:
- if (!flag(PUSHED)) return 1;
- clear_flag(PUSHED);
- redraw(DAMAGE_VALUE);
- if (type() == RADIO)
- setonly();
- else if (type() == TOGGLE)
- state(!initial_state);
- else {
- state(initial_state);
- if (when() & WHEN_CHANGED) {do_callback(); return 1;}
+ if (newval != value_) {
+ value_ = newval;
+ set_changed();
+ redraw();
+ if (when() & FL_WHEN_CHANGED) do_callback();
}
- if (when() & WHEN_RELEASE) do_callback(); else set_changed();
return 1;
- case FOCUS:
- redraw(1); // minimal redraw to just add the focus box
- // grab initial focus if we are an ReturnComplexButton:
- return shortcut()==ReturnKey ? 2 : 1;
- case UNFOCUS:
- redraw(DAMAGE_HIGHLIGHT);
- return 1;
- case KEY:
- if (event_key() == ' ' || event_key() == ReturnKey
- || event_key() == KeypadEnter) goto EXECUTE;
- return 0;
- case SHORTCUT:
- if (!test_shortcut()) return 0;
- EXECUTE:
- if (type() == RADIO) {
- if (!state()) {
- setonly();
- if (when() & WHEN_CHANGED) do_callback(); else set_changed();
- }
- } else if (type() == TOGGLE) {
- state(!state());
- if (when() & WHEN_CHANGED) do_callback(); else set_changed();
+ case FL_RELEASE:
+ if (value_ == oldval) {
+ if (when() & FL_WHEN_NOT_CHANGED) do_callback();
+ return 1;
}
- if (when() & WHEN_RELEASE) do_callback();
+ set_changed();
+ value(oldval);
+ set_changed();
+ if (when() & FL_WHEN_CHANGED) {
+ Fl_Widget_Tracker wp(this);
+ do_callback();
+ if (wp.deleted()) return 1;
+ }
+ if (when() & FL_WHEN_RELEASE) do_callback();
return 1;
+ case FL_FOCUS : /* FALLTHROUGH */
+ case FL_UNFOCUS :
+ if (Fl::visible_focus()) {
+ if (box() == FL_NO_BOX) {
+ // Widgets with the FL_NO_BOX boxtype need a parent to
+ // redraw, since it is responsible for redrawing the
+ // background...
+ int X = x() > 0 ? x() - 1 : 0;
+ int Y = y() > 0 ? y() - 1 : 0;
+ if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+ } else redraw();
+ return 1;
+ } else return 0;
+ case FL_KEYBOARD :
+ if (Fl::focus() == this && Fl::event_key() == ' ' &&
+ !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
+ set_changed();
+ Fl_Widget_Tracker wp(this);
+ if (wp.deleted()) return 1;
+ if (when() & FL_WHEN_RELEASE) do_callback();
+ return 1;
+ }
default:
return 0;
}
}
-////////////////////////////////////////////////////////////////
-
-#include <fltk/draw.h>
-
-extern Widget* fl_did_clipping;
-
-/*!
- This function provides a mess of back-compatabilty and Windows
- emulation to subclasses of ComplexButton to draw with. It will draw the
- button according to the current state of being pushed and it's
- state(). If non-zero is passed for \a glyph_width then the glyph()
- is drawn in that space on the left (or on the right if negative),
- and it assummes the glyph indicates the state(), so the box is only
- used to indicate the pushed state.
-*/
-void ComplexButton::draw(int glyph_width) const
-{
- // For back-compatability, setting color() or box() directly on a plain
- // button will cause it to act like buttoncolor() or buttonbox() are
- // set:
- Style localstyle;
- const Style* style = this->style();
- if (!glyph_width) {
- localstyle = *style;
- if (localstyle.color_) localstyle.buttoncolor_ = localstyle.color_;
- if (localstyle.box_) localstyle.buttonbox_ = localstyle.box_;
- if (localstyle.labelcolor_) localstyle.textcolor_ = localstyle.labelcolor_;
- style = &localstyle;
- }
-
- Box* box = style->buttonbox();
-
- Flags box_flags = flags() | OUTPUT;
- Flags glyph_flags = box_flags & ~(HIGHLIGHT|OUTPUT);
- if (glyph_width) box_flags &= ~STATE;
-
- // only draw "inside" labels:
- Rectangle r(0,0,w(),h());
-
- if (box == NO_BOX) {
- Color bg;
- if (box_flags & HIGHLIGHT && (bg = style->highlight_color())) {
- setcolor(bg);
- fillrect(r);
- } else if (label() || (damage()&(DAMAGE_EXPOSE|DAMAGE_HIGHLIGHT))) {
- // erase the background so we can redraw the label in the new color:
- draw_background();
- }
- // this allows these buttons to be put into browser/menus:
- //fg = fl_item_labelcolor(this);
- } else {
- if ((damage()&(DAMAGE_EXPOSE|DAMAGE_HIGHLIGHT))
- && !box->fills_rectangle()) {
- // Erase the area behind non-square boxes
- draw_background();
- }
- }
-
- // Draw the box:
- drawstyle(style,box_flags);
- // For back-compatability we use any directly-set selection_color()
- // to color the box:
- if (!glyph_width && state() && style->selection_color_) {
- setbgcolor(style->selection_color_);
- setcolor(contrast(style->selection_textcolor(),style->selection_color_));
- }
- box->draw(r);
- Rectangle r1(r); box->inset(r1);
-
- if (glyph_width) {
- int g = abs(glyph_width);
- Rectangle lr(r1);
- Rectangle gr(r1, g, g);
- if (glyph_width < 0) {
- lr.w(lr.w()-g-3);
- gr.x(r1.r()-g-3);
- } else {
- lr.set_x(g+3);
- gr.x(r1.x()+3);
- }
- this->draw_label(lr, box_flags);
- drawstyle(style,glyph_flags);
- this->glyph()->draw(gr);
- drawstyle(style,box_flags);
- } else {
- this->draw_label(r1, box_flags);
- }
- box->draw_symbol_overlay(r);
-}
-
-void ComplexButton::draw() {
- if (type() == HIDDEN) {
- fl_did_clipping = this;
- return;
- }
- draw(0);
-
- // ComplexButton is a Group, draw its children
- for (int i = children () - 1; i >= 0; i--)
- draw_child (*child (i));
+/**
+ The constructor creates the button using the given position, size and label.
+ \param[in] X, Y, W, H position and size of the widget
+ \param[in] L widget label, default is no label
+ */
+ComplexButton::ComplexButton(int X, int Y, int W, int H, const char *L)
+: Fl_Group(X,Y,W,H,L) {
+ Fl_Group::current(0);
+ box(FL_UP_BOX);
+ down_box(FL_NO_BOX);
+ value_ = oldval = 0;
}
-////////////////////////////////////////////////////////////////
-
-static NamedStyle style("ComplexButton", 0, &ComplexButton::default_style);
-NamedStyle* ComplexButton::default_style = &::style;
-
-ComplexButton::ComplexButton(int x,int y,int w,int h, const char *l) :
- Group(x,y,w,h,l)
-{
- style(default_style);
- highlight_color(GRAY20);
- //set_click_to_focus();
+ComplexButton::~ComplexButton() {
+ /*
+ * The Fl_Group destructor clear()s the children, but layout expects
+ * the flat view to be around until it deletes it.
+ */
+ remove(0);
}
-
-////////////////////////////////////////////////////////////////
-
-/*! \class fltk::ToggleComplexButton
- This button turns the state() on and off each release of a click
- inside of it.
-
- You can also convert a regular button into this by doing
- type(ComplexButton::TOGGLE) to it.
-*/
-
-//
-//
diff --git a/dw/fltkcomplexbutton.hh b/dw/fltkcomplexbutton.hh
index 83160c06..3a14cfb2 100644
--- a/dw/fltkcomplexbutton.hh
+++ b/dw/fltkcomplexbutton.hh
@@ -1,7 +1,6 @@
-// fltkcomplexbutton.hh contains code from FLTK2's fltk/Button.h
-// that is Copyright 2002 by Bill Spitzak and others.
-// (see http://svn.easysw.com/public/fltk/fltk/trunk/fltk/Button.h)
+// fltkcomplexbutton.hh contains code from FLTK 1.3's FL/Fl_Button.H
+// that is Copyright 1998-2010 by Bill Spitzak and others.
/*
* This program is free software; you can redistribute it and/or modify
@@ -21,35 +20,56 @@
#ifndef __FLTK_COMPLEX_BUTTON_HH__
#define __FLTK_COMPLEX_BUTTON_HH__
-#include <fltk/Group.h>
+#include <FL/Fl_Group.H>
+
+extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*);
namespace dw {
namespace fltk {
namespace ui {
-class ComplexButton: public ::fltk::Group
-{
+class FL_EXPORT ComplexButton : public Fl_Group {
+
+ int shortcut_;
+ char value_;
+ char oldval;
+ uchar down_box_;
+
+protected:
+ virtual void draw();
+
public:
- enum {HIDDEN=3}; // back-comptability value to hide the button
+ virtual int handle(int);
- bool value() const { return state(); }
- bool value(bool v) { return state(v); }
+ ComplexButton(int X, int Y, int W, int H, const char *L = 0);
+ ~ComplexButton();
- int handle(int);
- int handle(int event, const Rectangle&);
- ComplexButton(int,int,int,int,const char * = 0);
- ~ComplexButton() { remove_all ();};
- static ::fltk::NamedStyle* default_style;
+ int value(int v);
- virtual void draw();
- void draw(int glyph_width) const;
+ /**
+ Returns the current value of the button (0 or 1).
+ */
+ char value() const {return value_;}
+
+ /**
+ Returns the current down box type, which is drawn when value() is non-zero.
+ \retval Fl_Boxtype
+ */
+ Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}
+
+ /**
+ Sets the down box type. The default value of 0 causes FLTK to figure out
+ the correct matching down version of box().
+ \param[in] b down box type
+ */
+ void down_box(Fl_Boxtype b) {down_box_ = b;}
};
} // namespace ui
} // namespace fltk
} // namespace dw
-#endif // __FLTK_COMPLEX_BUTTON_HH__
+#endif
//
//
diff --git a/dw/fltkcore.hh b/dw/fltkcore.hh
index fbff3fad..376f588e 100644
--- a/dw/fltkcore.hh
+++ b/dw/fltkcore.hh
@@ -13,7 +13,7 @@ class FltkResource;
} // namespace fltk
} // namespace core
-#include <fltk/Widget.h>
+#include <FL/Fl_Widget.H>
#include "core.hh"
#include "fltkimgbuf.hh"
diff --git a/dw/fltkflatview.cc b/dw/fltkflatview.cc
index 85385394..b9e85d99 100644
--- a/dw/fltkflatview.cc
+++ b/dw/fltkflatview.cc
@@ -21,12 +21,8 @@
#include "fltkflatview.hh"
-#include <fltk/draw.h>
-#include <fltk/events.h>
-
#include <stdio.h>
-using namespace fltk;
using namespace lout::container::typed;
namespace dw {
@@ -82,24 +78,24 @@ void FltkFlatView::setViewportSize (int width, int height,
{
}
-int FltkFlatView::translateViewXToCanvasX (int x)
+int FltkFlatView::translateViewXToCanvasX (int X)
{
- return x;
+ return X - x ();
}
-int FltkFlatView::translateViewYToCanvasY (int y)
+int FltkFlatView::translateViewYToCanvasY (int Y)
{
- return y;
+ return Y - y ();
}
-int FltkFlatView::translateCanvasXToViewX (int x)
+int FltkFlatView::translateCanvasXToViewX (int X)
{
- return x;
+ return X + x ();
}
-int FltkFlatView::translateCanvasYToViewY (int y)
+int FltkFlatView::translateCanvasYToViewY (int Y)
{
- return y;
+ return Y + y ();
}
diff --git a/dw/fltkflatview.hh b/dw/fltkflatview.hh
index 5106cbdf..8d84fda9 100644
--- a/dw/fltkflatview.hh
+++ b/dw/fltkflatview.hh
@@ -1,9 +1,6 @@
#ifndef __DW_FLTKFLATVIEW_HH__
#define __DW_FLTKFLATVIEW_HH__
-#include <fltk/Group.h>
-#include <fltk/Scrollbar.h>
-
#include "core.hh"
#include "fltkcore.hh"
#include "fltkviewbase.hh"
diff --git a/dw/fltkimgbuf.cc b/dw/fltkimgbuf.cc
index e3be41a9..97cbc1b4 100644
--- a/dw/fltkimgbuf.cc
+++ b/dw/fltkimgbuf.cc
@@ -23,13 +23,10 @@
#include "../lout/msg.h"
#include "../lout/misc.hh"
-#include <fltk/draw.h>
-#include <fltk/Color.h>
+#include <FL/fl_draw.H>
#define IMAGE_MAX_AREA (6000 * 6000)
-using namespace fltk;
-
namespace dw {
namespace fltk {
@@ -302,7 +299,7 @@ int FltkImgbuf::scaledY(int ySrc)
return ySrc * height / root->height;
}
-void FltkImgbuf::draw (::fltk::Widget *target, int xRoot, int yRoot,
+void FltkImgbuf::draw (Fl_Widget *target, int xRoot, int yRoot,
int x, int y, int width, int height)
{
// TODO: Clarify the question, whether "target" is the current widget
@@ -324,10 +321,9 @@ void FltkImgbuf::draw (::fltk::Widget *target, int xRoot, int yRoot,
height = this->height - y;
}
- // Draw
- ::fltk::Rectangle rect (xRoot + x, yRoot + y, width, height);
- PixelType ptype = (type == RGBA) ? ::fltk::RGBA : ::fltk::RGB;
- drawimage(rawdata+bpp*(y*this->width + x),ptype,rect,bpp*this->width);
+ fl_draw_image(rawdata+bpp*(y*this->width + x), xRoot + x, yRoot + y, width,
+ height, bpp, this->width * bpp);
+
}
} // namespace dw
diff --git a/dw/fltkimgbuf.hh b/dw/fltkimgbuf.hh
index 54d9ca34..30e0cc37 100644
--- a/dw/fltkimgbuf.hh
+++ b/dw/fltkimgbuf.hh
@@ -55,7 +55,7 @@ public:
void setDeleteOnUnref (bool deleteOnUnref);
bool isReferred ();
- void draw (::fltk::Widget *target, int xRoot, int yRoot,
+ void draw (Fl_Widget *target, int xRoot, int yRoot,
int x, int y, int width, int height);
};
diff --git a/dw/fltkmisc.cc b/dw/fltkmisc.cc
index 5d20a87a..01024f25 100644
--- a/dw/fltkmisc.cc
+++ b/dw/fltkmisc.cc
@@ -18,11 +18,10 @@
*/
-
+#include "../lout/msg.h"
#include "fltkmisc.hh"
-#include <fltk/events.h>
-#include <fltk/Monitor.h>
+#include <FL/Fl.H>
#include <stdio.h>
namespace dw {
@@ -31,17 +30,17 @@ namespace misc {
int screenWidth ()
{
- return ::fltk::Monitor::all ().w ();
+ return Fl::w ();
}
int screenHeight ()
{
- return ::fltk::Monitor::all ().h ();
+ return Fl::h ();
}
void warpPointer (int x, int y)
{
- ::fltk::warp_mouse (x, y);
+ MSG_ERR("no warpPointer mechanism available.\n");
}
} // namespace misc
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index 17eb5d51..68819c91 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -18,24 +18,36 @@
*/
#include <stdio.h>
-#include <wchar.h>
-#include <wctype.h>
#include "../lout/msg.h"
#include "fltkcore.hh"
-#include <fltk/draw.h>
-#include <fltk/run.h>
-#include <fltk/events.h>
-#include <fltk/Monitor.h>
-#include <fltk/InvisibleBox.h>
-#include <fltk/Tooltip.h>
-#include <fltk/utf.h>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/Fl_Menu_Window.H>
+#include <FL/Fl_Paged_Device.H>
+
+/*
+ * Local data
+ */
+
+/* Use of Fl_Text_Display links in a lot of printer code that we don't have
+ * any need for currently. This stub prevents that. */
+class FL_EXPORT Fl_Printer : public Fl_Paged_Device {
+public:
+ static const char *class_id;
+ Fl_Printer(void) {};
+};
+const char *Fl_Printer::class_id = "Fl_Printer";
+
+/* Tooltips */
+static Fl_Menu_Window *tt_window = NULL;
+static int in_tooltip = 0, req_tooltip = 0;
namespace dw {
namespace fltk {
-using namespace ::fltk;
using namespace lout;
/**
@@ -47,37 +59,78 @@ container::typed::HashTable <dw::core::style::FontAttrs,
new container::typed::HashTable <dw::core::style::FontAttrs,
FltkFont> (false, false);
+container::typed::HashTable <lout::object::ConstString,
+ FltkFont::FontFamily> *FltkFont::systemFonts =
+ NULL;
+
+FltkFont::FontFamily FltkFont::standardFontFamily (FL_HELVETICA,
+ FL_HELVETICA_BOLD,
+ FL_HELVETICA_ITALIC,
+ FL_HELVETICA_BOLD_ITALIC);
+
+FltkFont::FontFamily::FontFamily (Fl_Font fontNormal, Fl_Font fontBold,
+ Fl_Font fontItalic, Fl_Font fontBoldItalic)
+{
+ font[0] = fontNormal;
+ font[1] = fontBold;
+ font[2] = fontItalic;
+ font[3] = fontBoldItalic;
+}
+
+void FltkFont::FontFamily::set (Fl_Font f, int attrs)
+{
+ int idx = 0;
+ if (attrs & FL_BOLD)
+ idx += 1;
+ if (attrs & FL_ITALIC)
+ idx += 2;
+ font[idx] = f;
+}
+
+Fl_Font FltkFont::FontFamily::get (int attrs)
+{
+ int idx = 0;
+ if (attrs & FL_BOLD)
+ idx += 1;
+ if (attrs & FL_ITALIC)
+ idx += 2;
+
+ // should the desired font style not exist, we
+ // return the normal font of the fontFamily
+ return font[idx] >= 0 ? font[idx] : font[0];
+}
+
+
+
FltkFont::FltkFont (core::style::FontAttrs *attrs)
{
+ if (!systemFonts)
+ initSystemFonts ();
+
copyAttrs (attrs);
int fa = 0;
if (weight >= 500)
- fa |= BOLD;
+ fa |= FL_BOLD;
if (style != core::style::FONT_STYLE_NORMAL)
- fa |= ITALIC;
+ fa |= FL_ITALIC;
- font = ::fltk::font(name, fa);
- if (font == NULL) {
- /*
- * If using xft, fltk::HELVETICA just means sans, fltk::COURIER
- * means mono, and fltk::TIMES means serif.
- */
- font = HELVETICA->plus (fa);
- }
+ object::ConstString nameString (name);
+ FontFamily *family = systemFonts->get (&nameString);
+ if (!family)
+ family = &standardFontFamily;
- setfont(font, size);
- spaceWidth = misc::max(0, (int)getwidth(" ") + letterSpacing);
- int xw, xh;
- measure("x", xw, xh);
- xHeight = xh;
- ascent = (int)getascent();
- descent = (int)getdescent();
+ font = family->get (fa);
- /**
- * \bug The code above does not seem to work, so this workaround.
- */
- xHeight = ascent * 3 / 5;
+ fl_font(font, size);
+ /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
+ * Reported to FLTK as STR #2688 */
+ spaceWidth = misc::max(0, (int)fl_width(" ") + letterSpacing);
+ int xx, xy, xw, xh;
+ fl_text_extents("x", xx, xy, xw, xh);
+ xHeight = xh;
+ descent = fl_descent();
+ ascent = fl_height() - descent;
}
FltkFont::~FltkFont ()
@@ -85,10 +138,75 @@ FltkFont::~FltkFont ()
fontsTable->remove (this);
}
+static void strstrip(char *big, const char *little)
+{
+ if (strlen(big) >= strlen(little) &&
+ strcasecmp(big + strlen(big) - strlen(little), little) == 0)
+ *(big + strlen(big) - strlen(little)) = '\0';
+}
+
+void FltkFont::initSystemFonts ()
+{
+ systemFonts = new container::typed::HashTable
+ <lout::object::ConstString, FontFamily> (true, true);
+
+ int k = Fl::set_fonts ("-*-iso10646-1");
+ for (int i = 0; i < k; i++) {
+ int t;
+ char *name = strdup (Fl::get_font_name ((Fl_Font) i, &t));
+
+ // normalize font family names (strip off "bold", "italic")
+ if (t & FL_ITALIC)
+ strstrip(name, " italic");
+ if (t & FL_BOLD)
+ strstrip(name, " bold");
+
+ _MSG("Found font: %s%s%s\n", name, t & FL_BOLD ? " bold" : "",
+ t & FL_ITALIC ? " italic" : "");
+
+ object::String *familyName = new object::String(name);
+ free (name);
+ FontFamily *family = systemFonts->get (familyName);
+
+ if (family) {
+ family->set ((Fl_Font) i, t);
+ delete familyName;
+ } else {
+ // set first font of family also as normal font in case there
+ // is no normal (non-bold, non-italic) font
+ family = new FontFamily ((Fl_Font) i, -1, -1, -1);
+ family->set ((Fl_Font) i, t);
+ systemFonts->put (familyName, family);
+ }
+ }
+}
+
+bool
+FltkFont::fontExists (const char *name)
+{
+ if (!systemFonts)
+ initSystemFonts ();
+ object::ConstString familyName (name);
+ return systemFonts->get (&familyName) != NULL;
+}
+
+Fl_Font
+FltkFont::get (const char *name, int attrs)
+{
+ if (!systemFonts)
+ initSystemFonts ();
+ object::ConstString familyName (name);
+ FontFamily *family = systemFonts->get (&familyName);
+ if (family)
+ return family->get (attrs);
+ else
+ return FL_HELVETICA;
+}
+
bool
FltkPlatform::fontExists (const char *name)
{
- return ::fltk::font(name) != NULL;
+ return FltkFont::fontExists (name);
}
FltkFont*
@@ -114,26 +232,14 @@ FltkColor::FltkColor (int color): Color (color)
{
this->color = color;
- /*
- * fltk/setcolor.cxx:
- * "A Color of zero (fltk::NO_COLOR) will draw black but is
- * ambiguous. It is returned as an error value or to indicate portions
- * of a Style that should be inherited, and it is also used as the
- * default label color for everything so that changing color zero can
- * be used by the -fg switch. You should use fltk::BLACK (56) to get
- * black."
- *
- * i.e., zero only works sometimes.
- */
-
if (!(colors[SHADING_NORMAL] = shadeColor (color, SHADING_NORMAL) << 8))
- colors[SHADING_NORMAL] = ::fltk::BLACK;
+ colors[SHADING_NORMAL] = FL_BLACK;
if (!(colors[SHADING_INVERSE] = shadeColor (color, SHADING_INVERSE) << 8))
- colors[SHADING_INVERSE] = ::fltk::BLACK;
+ colors[SHADING_INVERSE] = FL_BLACK;
if (!(colors[SHADING_DARK] = shadeColor (color, SHADING_DARK) << 8))
- colors[SHADING_DARK] = ::fltk::BLACK;
+ colors[SHADING_DARK] = FL_BLACK;
if (!(colors[SHADING_LIGHT] = shadeColor (color, SHADING_LIGHT) << 8))
- colors[SHADING_LIGHT] = ::fltk::BLACK;
+ colors[SHADING_LIGHT] = FL_BLACK;
}
FltkColor::~FltkColor ()
@@ -156,35 +262,12 @@ FltkColor * FltkColor::create (int col)
FltkTooltip::FltkTooltip (const char *text) : Tooltip(text)
{
- shown = false;
-
- if (!text || !strpbrk(text, "&@")) {
- escaped_str = NULL;
- } else {
- /*
- * WORKAROUND: ::fltk::Tooltip::tooltip_timeout() makes instance_
- * if necessary, and immediately uses it. This means that we can't
- * get our hands on it to set RAW_LABEL until after it has been shown
- * once. So let's escape the special characters ourselves.
- */
- const char *src = text;
- char *dest = escaped_str = (char *) malloc(strlen(text) * 2 + 1);
-
- while (*src) {
- if (*src == '&' || *src == '@')
- *dest++ = *src;
- *dest++ = *src++;
- }
- *dest = '\0';
- }
}
FltkTooltip::~FltkTooltip ()
{
- if (shown)
- ::fltk::Tooltip::exit();
- if (escaped_str)
- free(escaped_str);
+ if (in_tooltip || req_tooltip)
+ cancel(); /* cancel tooltip window */
}
FltkTooltip *FltkTooltip::create (const char *text)
@@ -192,40 +275,115 @@ FltkTooltip *FltkTooltip::create (const char *text)
return new FltkTooltip(text);
}
+/*
+ * Tooltip callback: used to delay it a bit
+ * INVARIANT: Only one instance of this function is requested.
+ */
+static void tooltip_tcb(void *data)
+{
+ req_tooltip = 2;
+ ((FltkTooltip *)data)->onEnter();
+ req_tooltip = 0;
+}
+
void FltkTooltip::onEnter()
{
- fltk::Widget *widget = fltk::belowmouse();
+ _MSG("FltkTooltip::onEnter\n");
+ if (!str || !*str)
+ return;
+ if (req_tooltip == 0) {
+ Fl::remove_timeout(tooltip_tcb);
+ Fl::add_timeout(1.0, tooltip_tcb, this);
+ req_tooltip = 1;
+ return;
+ }
- ::fltk::Tooltip::enter(widget, *((fltk::Rectangle *)widget),
- escaped_str ? escaped_str : str);
- shown = true;
+ if (!tt_window) {
+ tt_window = new Fl_Menu_Window(0,0,100,24);
+ tt_window->set_override();
+ tt_window->box(FL_NO_BOX);
+ Fl_Box *b = new Fl_Box(0,0,100,24);
+ b->box(FL_BORDER_BOX);
+ b->color(fl_color_cube(FL_NUM_RED-1, FL_NUM_GREEN-1, FL_NUM_BLUE-2));
+ b->labelcolor(FL_BLACK);
+ b->labelfont(FL_HELVETICA);
+ b->labelsize(14);
+ b->align(FL_ALIGN_WRAP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
+ tt_window->resizable(b);
+ tt_window->end();
+ }
+
+ /* prepare tooltip window */
+ int x, y;
+ Fl_Box *box = (Fl_Box*)tt_window->child(0);
+ box->label(str);
+ Fl::get_mouse(x,y); y += 6;
+ /* calculate window size */
+ int ww, hh;
+ ww = 800; // max width;
+ box->measure_label(ww, hh);
+ ww += 6 + 2 * Fl::box_dx(box->box());
+ hh += 6 + 2 * Fl::box_dy(box->box());
+ tt_window->resize(x,y,ww,hh);
+ tt_window->show();
+ in_tooltip = 1;
}
+/*
+ * Leaving the widget cancels the tooltip
+ */
void FltkTooltip::onLeave()
{
- ::fltk::Tooltip::exit();
- shown = false;
+ _MSG(" FltkTooltip::onLeave in_tooltip=%d\n", in_tooltip);
+ cancel();
+}
+
+void FltkPlatform::cancelTooltip()
+{
+ FltkTooltip::cancel();
+}
+
+/*
+ * Remove a shown tooltip or cancel a pending one
+ */
+void FltkTooltip::cancel()
+{
+ if (req_tooltip) {
+ Fl::remove_timeout(tooltip_tcb);
+ req_tooltip = 0;
+ }
+ if (!in_tooltip) return;
+ in_tooltip = 0;
+ tt_window->hide();
+
+ /* WORKAROUND: (Black magic here)
+ * Hiding a tooltip with the keyboard or mousewheel doesn't work.
+ * The code below "fixes" the problem */
+ Fl_Widget *widget = Fl::belowmouse();
+ if (widget && widget->window()) {
+ widget->window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1);
+ }
}
void FltkTooltip::onMotion()
{
}
-void FltkView::addFltkWidget (::fltk::Widget *widget,
+void FltkView::addFltkWidget (Fl_Widget *widget,
core::Allocation *allocation)
{
}
-void FltkView::removeFltkWidget (::fltk::Widget *widget)
+void FltkView::removeFltkWidget (Fl_Widget *widget)
{
}
-void FltkView::allocateFltkWidget (::fltk::Widget *widget,
+void FltkView::allocateFltkWidget (Fl_Widget *widget,
core::Allocation *allocation)
{
}
-void FltkView::drawFltkWidget (::fltk::Widget *widget, core::Rectangle *area)
+void FltkView::drawFltkWidget (Fl_Widget *widget, core::Rectangle *area)
{
}
@@ -310,7 +468,7 @@ FltkPlatform::FltkPlatform ()
FltkPlatform::~FltkPlatform ()
{
if (idleFuncRunning)
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
delete idleQueue;
delete resources;
}
@@ -354,32 +512,32 @@ int FltkPlatform::textWidth (core::style::Font *font, const char *text,
int len)
{
char chbuf[4];
- wchar_t wc, wcu;
+ int c, cu;
int width = 0;
FltkFont *ff = (FltkFont*) font;
int curr = 0, next = 0, nb;
- if (font->fontVariant == 1) {
+ if (font->fontVariant == core::style::FONT_VARIANT_SMALL_CAPS) {
int sc_fontsize = lout::misc::roundInt(ff->size * 0.78);
for (curr = 0; next < len; curr = next) {
next = nextGlyph(text, curr);
- wc = utf8decode(text + curr, text + next, &nb);
- if ((wcu = towupper(wc)) == wc) {
+ c = fl_utf8decode(text + curr, text + next, &nb);
+ if ((cu = fl_toupper(c)) == c) {
/* already uppercase, just draw the character */
- setfont(ff->font, ff->size);
+ fl_font(ff->font, ff->size);
width += font->letterSpacing;
- width += (int)getwidth(text + curr, next - curr);
+ width += (int)fl_width(text + curr, next - curr);
} else {
/* make utf8 string for converted char */
- nb = utf8encode(wcu, chbuf);
- setfont(ff->font, sc_fontsize);
+ nb = fl_utf8encode(cu, chbuf);
+ fl_font(ff->font, sc_fontsize);
width += font->letterSpacing;
- width += (int)getwidth(chbuf, nb);
+ width += (int)fl_width(chbuf, nb);
}
}
} else {
- setfont (ff->font, ff->size);
- width = (int) getwidth (text, len);
+ fl_font (ff->font, ff->size);
+ width = (int) fl_width (text, len);
if (font->letterSpacing) {
int curr = 0, next = 0;
@@ -397,22 +555,28 @@ int FltkPlatform::textWidth (core::style::Font *font, const char *text,
int FltkPlatform::nextGlyph (const char *text, int idx)
{
- return utf8fwd (&text[idx + 1], text, &text[strlen (text)]) - text;
+ return fl_utf8fwd (&text[idx + 1], text, &text[strlen (text)]) - text;
}
int FltkPlatform::prevGlyph (const char *text, int idx)
{
- return utf8back (&text[idx - 1], text, &text[strlen (text)]) - text;
+ return fl_utf8back (&text[idx - 1], text, &text[strlen (text)]) - text;
}
float FltkPlatform::dpiX ()
{
- return ::fltk::Monitor::all ().dpi_x ();
+ float horizontal, vertical;
+
+ Fl::screen_dpi(horizontal, vertical);
+ return horizontal;
}
float FltkPlatform::dpiY ()
{
- return ::fltk::Monitor::all ().dpi_y ();
+ float horizontal, vertical;
+
+ Fl::screen_dpi(horizontal, vertical);
+ return vertical;
}
void FltkPlatform::generalStaticIdle (void *data)
@@ -435,7 +599,7 @@ void FltkPlatform::generalIdle ()
if (idleQueue->isEmpty()) {
idleFuncRunning = false;
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
}
}
@@ -449,7 +613,7 @@ int FltkPlatform::addIdle (void (core::Layout::*func) ())
* idle function, the passed idle function is put into a queue.
*/
if (!idleFuncRunning) {
- add_idle (generalStaticIdle, (void*)this);
+ Fl::add_idle (generalStaticIdle, (void*)this);
idleFuncRunning = true;
}
@@ -478,7 +642,7 @@ void FltkPlatform::removeIdle (int idleId)
}
if (idleFuncRunning && idleQueue->isEmpty())
- remove_idle (generalStaticIdle, (void*)this);
+ Fl::remove_idle (generalStaticIdle, (void*)this);
}
core::style::Font *FltkPlatform::createFont (core::style::FontAttrs
@@ -500,7 +664,7 @@ core::style::Tooltip *FltkPlatform::createTooltip (const char *text)
void FltkPlatform::copySelection(const char *text)
{
- fltk::copy(text, strlen(text), false);
+ Fl::copy(text, strlen(text), 0);
}
core::Imgbuf *FltkPlatform::createImgbuf (core::Imgbuf::Type type,
diff --git a/dw/fltkplatform.hh b/dw/fltkplatform.hh
index 7a708938..db4bc794 100644
--- a/dw/fltkplatform.hh
+++ b/dw/fltkplatform.hh
@@ -5,8 +5,6 @@
# error Do not include this file directly, use "fltkcore.hh" instead.
#endif
-#include <fltk/Font.h>
-
namespace dw {
/**
@@ -16,16 +14,33 @@ namespace fltk {
class FltkFont: public core::style::Font
{
+ class FontFamily: public lout::object::Object {
+ Fl_Font font[4];
+ public:
+ FontFamily (Fl_Font fontNormal, Fl_Font fontBold,
+ Fl_Font fontItalic, Fl_Font fontBoldItalic);
+ void set (Fl_Font, int attrs);
+ Fl_Font get (int attrs);
+ };
+
+ static FontFamily standardFontFamily;
+
+ static lout::container::typed::HashTable <lout::object::ConstString,
+ FontFamily> *systemFonts;
static lout::container::typed::HashTable <dw::core::style::FontAttrs,
FltkFont> *fontsTable;
FltkFont (core::style::FontAttrs *attrs);
~FltkFont ();
+ static void initSystemFonts ();
+
public:
- ::fltk::Font *font;
+ Fl_Font font;
static FltkFont *create (core::style::FontAttrs *attrs);
+ static bool fontExists (const char *name);
+ static Fl_Font get (const char *name, int attrs);
};
@@ -48,10 +63,9 @@ class FltkTooltip: public core::style::Tooltip
private:
FltkTooltip (const char *text);
~FltkTooltip ();
- bool shown;
- char *escaped_str; /* fltk WORKAROUND */
public:
static FltkTooltip *create(const char *text);
+ static void cancel();
void onEnter();
void onLeave();
void onMotion();
@@ -66,12 +80,12 @@ class FltkView: public core::View
public:
virtual bool usesFltkWidgets () = 0;
- virtual void addFltkWidget (::fltk::Widget *widget,
+ virtual void addFltkWidget (Fl_Widget *widget,
core::Allocation *allocation);
- virtual void removeFltkWidget (::fltk::Widget *widget);
- virtual void allocateFltkWidget (::fltk::Widget *widget,
+ virtual void removeFltkWidget (Fl_Widget *widget);
+ virtual void allocateFltkWidget (Fl_Widget *widget,
core::Allocation *allocation);
- virtual void drawFltkWidget (::fltk::Widget *widget, core::Rectangle *area);
+ virtual void drawFltkWidget (Fl_Widget *widget, core::Rectangle *area);
};
@@ -152,6 +166,7 @@ public:
bool fontExists (const char *name);
core::style::Color *createColor (int color);
core::style::Tooltip *createTooltip (const char *text);
+ void cancelTooltip();
core::Imgbuf *createImgbuf (core::Imgbuf::Type type, int width, int height);
diff --git a/dw/fltkpreview.cc b/dw/fltkpreview.cc
index 7096420f..ecb96f22 100644
--- a/dw/fltkpreview.cc
+++ b/dw/fltkpreview.cc
@@ -22,15 +22,13 @@
#include "fltkpreview.hh"
#include "fltkmisc.hh"
-#include <fltk/events.h>
-#include <fltk/xbmImage.h>
-#include <fltk/draw.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Bitmap.H>
+#include <FL/fl_draw.H>
#include <stdio.h>
#include "preview.xbm"
-using namespace ::fltk;
-
namespace dw {
namespace fltk {
@@ -126,7 +124,7 @@ void FltkPreview::drawText (core::style::Font *font,
* else that measures text).
*/
FltkFont *ff = (FltkFont*)font;
- setfont(ff->font, translateCanvasXToViewX (ff->size));
+ Fl::set_font(ff->font, translateCanvasXToViewX (ff->size));
#if 0
/**
* \todo Normally, this should already be known, maybe it
@@ -144,9 +142,16 @@ void FltkPreview::drawText (core::style::Font *font,
setcolor(((FltkColor*)color)->colors[shading]);
fillrect (rect);
#endif
- setcolor(((FltkColor*)color)->colors[shading]);
- drawtext(text, len,
- translateCanvasXToViewX (x), translateCanvasYToViewY (y));
+ fl_color(((FltkColor*)color)->colors[shading]);
+ fl_draw(text, len, translateCanvasXToViewX (x), translateCanvasYToViewY(y));
+}
+
+void FltkPreview::drawSimpleWrappedText (core::style::Font *font,
+ core::style::Color *color,
+ core::style::Color::Shading shading,
+ int x, int y, int w, int h,
+ const char *text)
+{
}
void FltkPreview::drawImage (core::Imgbuf *imgbuf, int xRoot, int yRoot,
@@ -159,7 +164,7 @@ bool FltkPreview::usesFltkWidgets ()
return false;
}
-void FltkPreview::drawFltkWidget (::fltk::Widget *widget,
+void FltkPreview::drawFltkWidget (Fl_Widget *widget,
core::Rectangle *area)
{
}
@@ -167,9 +172,9 @@ void FltkPreview::drawFltkWidget (::fltk::Widget *widget,
// ----------------------------------------------------------------------
FltkPreviewWindow::FltkPreviewWindow (dw::core::Layout *layout):
- MenuWindow (1, 1)
+ Fl_Menu_Window (1, 1)
{
- box (EMBOSSED_BOX);
+ box (FL_EMBOSSED_BOX);
begin ();
preview = new FltkPreview (BORDER_WIDTH, BORDER_WIDTH, 1, 1, layout);
@@ -205,7 +210,7 @@ void FltkPreviewWindow::reallocate ()
height = preview->canvasHeight * maxWidth / preview->canvasWidth;
}
- get_mouse(mx, my);
+ Fl::get_mouse(mx, my);
posX = mx - preview->translateCanvasXToViewX (preview->scrollX
+ preview->scrollWidth / 2);
@@ -237,13 +242,12 @@ void FltkPreviewWindow::reallocate ()
resize (posX, posY, width, height);
- preview->w (w () - 2 * BORDER_WIDTH);
- preview->h (h () - 2 * BORDER_WIDTH);
+ preview->size(w () - 2 * BORDER_WIDTH, h () - 2 * BORDER_WIDTH);
}
void FltkPreviewWindow::hideWindow ()
{
- Window::hide ();
+ Fl_Window::hide ();
}
void FltkPreviewWindow::scrollTo (int mouseX, int mouseY)
@@ -263,9 +267,9 @@ void FltkPreviewWindow::scrollTo (int mouseX, int mouseY)
FltkPreviewButton::FltkPreviewButton (int x, int y, int w, int h,
dw::core::Layout *layout,
const char *label):
- Button (x, y, w, h, label)
+ Fl_Button (x, y, w, h, label)
{
- image (new xbmImage (preview_bits, preview_width, preview_height));
+ image (new Fl_Bitmap (preview_bits, preview_width, preview_height));
window = new FltkPreviewWindow (layout);
}
@@ -278,23 +282,23 @@ int FltkPreviewButton::handle (int event)
/** \bug Some parts are missing. */
switch (event) {
- case PUSH:
+ case FL_PUSH:
window->showWindow ();
- return Button::handle (event);
+ return Fl_Button::handle (event);
- case DRAG:
+ case FL_DRAG:
if (window->visible ()) {
- window->scrollTo (event_x_root (), event_y_root ());
+ window->scrollTo (Fl::event_x_root (), Fl::event_y_root ());
return 1;
}
- return Button::handle (event);
+ return Fl_Button::handle (event);
- case RELEASE:
+ case FL_RELEASE:
window->hideWindow ();
- return Button::handle (event);
+ return Fl_Button::handle (event);
default:
- return Button::handle (event);
+ return Fl_Button::handle (event);
}
}
diff --git a/dw/fltkpreview.hh b/dw/fltkpreview.hh
index 13db2811..2382b861 100644
--- a/dw/fltkpreview.hh
+++ b/dw/fltkpreview.hh
@@ -1,8 +1,8 @@
#ifndef __FlTKPREVIEW_HH__
#define __FlTKPREVIEW_HH__
-#include <fltk/Button.h>
-#include <fltk/MenuWindow.h>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Menu_Window.H>
#include "fltkviewbase.hh"
namespace dw {
@@ -42,15 +42,20 @@ public:
core::style::Color *color,
core::style::Color::Shading shading,
int x, int y, const char *text, int len);
+ void drawSimpleWrappedText (core::style::Font *font,
+ core::style::Color *color,
+ core::style::Color::Shading shading,
+ int x, int y, int w, int h,
+ const char *text);
void drawImage (core::Imgbuf *imgbuf, int xRoot, int yRoot,
int x, int y, int width, int height);
bool usesFltkWidgets ();
- void drawFltkWidget (::fltk::Widget *widget, core::Rectangle *area);
+ void drawFltkWidget (Fl_Widget *widget, core::Rectangle *area);
};
-class FltkPreviewWindow: public ::fltk::MenuWindow
+class FltkPreviewWindow: public Fl_Menu_Window
{
private:
enum { BORDER_WIDTH = 2 };
@@ -71,7 +76,7 @@ public:
};
-class FltkPreviewButton: public ::fltk::Button
+class FltkPreviewButton: public Fl_Button
{
private:
FltkPreviewWindow *window;
diff --git a/dw/fltkui.cc b/dw/fltkui.cc
index ff80e14c..c0c8ff42 100644
--- a/dw/fltkui.cc
+++ b/dw/fltkui.cc
@@ -25,21 +25,57 @@
#include "../lout/msg.h"
#include "../lout/misc.hh"
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Text_Editor.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Round_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Tree.H>
+
#include <stdio.h>
-#include <fltk/Widget.h>
-#include <fltk/Group.h>
-#include <fltk/Input.h>
-#include <fltk/TextEditor.h>
-#include <fltk/RadioButton.h>
-#include <fltk/CheckButton.h>
-#include <fltk/Choice.h>
-#include <fltk/Browser.h>
-#include <fltk/Font.h>
-#include <fltk/draw.h>
-#include <fltk/Symbol.h>
-#include <fltk/Item.h>
-#include <fltk/ItemGroup.h>
-#include <fltk/events.h>
+
+//----------------------------------------------------------------------------
+/*
+ * Local sub classes
+ */
+
+/*
+ * Used to enable CTRL+{a,e,d,k} in form inputs (for start,end,del,cut)
+ */
+class CustInput2 : public Fl_Input {
+public:
+ CustInput2 (int x, int y, int w, int h, const char* l=0) :
+ Fl_Input(x,y,w,h,l) {};
+ int handle(int e);
+};
+
+int CustInput2::handle(int e)
+{
+ int k = Fl::event_key();
+
+ _MSG("CustInput2::handle event=%d\n", e);
+
+ // We're only interested in some flags
+ unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT);
+
+ if (e == FL_KEYBOARD && modifier == FL_CTRL) {
+ if (k == 'a' || k == 'e') {
+ position(k == 'a' ? 0 : size());
+ return 1;
+ } else if (k == 'k') {
+ cut(position(), size());
+ return 1;
+ } else if (k == 'd') {
+ cut(position(), position()+1);
+ return 1;
+ }
+ }
+ return Fl_Input::handle(e);
+}
+
+//----------------------------------------------------------------------------
namespace dw {
namespace fltk {
@@ -139,14 +175,12 @@ void FltkResource::setStyle (core::style::Style *style)
setWidgetStyle (widget, style);
}
-void FltkResource::setWidgetStyle (::fltk::Widget *widget,
+void FltkResource::setWidgetStyle (Fl_Widget *widget,
core::style::Style *style)
{
FltkFont *font = (FltkFont*)style->font;
widget->labelsize (font->size);
widget->labelfont (font->font);
- widget->textsize (font->size);
- widget->textfont (font->font);
FltkColor *bg = (FltkColor*)style->backgroundColor;
if (bg) {
@@ -155,21 +189,13 @@ void FltkResource::setWidgetStyle (::fltk::Widget *widget,
if (style->color) {
int style_fg = ((FltkColor*)style->color)->colors
[FltkColor::SHADING_NORMAL];
- ::fltk::Color fg = ::fltk::contrast(style_fg, normal_bg);
+ Fl_Color fg = fl_contrast(style_fg, normal_bg);
widget->labelcolor(fg);
- widget->textcolor(fg);
widget->selection_color(fg);
}
widget->color(normal_bg);
- widget->buttoncolor(normal_bg);
- widget->selection_textcolor(normal_bg);
- if (widget->type() != ::fltk::Widget::RADIO &&
- widget->type() != ::fltk::Widget::TOGGLE) {
- /* it looks awful to highlight the buttons */
- widget->highlight_color(bg->colors[FltkColor::SHADING_LIGHT]);
- }
}
}
@@ -250,19 +276,17 @@ FltkLabelButtonResource::FltkLabelButtonResource (FltkPlatform *platform,
FltkLabelButtonResource::~FltkLabelButtonResource ()
{
- delete label;
+ free((char *)label);
}
-::fltk::Widget *FltkLabelButtonResource::createNewWidget (core::Allocation
- *allocation)
+Fl_Widget *FltkLabelButtonResource::createNewWidget (core::Allocation
+ *allocation)
{
- ::fltk::Button *button =
- new ::fltk::Button (allocation->x, allocation->y, allocation->width,
- allocation->ascent + allocation->descent,
- label);
- button->set_flag (::fltk::RAW_LABEL);
+ Fl_Button *button =
+ new Fl_Button (allocation->x, allocation->y, allocation->width,
+ allocation->ascent + allocation->descent, label);
button->callback (widgetCallback, this);
- button->when (::fltk::WHEN_RELEASE);
+ button->when (FL_WHEN_RELEASE);
return button;
}
@@ -270,9 +294,9 @@ void FltkLabelButtonResource::sizeRequest (core::Requisition *requisition)
{
if (style) {
FltkFont *font = (FltkFont*)style->font;
- ::fltk::setfont(font->font,font->size);
+ fl_font(font->font,font->size);
requisition->width =
- (int)::fltk::getwidth (label, strlen (label))
+ (int)fl_width (label, strlen (label))
+ 2 * RELIEF_X_THICKNESS;
requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
requisition->descent = font->descent + RELIEF_Y_THICKNESS;
@@ -290,35 +314,32 @@ void FltkLabelButtonResource::sizeRequest (core::Requisition *requisition)
*/
static core::ButtonState getDwButtonState ()
{
- int s1 = ::fltk::event_state ();
+ int s1 = Fl::event_state ();
int s2 = (core::ButtonState)0;
- if (s1 & ::fltk::SHIFT) s2 |= core::SHIFT_MASK;
- if (s1 & ::fltk::CTRL) s2 |= core::CONTROL_MASK;
- if (s1 & ::fltk::ALT) s2 |= core::META_MASK;
- if (s1 & ::fltk::BUTTON1) s2 |= core::BUTTON1_MASK;
- if (s1 & ::fltk::BUTTON2) s2 |= core::BUTTON2_MASK;
- if (s1 & ::fltk::BUTTON3) s2 |= core::BUTTON3_MASK;
+ if (s1 & FL_SHIFT) s2 |= core::SHIFT_MASK;
+ if (s1 & FL_CTRL) s2 |= core::CONTROL_MASK;
+ if (s1 & FL_ALT) s2 |= core::META_MASK;
+ if (s1 & FL_BUTTON1) s2 |= core::BUTTON1_MASK;
+ if (s1 & FL_BUTTON2) s2 |= core::BUTTON2_MASK;
+ if (s1 & FL_BUTTON3) s2 |= core::BUTTON3_MASK;
return (core::ButtonState)s2;
}
static void setButtonEvent(dw::core::EventButton *event)
{
- event->xCanvas = ::fltk::event_x();
- event->yCanvas = ::fltk::event_y();
+ event->xCanvas = Fl::event_x();
+ event->yCanvas = Fl::event_y();
event->state = getDwButtonState();
- event->button = ::fltk::event_button();
- event->numPressed = ::fltk::event_clicks() + 1;
+ event->button = Fl::event_button();
+ event->numPressed = Fl::event_clicks() + 1;
}
-void FltkLabelButtonResource::widgetCallback (::fltk::Widget *widget,
+void FltkLabelButtonResource::widgetCallback (Fl_Widget *widget,
void *data)
{
- if ((widget->when () & ::fltk::WHEN_RELEASE) &&
- ((::fltk::event_key() == ::fltk::ReturnKey) ||
- (::fltk::event_button() == ::fltk::LeftButton ||
- ::fltk::event_button() == ::fltk::MiddleButton))) {
+ if (!Fl::event_button3()) {
FltkLabelButtonResource *lbr = (FltkLabelButtonResource*) data;
dw::core::EventButton event;
setButtonEvent(&event);
@@ -334,7 +355,7 @@ const char *FltkLabelButtonResource::getLabel ()
void FltkLabelButtonResource::setLabel (const char *label)
{
- delete this->label;
+ free((char *)this->label);
this->label = strdup (label);
widget->label (this->label);
@@ -358,22 +379,17 @@ FltkComplexButtonResource::~FltkComplexButtonResource ()
{
}
-void FltkComplexButtonResource::widgetCallback (::fltk::Widget *widget,
+void FltkComplexButtonResource::widgetCallback (Fl_Widget *widget,
void *data)
{
FltkComplexButtonResource *res = (FltkComplexButtonResource*)data;
- if (widget->when() == ::fltk::WHEN_RELEASE &&
- ((::fltk::event_key() == ::fltk::ReturnKey) ||
- (::fltk::event_button() == ::fltk::LeftButton ||
- ::fltk::event_button() == ::fltk::MiddleButton))) {
- res->click_x = ::fltk::event_x();
- res->click_y = ::fltk::event_y();
+ if (!Fl::event_button3()) {
+ res->click_x = Fl::event_x();
+ res->click_y = Fl::event_y();
dw::core::EventButton event;
setButtonEvent(&event);
res->emitClicked(&event);
- } else {
- ((FltkViewBase*)res->flatView)->handle(::fltk::event());
}
}
@@ -423,16 +439,16 @@ int FltkComplexButtonResource::reliefYThickness ()
}
-::fltk::Widget *FltkComplexButtonResource::createNewWidget (core::Allocation
+Fl_Widget *FltkComplexButtonResource::createNewWidget (core::Allocation
*allocation)
{
ComplexButton *button =
new ComplexButton (allocation->x, allocation->y, allocation->width,
allocation->ascent + allocation->descent);
button->callback (widgetCallback, this);
- button->when (::fltk::WHEN_RELEASE);
+ button->when (FL_WHEN_RELEASE);
if (!relief)
- button->box(::fltk::FLAT_BOX);
+ button->box(FL_FLAT_BOX);
flatView = new FltkFlatView (allocation->x + reliefXThickness (),
allocation->y + reliefYThickness (),
@@ -455,6 +471,7 @@ FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int maxLength,
this->maxLength = maxLength;
this->password = password;
this->label = label ? strdup(label) : NULL;
+ this->label_w = 0;
initText = NULL;
editable = false;
@@ -465,25 +482,25 @@ FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int maxLength,
FltkEntryResource::~FltkEntryResource ()
{
if (initText)
- delete initText;
+ free((char *)initText);
if (label)
- delete label;
+ free(label);
}
-::fltk::Widget *FltkEntryResource::createNewWidget (core::Allocation
+Fl_Widget *FltkEntryResource::createNewWidget (core::Allocation
*allocation)
{
- ::fltk::Input *input =
- new ::fltk::Input (allocation->x, allocation->y, allocation->width,
- allocation->ascent + allocation->descent);
+ Fl_Input *input =
+ new CustInput2(allocation->x, allocation->y, allocation->width,
+ allocation->ascent + allocation->descent);
if (password)
- input->type(::fltk::Input::SECRET);
+ input->type(FL_SECRET_INPUT);
input->callback (widgetCallback, this);
- input->when (::fltk::WHEN_ENTER_KEY_ALWAYS);
+ input->when (FL_WHEN_ENTER_KEY_ALWAYS);
if (label) {
input->label(label);
- input->set_flag(::fltk::ALIGN_INSIDE_LEFT);
+ input->align(FL_ALIGN_LEFT);
}
if (initText)
input->value (initText);
@@ -491,6 +508,26 @@ FltkEntryResource::~FltkEntryResource ()
return input;
}
+void FltkEntryResource::setWidgetStyle (Fl_Widget *widget,
+ core::style::Style *style)
+{
+ Fl_Input *in = (Fl_Input *)widget;
+
+ FltkResource::setWidgetStyle(widget, style);
+
+ in->textcolor(widget->labelcolor());
+ in->cursor_color(in->textcolor());
+ in->textsize(in->labelsize());
+ in->textfont(in->labelfont());
+
+ if (label) {
+ int h;
+ label_w = 0;
+ widget->measure_label(label_w, h);
+ label_w += RELIEF_X_THICKNESS;
+ }
+}
+
void FltkEntryResource::setDisplayed(bool displayed)
{
FltkResource::setDisplayed(displayed);
@@ -501,11 +538,13 @@ void FltkEntryResource::sizeRequest (core::Requisition *requisition)
{
if (displayed() && style) {
FltkFont *font = (FltkFont*)style->font;
- ::fltk::setfont(font->font,font->size);
+ fl_font(font->font,font->size);
+ /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
+ * Reported to FLTK as STR #2688 */
requisition->width =
- (int)::fltk::getwidth ("n", 1)
+ (int)fl_width ("n")
* (maxLength == UNLIMITED_MAX_LENGTH ? 10 : maxLength)
- + 2 * RELIEF_X_THICKNESS;
+ + label_w + (2 * RELIEF_X_THICKNESS);
requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
requisition->descent = font->descent + RELIEF_Y_THICKNESS;
} else {
@@ -515,33 +554,38 @@ void FltkEntryResource::sizeRequest (core::Requisition *requisition)
}
}
-void FltkEntryResource::widgetCallback (::fltk::Widget *widget,
- void *data)
+void FltkEntryResource::sizeAllocate (core::Allocation *allocation)
{
- /* The (::fltk::event_key() == ::fltk::ReturnKey) test
- * is necessary because WHEN_ENTER_KEY also includes
- * other events we're not interested in. For instance pressing
- * The Back or Forward, buttons, or the first click on a rendered
- * page. BUG: this must be investigated and reported to FLTK2 team
- */
- _MSG("when = %d\n", widget->when ());
- if ((widget->when () & ::fltk::WHEN_ENTER_KEY_ALWAYS) &&
- (::fltk::event_key() == ::fltk::ReturnKey))
- ((FltkEntryResource*)data)->emitActivate ();
+ if (!label) {
+ FltkResource::sizeAllocate(allocation);
+ } else {
+ this->allocation = *allocation;
+
+ /* push the Fl_Input over to the right of the label */
+ core::Allocation a = this->allocation;
+ a.x += this->label_w;
+ a.width -= this->label_w;
+ view->allocateFltkWidget (widget, &a);
+ }
+}
+
+void FltkEntryResource::widgetCallback (Fl_Widget *widget, void *data)
+{
+ ((FltkEntryResource*)data)->emitActivate ();
}
const char *FltkEntryResource::getText ()
{
- return ((::fltk::Input*)widget)->value ();
+ return ((Fl_Input*)widget)->value ();
}
void FltkEntryResource::setText (const char *text)
{
if (initText)
- delete initText;
+ free((char *)initText);
initText = strdup (text);
- ((::fltk::Input*)widget)->value (initText);
+ ((Fl_Input*)widget)->value (initText);
}
bool FltkEntryResource::isEditable ()
@@ -560,7 +604,8 @@ FltkMultiLineTextResource::FltkMultiLineTextResource (FltkPlatform *platform,
int cols, int rows):
FltkSpecificResource <dw::core::ui::MultiLineTextResource> (platform)
{
- buffer = new ::fltk::TextBuffer;
+ buffer = new Fl_Text_Buffer;
+ text_copy = NULL;
editable = false;
numCols = cols;
@@ -582,29 +627,45 @@ FltkMultiLineTextResource::FltkMultiLineTextResource (FltkPlatform *platform,
FltkMultiLineTextResource::~FltkMultiLineTextResource ()
{
/* Free memory avoiding a double-free of text buffers */
- ((::fltk::TextEditor *) widget)->buffer (0);
+ ((Fl_Text_Editor *) widget)->buffer (0);
delete buffer;
+ if (text_copy)
+ free(text_copy);
}
-::fltk::Widget *FltkMultiLineTextResource::createNewWidget (core::Allocation
+Fl_Widget *FltkMultiLineTextResource::createNewWidget (core::Allocation
*allocation)
{
- ::fltk::TextEditor *text =
- new ::fltk::TextEditor (allocation->x, allocation->y,
- allocation->width,
- allocation->ascent + allocation->descent);
+ Fl_Text_Editor *text =
+ new Fl_Text_Editor (allocation->x, allocation->y, allocation->width,
+ allocation->ascent + allocation->descent);
+ text->wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 0);
text->buffer (buffer);
return text;
}
+void FltkMultiLineTextResource::setWidgetStyle (Fl_Widget *widget,
+ core::style::Style *style)
+{
+ Fl_Text_Editor *ed = (Fl_Text_Editor *)widget;
+
+ FltkResource::setWidgetStyle(widget, style);
+
+ ed->textcolor(widget->labelcolor());
+ ed->cursor_color(ed->textcolor());
+ ed->textsize(ed->labelsize());
+ ed->textfont(ed->labelfont());
+}
+
void FltkMultiLineTextResource::sizeRequest (core::Requisition *requisition)
{
if (style) {
FltkFont *font = (FltkFont*)style->font;
- ::fltk::setfont(font->font,font->size);
+ fl_font(font->font,font->size);
+ /* WORKAROUND: fl_width(uint_t) is not working on non-xft X.
+ * Reported to FLTK as STR #2688 */
requisition->width =
- (int)::fltk::getwidth ("n", 1) * numCols +
- 2 * RELIEF_X_THICKNESS;
+ (int)fl_width ("n") * numCols + 2 * RELIEF_X_THICKNESS;
requisition->ascent =
RELIEF_Y_THICKNESS + font->ascent +
(font->ascent + font->descent) * (numRows - 1);
@@ -620,7 +681,13 @@ void FltkMultiLineTextResource::sizeRequest (core::Requisition *requisition)
const char *FltkMultiLineTextResource::getText ()
{
- return buffer->text ();
+ /* FLTK-1.3 insists upon returning a new copy of the buffer text, so
+ * we have to keep track of it.
+ */
+ if (text_copy)
+ free(text_copy);
+ text_copy = buffer->text();
+ return text_copy;
}
void FltkMultiLineTextResource::setText (const char *text)
@@ -656,14 +723,23 @@ FltkToggleButtonResource<I>::~FltkToggleButtonResource ()
template <class I>
-::fltk::Widget *FltkToggleButtonResource<I>::createNewWidget (core::Allocation
+Fl_Widget *FltkToggleButtonResource<I>::createNewWidget (core::Allocation
*allocation)
{
- ::fltk::Button *button = createNewButton (allocation);
+ Fl_Button *button = createNewButton (allocation);
button->value (initActivated);
return button;
}
+template <class I>
+void FltkToggleButtonResource<I>::setWidgetStyle (Fl_Widget *widget,
+ core::style::Style *style)
+{
+ FltkResource::setWidgetStyle(widget, style);
+
+ widget->selection_color(FL_BLACK);
+}
+
template <class I>
void FltkToggleButtonResource<I>::sizeRequest (core::Requisition *requisition)
@@ -672,7 +748,7 @@ void FltkToggleButtonResource<I>::sizeRequest (core::Requisition *requisition)
(this->FltkResource::style ? this->FltkResource::style->font : NULL);
if (font) {
- ::fltk::setfont(font->font, font->size);
+ fl_font(font->font, font->size);
requisition->width = font->ascent + font->descent + 2*RELIEF_X_THICKNESS;
requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
requisition->descent = font->descent + RELIEF_Y_THICKNESS;
@@ -687,7 +763,7 @@ void FltkToggleButtonResource<I>::sizeRequest (core::Requisition *requisition)
template <class I>
bool FltkToggleButtonResource<I>::FltkToggleButtonResource::isActivated ()
{
- return ((::fltk::Button*)this->widget)->value ();
+ return ((Fl_Button*)this->widget)->value ();
}
@@ -695,7 +771,7 @@ template <class I>
void FltkToggleButtonResource<I>::setActivated (bool activated)
{
initActivated = activated;
- ((::fltk::Button*)this->widget)->value (initActivated);
+ ((Fl_Button*)this->widget)->value (initActivated);
}
// ----------------------------------------------------------------------
@@ -714,13 +790,12 @@ FltkCheckButtonResource::~FltkCheckButtonResource ()
}
-::fltk::Button *FltkCheckButtonResource::createNewButton (core::Allocation
+Fl_Button *FltkCheckButtonResource::createNewButton (core::Allocation
*allocation)
{
- ::fltk::CheckButton *cb =
- new ::fltk::CheckButton (allocation->x, allocation->y, allocation->width,
- allocation->ascent + allocation->descent);
- cb->set_flag (::fltk::RAW_LABEL);
+ Fl_Check_Button *cb =
+ new Fl_Check_Button (allocation->x, allocation->y, allocation->width,
+ allocation->ascent + allocation->descent);
return cb;
}
@@ -798,10 +873,10 @@ dw::core::ui::RadioButtonResource::GroupIterator
return group->groupIterator ();
}
-void FltkRadioButtonResource::widgetCallback (::fltk::Widget *widget,
+void FltkRadioButtonResource::widgetCallback (Fl_Widget *widget,
void *data)
{
- if (widget->when () & ::fltk::WHEN_CHANGED)
+ if (widget->when () & FL_WHEN_CHANGED)
((FltkRadioButtonResource*)data)->buttonClicked ();
}
@@ -814,11 +889,11 @@ void FltkRadioButtonResource::buttonClicked ()
}
}
-::fltk::Button *FltkRadioButtonResource::createNewButton (core::Allocation
- *allocation)
+Fl_Button *FltkRadioButtonResource::createNewButton (core::Allocation
+ *allocation)
{
/*
- * Groups of fltk::RadioButton must be added to one fltk::Group, which is
+ * Groups of Fl_Radio_Button must be added to one Fl_Group, which is
* not possible in this context. For this, we do the grouping ourself,
* based on FltkRadioButtonResource::Group.
*
@@ -829,297 +904,191 @@ void FltkRadioButtonResource::buttonClicked ()
* (instead of creating a check button, and changing the style).
*/
- ::fltk::Button *button =
- new ::fltk::RadioButton (allocation->x, allocation->y,
- allocation->width,
- allocation->ascent + allocation->descent);
- button->set_flag (::fltk::RAW_LABEL);
- button->when (::fltk::WHEN_CHANGED);
+ Fl_Button *button =
+ new Fl_Round_Button (allocation->x, allocation->y, allocation->width,
+ allocation->ascent + allocation->descent);
+ button->when (FL_WHEN_CHANGED);
button->callback (widgetCallback, this);
- button->type (::fltk::Button::TOGGLE);
+ button->type (FL_TOGGLE_BUTTON);
return button;
}
// ----------------------------------------------------------------------
-template <class I> FltkSelectionResource<I>::Item::Item (Type type,
- const char *name,
- bool enabled,
- bool selected)
+template <class I> dw::core::Iterator *
+FltkSelectionResource<I>::iterator (dw::core::Content::Type mask, bool atEnd)
{
- this->type = type;
- this->name = name ? strdup (name) : NULL;
- this->enabled = enabled;
- initSelected = selected;
+ /** \bug Implementation. */
+ return new core::EmptyIterator (this->getEmbed (), mask, atEnd);
}
-template <class I> FltkSelectionResource<I>::Item::~Item ()
-{
- if (name)
- delete name;
-}
+// ----------------------------------------------------------------------
-template <class I>
-::fltk::Item *FltkSelectionResource<I>::Item::createNewWidget (int index)
+FltkOptionMenuResource::FltkOptionMenuResource (FltkPlatform *platform):
+ FltkSelectionResource <dw::core::ui::OptionMenuResource> (platform)
{
- ::fltk::Item *item = new ::fltk::Item (name);
- item->set_flag (::fltk::RAW_LABEL);
- item->user_data ((void *) index);
- return item;
-}
+ /* Fl_Menu_ does not like multiple menu items with the same label, and
+ * insert() treats some characters specially unless escaped, so let's
+ * do our own menu handling.
+ */
+ itemsAllocated = 0x10;
+ menu = new Fl_Menu_Item[itemsAllocated];
+ memset(menu, 0, itemsAllocated * sizeof(Fl_Menu_Item));
+ itemsUsed = 1; // menu[0].text == NULL, which is an end-of-menu marker.
+ visibleItems = 0;
-template <class I>
-::fltk::ItemGroup *
-FltkSelectionResource<I>::Item::createNewGroupWidget ()
-{
- ::fltk::ItemGroup *itemGroup = new ::fltk::ItemGroup (name);
- itemGroup->set_flag (::fltk::RAW_LABEL);
- itemGroup->user_data ((void *) -1L);
- return itemGroup;
+ init (platform);
}
-
-template <class I>
-FltkSelectionResource<I>::WidgetStack::WidgetStack (::fltk::Menu *widget)
+FltkOptionMenuResource::~FltkOptionMenuResource ()
{
- this->widget = widget;
- this->stack = new Stack <TypedPointer < ::fltk::Menu> > (true);
+ for (int i = 0; i < itemsUsed; i++) {
+ if (menu[i].text)
+ free((char *) menu[i].text);
+ }
+ delete[] menu;
}
-template <class I> FltkSelectionResource<I>::WidgetStack::~WidgetStack ()
+void FltkOptionMenuResource::setWidgetStyle (Fl_Widget *widget,
+ core::style::Style *style)
{
- delete stack;
-}
+ Fl_Choice *ch = (Fl_Choice *)widget;
+ FltkResource::setWidgetStyle(widget, style);
-template <class I>
-FltkSelectionResource<I>::FltkSelectionResource (FltkPlatform *platform):
- FltkSpecificResource<I> (platform)
-{
- widgetStacks = new List <WidgetStack> (true);
- allItems = new List <Item> (true);
- items = new Vector <Item> (16, false);
+ ch->textcolor(widget->labelcolor());
+ ch->textfont(ch->labelfont());
+ ch->textsize(ch->labelsize());
}
-template <class I> FltkSelectionResource<I>::~FltkSelectionResource ()
+Fl_Widget *FltkOptionMenuResource::createNewWidget (core::Allocation
+ *allocation)
{
- delete widgetStacks;
- delete allItems;
- delete items;
+ Fl_Choice *choice =
+ new Fl_Choice (allocation->x, allocation->y,
+ allocation->width,
+ allocation->ascent + allocation->descent);
+ choice->menu(menu);
+ return choice;
}
-template <class I> dw::core::Iterator *
-FltkSelectionResource<I>::iterator (dw::core::Content::Type mask, bool atEnd)
+void FltkOptionMenuResource::widgetCallback (Fl_Widget *widget,
+ void *data)
{
- /** \bug Implementation. */
- return new core::EmptyIterator (this->getEmbed (), mask, atEnd);
}
-template <class I> ::fltk::Widget *
-FltkSelectionResource<I>::createNewWidget (core::Allocation *allocation)
+int FltkOptionMenuResource::getMaxItemWidth()
{
- /** \todo Attributes (enabled, selected). */
-
- ::fltk::Menu *menu = createNewMenu (allocation);
- WidgetStack *widgetStack = new WidgetStack (menu);
- widgetStack->stack->push (new TypedPointer < ::fltk::Menu> (menu));
- widgetStacks->append (widgetStack);
-
+ int i, max = 0;
- ::fltk::Menu *itemGroup;
- ::fltk::Item *itemWidget;
+ for (i = 0; i < itemsUsed; i++) {
+ int width = 0;
+ const char *str = menu[i].text;
- ::fltk::Group *currGroup = widgetStack->stack->getTop()->getTypedValue();
-
- int index = 0;
- for (Iterator <Item> it = allItems->iterator (); it.hasNext (); ) {
- Item *item = it.getNext ();
- switch (item->type) {
- case Item::ITEM:
- itemWidget = item->createNewWidget (index++);
- currGroup->add (itemWidget);
- break;
-
- case Item::START:
- itemGroup = item->createNewGroupWidget ();
- currGroup->add (itemGroup);
- widgetStack->stack->push (new TypedPointer < ::fltk::Menu> (menu));
- currGroup = itemGroup;
- break;
-
- case Item::END:
- widgetStack->stack->pop ();
- currGroup = widgetStack->stack->getTop()->getTypedValue();
- break;
+ if (str) {
+ width = fl_width(str);
+ if (width > max)
+ max = width;
}
}
-
- return menu;
+ return max;
}
-template <class I>
-typename FltkSelectionResource<I>::Item *
-FltkSelectionResource<I>::createNewItem (typename Item::Type type,
- const char *name,
- bool enabled,
- bool selected) {
- return new Item(type,name,enabled,selected);
-}
-
-template <class I> void FltkSelectionResource<I>::addItem (const char *str,
- bool enabled,
- bool selected)
-{
- int index = items->size ();
- Item *item = createNewItem (Item::ITEM, str, enabled, selected);
- items->put (item);
- allItems->append (item);
-
- for (Iterator <WidgetStack> it = widgetStacks->iterator ();
- it.hasNext(); ) {
- WidgetStack *widgetStack = it.getNext ();
- ::fltk::Item *itemWidget = item->createNewWidget (index);
- widgetStack->stack->getTop()->getTypedValue()->add (itemWidget);
-
- if (!enabled)
- itemWidget->deactivate ();
-
- if (selected) {
- itemWidget->set_selected();
- if (setSelectedItems ()) {
- // Handle multiple item selection.
- int *pos = new int[widgetStack->stack->size ()];
- int i;
- Iterator <TypedPointer < ::fltk::Menu> > it;
- for (it = widgetStack->stack->iterator (),
- i = widgetStack->stack->size () - 1;
- it.hasNext ();
- i--) {
- TypedPointer < ::fltk::Menu> * p = it.getNext ();
- pos[i] = p->getTypedValue()->children () - 1;
- }
- widgetStack->widget->set_item (pos, widgetStack->stack->size ());
- delete [] pos;
- }
- }
+void FltkOptionMenuResource::sizeRequest (core::Requisition *requisition)
+{
+ if (style) {
+ FltkFont *font = (FltkFont*)style->font;
+ fl_font(font->font, font->size);
+ int maxItemWidth = getMaxItemWidth ();
+ requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
+ requisition->descent = font->descent + RELIEF_Y_THICKNESS;
+ requisition->width = maxItemWidth
+ + (requisition->ascent + requisition->descent)
+ + 2 * RELIEF_X_THICKNESS;
+ } else {
+ requisition->width = 1;
+ requisition->ascent = 1;
+ requisition->descent = 0;
}
}
-template <class I> void FltkSelectionResource<I>::pushGroup (const char *name,
- bool enabled)
+void FltkOptionMenuResource::enlargeMenu ()
{
- Item *item = createNewItem (Item::START, name, enabled);
- allItems->append (item);
+ Fl_Choice *ch = (Fl_Choice *)widget;
+ int selected = ch->value();
+ Fl_Menu_Item *newMenu;
- for (Iterator <WidgetStack> it = widgetStacks->iterator ();
- it.hasNext(); ) {
- WidgetStack *widgetStack = it.getNext ();
- ::fltk::ItemGroup *group = item->createNewGroupWidget ();
- widgetStack->stack->getTop()->getTypedValue()->add (group);
- widgetStack->stack->push (new TypedPointer < ::fltk::Menu> (group));
- if (!enabled)
- group->deactivate ();
- }
+ itemsAllocated += 0x10;
+ newMenu = new Fl_Menu_Item[itemsAllocated];
+ memcpy(newMenu, menu, itemsUsed * sizeof(Fl_Menu_Item));
+ memset(newMenu + itemsUsed, 0, 0x10 * sizeof(Fl_Menu_Item));
+ delete[] menu;
+ menu = newMenu;
+ ch->menu(menu);
+ ch->value(selected);
}
-template <class I> void FltkSelectionResource<I>::popGroup ()
+Fl_Menu_Item *FltkOptionMenuResource::newItem()
{
- Item *item = createNewItem (Item::END);
- allItems->append (item);
+ Fl_Menu_Item *item;
- for (Iterator <WidgetStack> it = widgetStacks->iterator ();
- it.hasNext(); ) {
- WidgetStack *widgetStack = it.getNext ();
- widgetStack->stack->pop ();
- }
-}
+ if (itemsUsed == itemsAllocated)
+ enlargeMenu();
-template <class I> int FltkSelectionResource<I>::getNumberOfItems ()
-{
- return items->size ();
-}
+ item = menu + itemsUsed - 1;
+ itemsUsed++;
-template <class I> const char *FltkSelectionResource<I>::getItem (int index)
-{
- return items->get(index)->name;
+ return item;
}
-template <class I> int FltkSelectionResource<I>::getMaxStringWidth ()
+void FltkOptionMenuResource::addItem (const char *str,
+ bool enabled, bool selected)
{
- int width = 0, numberOfItems = getNumberOfItems ();
- for (int i = 0; i < numberOfItems; i++) {
- int len = (int)::fltk::getwidth (getItem(i));
- if (len > width) width = len;
- }
- return width;
-}
+ Fl_Menu_Item *item = newItem();
-// ----------------------------------------------------------------------
+ item->text = strdup(str);
+ item->argument(visibleItems++);
-FltkOptionMenuResource::FltkOptionMenuResource (FltkPlatform *platform):
- FltkSelectionResource <dw::core::ui::OptionMenuResource> (platform),
- selection(-1)
-{
- init (platform);
+ if (enabled == false)
+ item->flags = FL_MENU_INACTIVE;
+
+ if (selected)
+ ((Fl_Choice *)widget)->value(item);
+
+ queueResize (true);
}
-FltkOptionMenuResource::~FltkOptionMenuResource ()
+void FltkOptionMenuResource::pushGroup (const char *name, bool enabled)
{
-}
+ Fl_Menu_Item *item = newItem();
+ item->text = strdup(name);
+ item->argument(visibleItems++);
-::fltk::Menu *FltkOptionMenuResource::createNewMenu (core::Allocation
- *allocation)
-{
- ::fltk::Menu *menu =
- new ::fltk::Choice (allocation->x, allocation->y,
- allocation->width,
- allocation->ascent + allocation->descent);
- menu->set_flag (::fltk::RAW_LABEL);
- menu->callback(widgetCallback,this);
- return menu;
-}
+ if (enabled == false)
+ item->flags = FL_MENU_INACTIVE;
-void FltkOptionMenuResource::widgetCallback (::fltk::Widget *widget,
- void *data)
-{
- ((FltkOptionMenuResource *) data)->selection =
- (long) (((::fltk::Menu *) widget)->item()->user_data());
-}
+ item->flags |= FL_SUBMENU;
-void FltkOptionMenuResource::sizeRequest (core::Requisition *requisition)
-{
- if (style) {
- FltkFont *font = (FltkFont*)style->font;
- ::fltk::setfont(font->font,font->size);
- int maxStringWidth = getMaxStringWidth ();
- requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
- requisition->descent = font->descent + RELIEF_Y_THICKNESS;
- requisition->width = maxStringWidth
- + (requisition->ascent + requisition->descent) * 4 / 5
- + 2 * RELIEF_X_THICKNESS;
- } else {
- requisition->width = 1;
- requisition->ascent = 1;
- requisition->descent = 0;
- }
+ queueResize (true);
}
-void FltkOptionMenuResource::addItem (const char *str,
- bool enabled, bool selected)
+void FltkOptionMenuResource::popGroup ()
{
- FltkSelectionResource<dw::core::ui::OptionMenuResource>::addItem
- (str,enabled,selected);
- if (selected)
- selection = (items->size ()) - 1;
-
+ /* Item with NULL text field closes the submenu */
+ newItem();
queueResize (true);
}
bool FltkOptionMenuResource::isSelected (int index)
{
- return index == selection;
+ return index == (long) ((Fl_Choice *)widget)->mvalue()->user_data();
+}
+
+int FltkOptionMenuResource::getNumberOfItems()
+{
+ return ((Fl_Choice*)widget)->size();
}
// ----------------------------------------------------------------------
@@ -1140,70 +1109,133 @@ FltkListResource::~FltkListResource ()
}
-::fltk::Menu *FltkListResource::createNewMenu (core::Allocation *allocation)
+Fl_Widget *FltkListResource::createNewWidget (core::Allocation *allocation)
{
- ::fltk::Menu *menu =
- new ::fltk::Browser (allocation->x, allocation->y, allocation->width,
+ Fl_Tree *tree =
+ new Fl_Tree (allocation->x, allocation->y, allocation->width,
allocation->ascent + allocation->descent);
- if (mode == SELECTION_MULTIPLE)
- menu->type(::fltk::Browser::MULTI);
- menu->set_flag (::fltk::RAW_LABEL);
- menu->callback(widgetCallback,this);
- menu->when(::fltk::WHEN_CHANGED);
- return menu;
+
+ tree->selectmode((mode == SELECTION_MULTIPLE) ? FL_TREE_SELECT_MULTI
+ : FL_TREE_SELECT_SINGLE);
+ tree->showroot(0);
+ tree->connectorstyle(FL_TREE_CONNECTOR_NONE);
+ tree->marginleft(-14);
+ tree->callback(widgetCallback,this);
+ tree->when(FL_WHEN_CHANGED);
+
+ currParent = tree->root();
+ return tree;
}
-void FltkListResource::widgetCallback (::fltk::Widget *widget, void *data)
+void FltkListResource::setWidgetStyle (Fl_Widget *widget,
+ core::style::Style *style)
{
- ::fltk::Widget *fltkItem = ((::fltk::Menu *) widget)->item ();
+ Fl_Tree *t = (Fl_Tree *)widget;
+
+ FltkResource::setWidgetStyle(widget, style);
+
+ t->item_labelfont(widget->labelfont());
+ t->item_labelsize(widget->labelsize());
+ t->item_labelfgcolor(widget->labelcolor());
+ t->item_labelbgcolor(widget->color());
+}
+
+void FltkListResource::widgetCallback (Fl_Widget *widget, void *data)
+{
+ Fl_Tree_Item *fltkItem = ((Fl_Tree *) widget)->callback_item ();
int index = -1;
if (fltkItem)
index = (long) (fltkItem->user_data ());
if (index > -1) {
- /* A MultiBrowser will trigger a callback for each item that is
- * selected and each item that is deselected, but a "plain"
- * Browser will only trigger the callback for the newly selected item
- * (for which selected() is false, incidentally).
- */
FltkListResource *res = (FltkListResource *) data;
- if (res->mode == SELECTION_MULTIPLE) {
- bool selected = fltkItem->selected ();
- res->itemsSelected.set (index, selected);
+ bool selected = fltkItem->is_selected ();
+ res->itemsSelected.set (index, selected);
+ }
+}
+
+void *FltkListResource::newItem (const char *str, bool enabled, bool selected)
+{
+ Fl_Tree *tree = (Fl_Tree *) widget;
+ Fl_Tree_Item *parent = (Fl_Tree_Item *)currParent;
+ Fl_Tree_Item *item = tree->add(parent, str);
+ int index = itemsSelected.size();
+
+ enabled &= parent->is_active();
+ item->activate(enabled);
+ item->user_data((void*)(long)index);
+ itemsSelected.increase ();
+ itemsSelected.set (itemsSelected.size() - 1, selected);
+
+ return item;
+}
+
+void FltkListResource::addItem (const char *str, bool enabled, bool selected)
+{
+ Fl_Tree *tree = (Fl_Tree *) widget;
+ Fl_Tree_Item *item = (Fl_Tree_Item *) newItem(str, enabled, selected);
+
+ if (selected) {
+ if (mode == SELECTION_MULTIPLE) {
+ item->select(selected);
} else {
- int size = res->itemsSelected.size();
- for (int i = 0; i < size; i++)
- res->itemsSelected.set (i, false);
- res->itemsSelected.set (index, true);
+ const bool do_callback = true;
+ tree->select_only(item, do_callback);
}
}
+ queueResize (true);
}
-void FltkListResource::addItem (const char *str, bool enabled, bool selected)
+void FltkListResource::pushGroup (const char *name, bool enabled)
{
- FltkSelectionResource<dw::core::ui::ListResource>::addItem
- (str,enabled,selected);
- int index = itemsSelected.size ();
- itemsSelected.increase ();
- itemsSelected.set (index,selected);
+ bool selected = false;
+
+ /* TODO: make it impossible to select a group */
+ currParent = (Fl_Tree_Item *) newItem(name, enabled, selected);
queueResize (true);
}
+void FltkListResource::popGroup ()
+{
+ Fl_Tree_Item *p = (Fl_Tree_Item *)currParent;
+
+ if (p->parent())
+ currParent = p->parent();
+}
+
+int FltkListResource::getMaxItemWidth()
+{
+ Fl_Tree *tree = (Fl_Tree *)widget;
+ int max = 0;
+
+ for (Fl_Tree_Item *i = tree->first(); i; i = tree->next(i)) {
+ int width = 0;
+
+ if (i == tree->root())
+ continue;
+
+ for (Fl_Tree_Item *p = i->parent(); p != tree->root(); p = p->parent())
+ width += tree->connectorwidth();
+
+ if (i->label())
+ width += fl_width(i->label());
+
+ if (width > max)
+ max = width;
+ }
+ return max;
+}
+
void FltkListResource::sizeRequest (core::Requisition *requisition)
{
if (style) {
FltkFont *font = (FltkFont*)style->font;
- ::fltk::setfont(font->font,font->size);
+ fl_font(font->font,font->size);
int rows = getNumberOfItems();
if (showRows < rows) {
rows = showRows;
}
- /*
- * The widget sometimes shows scrollbars when they are not required.
- * The following values try to keep any scrollbars from obscuring
- * options, at the cost of showing too much whitespace at times.
- */
- requisition->width = getMaxStringWidth() + 24;
- requisition->ascent = font->ascent + 2 +
+ requisition->width = getMaxItemWidth() + 5 + Fl::scrollbar_size();;
+ requisition->ascent = font->ascent + 5 +
(rows - 1) * (font->ascent + font->descent + 1);
requisition->descent = font->descent + 3;
} else {
diff --git a/dw/fltkui.hh b/dw/fltkui.hh
index 245d5aad..ff927c80 100644
--- a/dw/fltkui.hh
+++ b/dw/fltkui.hh
@@ -5,11 +5,9 @@
# error Do not include this file directly, use "fltkcore.hh" instead.
#endif
-#include <fltk/Button.h>
-#include <fltk/Menu.h>
-#include <fltk/TextBuffer.h>
-#include <fltk/Item.h>
-#include <fltk/ItemGroup.h>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Menu.H>
+#include <FL/Fl_Text_Buffer.H>
namespace dw {
namespace fltk {
@@ -179,7 +177,7 @@ private:
protected:
FltkView *view;
- ::fltk::Widget *widget;
+ Fl_Widget *widget;
core::Allocation allocation;
FltkPlatform *platform;
@@ -187,9 +185,9 @@ protected:
FltkResource (FltkPlatform *platform);
void init (FltkPlatform *platform);
- virtual ::fltk::Widget *createNewWidget (core::Allocation *allocation) = 0;
+ virtual Fl_Widget *createNewWidget (core::Allocation *allocation) = 0;
- void setWidgetStyle (::fltk::Widget *widget, core::style::Style *style);
+ virtual void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
void setDisplayed (bool displayed);
bool displayed();
public:
@@ -229,10 +227,10 @@ class FltkLabelButtonResource:
private:
const char *label;
- static void widgetCallback (::fltk::Widget *widget, void *data);
+ static void widgetCallback (Fl_Widget *widget, void *data);
protected:
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
public:
FltkLabelButtonResource (FltkPlatform *platform, const char *label);
@@ -251,7 +249,7 @@ class FltkComplexButtonResource:
private:
bool relief;
- static void widgetCallback (::fltk::Widget *widget, void *data);
+ static void widgetCallback (Fl_Widget *widget, void *data);
protected:
FltkView *topView, *flatView;
@@ -267,7 +265,7 @@ protected:
int reliefXThickness ();
int reliefYThickness ();
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
public:
FltkComplexButtonResource (FltkPlatform *platform, dw::core::Widget *widget,
@@ -288,13 +286,15 @@ private:
bool password;
const char *initText;
char *label;
+ int label_w;
bool editable;
- static void widgetCallback (::fltk::Widget *widget, void *data);
+ static void widgetCallback (Fl_Widget *widget, void *data);
void setDisplayed (bool displayed);
protected:
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
+ void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
public:
FltkEntryResource (FltkPlatform *platform, int maxLength, bool password,
@@ -302,6 +302,7 @@ public:
~FltkEntryResource ();
void sizeRequest (core::Requisition *requisition);
+ void sizeAllocate (core::Allocation *allocation);
const char *getText ();
void setText (const char *text);
@@ -314,12 +315,14 @@ class FltkMultiLineTextResource:
public FltkSpecificResource <dw::core::ui::MultiLineTextResource>
{
private:
- ::fltk::TextBuffer *buffer;
+ Fl_Text_Buffer *buffer;
+ char *text_copy;
bool editable;
int numCols, numRows;
protected:
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
+ void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
public:
FltkMultiLineTextResource (FltkPlatform *platform, int cols, int rows);
@@ -341,8 +344,9 @@ private:
bool initActivated;
protected:
- virtual ::fltk::Button *createNewButton (core::Allocation *allocation) = 0;
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
+ virtual Fl_Button *createNewButton (core::Allocation *allocation) = 0;
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
+ void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
public:
FltkToggleButtonResource (FltkPlatform *platform,
@@ -360,7 +364,7 @@ class FltkCheckButtonResource:
public FltkToggleButtonResource <dw::core::ui::CheckButtonResource>
{
protected:
- ::fltk::Button *createNewButton (core::Allocation *allocation);
+ Fl_Button *createNewButton (core::Allocation *allocation);
public:
FltkCheckButtonResource (FltkPlatform *platform,
@@ -401,7 +405,8 @@ private:
public:
Group (FltkRadioButtonResource *radioButtonResource);
- inline lout::container::typed::Iterator <FltkRadioButtonResource> iterator ()
+ inline lout::container::typed::Iterator <FltkRadioButtonResource>
+ iterator ()
{
return list->iterator ();
}
@@ -418,11 +423,11 @@ private:
Group *group;
- static void widgetCallback (::fltk::Widget *widget, void *data);
+ static void widgetCallback (Fl_Widget *widget, void *data);
void buttonClicked ();
protected:
- ::fltk::Button *createNewButton (core::Allocation *allocation);
+ Fl_Button *createNewButton (core::Allocation *allocation);
public:
FltkRadioButtonResource (FltkPlatform *platform,
@@ -438,60 +443,14 @@ template <class I> class FltkSelectionResource:
public FltkSpecificResource <I>
{
protected:
- class Item: public lout::object::Object
- {
- public:
- enum Type { ITEM, START, END } type;
-
- const char *name;
- bool enabled, initSelected;
-
- Item (Type type, const char *name = NULL, bool enabled = true,
- bool selected = false);
- ~Item ();
-
- ::fltk::Item *createNewWidget (int index);
- ::fltk::ItemGroup *createNewGroupWidget ();
- };
-
- class WidgetStack: public lout::object::Object
- {
- public:
- ::fltk::Menu *widget;
- lout::container::typed::Stack <lout::object::TypedPointer < ::fltk::Menu> > *stack;
-
- WidgetStack (::fltk::Menu *widget);
- ~WidgetStack ();
- };
-
- lout::container::typed::List <WidgetStack> *widgetStacks;
- lout::container::typed::List <Item> *allItems;
- lout::container::typed::Vector <Item> *items;
-
- Item *createNewItem (typename Item::Type type,
- const char *name = NULL,
- bool enabled = true,
- bool selected = false);
-
- ::fltk::Widget *createNewWidget (core::Allocation *allocation);
- virtual ::fltk::Menu *createNewMenu (core::Allocation *allocation) = 0;
virtual bool setSelectedItems() { return false; }
-
- int getMaxStringWidth ();
-
+ virtual void addItem (const char *str, bool enabled, bool selected) = 0;
+ virtual void pushGroup (const char *name, bool enabled) = 0;
+ virtual void popGroup () = 0;
public:
- FltkSelectionResource (FltkPlatform *platform);
- ~FltkSelectionResource ();
-
+ FltkSelectionResource (FltkPlatform *platform) :
+ FltkSpecificResource<I> (platform) {};
dw::core::Iterator *iterator (dw::core::Content::Type mask, bool atEnd);
-
- void addItem (const char *str, bool enabled, bool selected);
-
- void pushGroup (const char *name, bool enabled);
- void popGroup ();
-
- int getNumberOfItems ();
- const char *getItem (int index);
};
@@ -499,18 +458,25 @@ class FltkOptionMenuResource:
public FltkSelectionResource <dw::core::ui::OptionMenuResource>
{
protected:
- ::fltk::Menu *createNewMenu (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
virtual bool setSelectedItems() { return true; }
-
+ void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
+ int getNumberOfItems();
+ int getMaxItemWidth ();
private:
- static void widgetCallback (::fltk::Widget *widget, void *data);
- int selection;
-
+ static void widgetCallback (Fl_Widget *widget, void *data);
+ void enlargeMenu();
+ Fl_Menu_Item *newItem();
+ Fl_Menu_Item *menu;
+ int itemsAllocated, itemsUsed;
+ int visibleItems; /* not counting the invisible ones that close a group */
public:
FltkOptionMenuResource (FltkPlatform *platform);
~FltkOptionMenuResource ();
void addItem (const char *str, bool enabled, bool selected);
+ void pushGroup (const char *name, bool enabled);
+ void popGroup ();
void sizeRequest (core::Requisition *requisition);
bool isSelected (int index);
@@ -520,10 +486,16 @@ class FltkListResource:
public FltkSelectionResource <dw::core::ui::ListResource>
{
protected:
- ::fltk::Menu *createNewMenu (core::Allocation *allocation);
+ Fl_Widget *createNewWidget (core::Allocation *allocation);
+ void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
+
+ int getNumberOfItems () {return itemsSelected.size();};
+ int getMaxItemWidth ();
private:
- static void widgetCallback (::fltk::Widget *widget, void *data);
+ static void widgetCallback (Fl_Widget *widget, void *data);
+ void *newItem (const char *str, bool enabled, bool selected);
+ void *currParent;
lout::misc::SimpleVector <bool> itemsSelected;
int showRows;
ListResource::SelectionMode mode;
@@ -534,6 +506,8 @@ public:
~FltkListResource ();
void addItem (const char *str, bool enabled, bool selected);
+ void pushGroup (const char *name, bool enabled);
+ void popGroup ();
void sizeRequest (core::Requisition *requisition);
bool isSelected (int index);
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc
index cab22cf4..bf3aba22 100644
--- a/dw/fltkviewbase.cc
+++ b/dw/fltkviewbase.cc
@@ -21,40 +21,63 @@
#include "fltkviewport.hh"
-#include <fltk/draw.h>
-#include <fltk/damage.h>
-#include <fltk/layout.h>
-#include <fltk/events.h>
-#include <fltk/Cursor.h>
-#include <fltk/run.h>
-#include <fltk/utf.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
#include <stdio.h>
-#include <wchar.h>
-#include <wctype.h>
#include "../lout/msg.h"
-using namespace fltk;
+extern Fl_Widget* fl_oldfocus;
+
using namespace lout::object;
using namespace lout::container::typed;
namespace dw {
namespace fltk {
-::fltk::Image *FltkViewBase::backBuffer;
+FltkViewBase::BackBuffer::BackBuffer ()
+{
+ w = 0;
+ h = 0;
+ created = false;
+}
+
+FltkViewBase::BackBuffer::~BackBuffer ()
+{
+ if (created)
+ fl_delete_offscreen (offscreen);
+}
+
+void FltkViewBase::BackBuffer::setSize (int w, int h)
+{
+ if (!created || w > this->w || h > this->h) {
+ this->w = w;
+ this->h = h;
+ if (created)
+ fl_delete_offscreen (offscreen);
+ offscreen = fl_create_offscreen (w, h);
+ created = true;
+ }
+}
+
+FltkViewBase::BackBuffer *FltkViewBase::backBuffer;
bool FltkViewBase::backBufferInUse;
FltkViewBase::FltkViewBase (int x, int y, int w, int h, const char *label):
- Group (x, y, w, h, label)
+ Fl_Group (x, y, w, h, label)
{
+ Fl_Group::current(0);
canvasWidth = 1;
canvasHeight = 1;
- bgColor = WHITE;
+ bgColor = FL_WHITE;
mouse_x = mouse_y = 0;
+ focused_child = NULL;
exposeArea = NULL;
if (backBuffer == NULL) {
- backBuffer = new Image ();
+ backBuffer = new BackBuffer ();
}
+ box(FL_NO_BOX);
+ resizable(NULL);
}
FltkViewBase::~FltkViewBase ()
@@ -64,7 +87,7 @@ FltkViewBase::~FltkViewBase ()
void FltkViewBase::setBufferedDrawing (bool b) {
if (b && backBuffer == NULL) {
- backBuffer = new Image ();
+ backBuffer = new BackBuffer ();
} else if (!b && backBuffer != NULL) {
delete backBuffer;
backBuffer = NULL;
@@ -75,7 +98,7 @@ void FltkViewBase::draw ()
{
int d = damage ();
- if ((d & DAMAGE_VALUE) && !(d & DAMAGE_EXPOSE)) {
+ if ((d & FL_DAMAGE_USER1) && !(d & FL_DAMAGE_EXPOSE)) {
lout::container::typed::Iterator <core::Rectangle> it;
for (it = drawRegion.rectangles (); it.hasNext (); ) {
@@ -83,22 +106,22 @@ void FltkViewBase::draw ()
}
drawRegion.clear ();
- d &= ~DAMAGE_VALUE;
+ d &= ~FL_DAMAGE_USER1;
}
- if (d & DAMAGE_CHILD) {
+ if (d & FL_DAMAGE_CHILD) {
drawChildWidgets ();
- d &= ~DAMAGE_CHILD;
+ d &= ~FL_DAMAGE_CHILD;
}
if (d) {
dw::core::Rectangle rect (
- translateViewXToCanvasX (0),
- translateViewYToCanvasY (0),
+ translateViewXToCanvasX (x ()),
+ translateViewYToCanvasY (y ()),
w (),
h ());
- if (d == DAMAGE_SCROLL) {
+ if (d == FL_DAMAGE_SCROLL) {
// a clipping rectangle has already been set by fltk::scrollrect ()
draw (&rect, DRAW_PLAIN);
} else {
@@ -111,88 +134,84 @@ void FltkViewBase::draw ()
void FltkViewBase::draw (const core::Rectangle *rect,
DrawType type)
{
- int offsetX = 0, offsetY = 0;
-
- /* fltk-clipping does not use widget coordinates */
- transform (offsetX, offsetY);
-
- ::fltk::Rectangle viewRect (
- translateCanvasXToViewX (rect->x) + offsetX,
- translateCanvasYToViewY (rect->y) + offsetY,
- rect->width, rect->height);
-
- ::fltk::intersect_with_clip (viewRect);
-
- viewRect.x (viewRect.x () - offsetX);
- viewRect.y (viewRect.y () - offsetY);
-
- if (! viewRect.empty ()) {
- dw::core::Rectangle r (
- translateViewXToCanvasX (viewRect.x ()),
- translateViewYToCanvasY (viewRect.y ()),
- viewRect.w (),
- viewRect.h ());
-
- 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 ());
-
- setcolor (bgColor);
- fillrect (viewRect);
- theLayout->expose (this, &r);
- }
-
- backBuffer->draw (Rectangle (0, 0, viewRect.w (), viewRect.h ()),
- viewRect);
-
- backBufferInUse = false;
- } 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 {
- setcolor (bgColor);
- fillrect (viewRect);
- theLayout->expose (this, &r);
- }
-
- exposeArea = NULL;
+ int X = translateCanvasXToViewX (rect->x);
+ int Y = translateCanvasYToViewY (rect->y);
+ int W, H;
+
+ // fl_clip_box() can't handle values greater than SHRT_MAX!
+ if (X > x () + w () || Y > y () + h ())
+ return;
+
+ W = X + rect->width > x () + w () ? x () + w () - X : rect->width;
+ H = Y + rect->height > y () + h () ? y () + h () - Y : rect->height;
+
+ fl_clip_box(X, Y, W, H, X, Y, W, H);
+
+ core::Rectangle r (translateViewXToCanvasX (X),
+ translateViewYToCanvasY (Y), W, H);
+
+ if (r.isEmpty ())
+ return;
+
+ exposeArea = &r;
+
+ if (type == DRAW_BUFFERED && backBuffer && !backBufferInUse) {
+ backBufferInUse = true;
+ backBuffer->setSize (X + W, Y + H); // would be nicer to use (W, H)...
+ fl_begin_offscreen (backBuffer->offscreen);
+ fl_push_matrix ();
+ fl_color (bgColor);
+ fl_rectf (X, Y, W, H);
+ theLayout->expose (this, &r);
+ fl_pop_matrix ();
+ fl_end_offscreen ();
+ fl_copy_offscreen (X, Y, W, H, backBuffer->offscreen, X, Y);
+ backBufferInUse = false;
+ } 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
+ fl_push_clip (X, Y, W, H);
+ fl_color (bgColor);
+ fl_rectf (X, Y, W, H);
+ theLayout->expose (this, &r);
+ fl_pop_clip ();
+ } else {
+ fl_color (bgColor);
+ fl_rectf (X, Y, W, H);
+ theLayout->expose (this, &r);
}
+ // DEBUG:
+ //fl_color(FL_RED);
+ //fl_rect(X, Y, W, H);
+
+ exposeArea = NULL;
}
void FltkViewBase::drawChildWidgets () {
for (int i = children () - 1; i >= 0; i--) {
- Widget& w = *child(i);
+ Fl_Widget& w = *child(i);
+#if 0
+PORT1.3
if (w.damage() & DAMAGE_CHILD_LABEL) {
draw_outside_label(w);
w.set_damage(w.damage() & ~DAMAGE_CHILD_LABEL);
}
+#endif
update_child(w);
}
}
core::ButtonState getDwButtonState ()
{
- int s1 = event_state ();
+ int s1 = Fl::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 & FL_SHIFT) s2 |= core::SHIFT_MASK;
+ if (s1 & FL_CTRL) s2 |= core::CONTROL_MASK;
+ if (s1 & FL_ALT) s2 |= core::META_MASK;
+ if (s1 & FL_BUTTON1) s2 |= core::BUTTON1_MASK;
+ if (s1 & FL_BUTTON2) s2 |= core::BUTTON2_MASK;
+ if (s1 & FL_BUTTON3) s2 |= core::BUTTON3_MASK;
return (core::ButtonState)s2;
}
@@ -207,61 +226,79 @@ int FltkViewBase::handle (int event)
* when passed a fltk::PUSH event. "
*/
switch(event) {
- case PUSH:
+ case FL_PUSH:
+ /* Hide the tooltip */
+ theLayout->cancelTooltip();
+
processed =
- theLayout->buttonPress (this, event_clicks () + 1,
- translateViewXToCanvasX (event_x ()),
- translateViewYToCanvasY (event_y ()),
- getDwButtonState (), event_button ());
+ theLayout->buttonPress (this, Fl::event_clicks () + 1,
+ translateViewXToCanvasX (Fl::event_x ()),
+ translateViewYToCanvasY (Fl::event_y ()),
+ getDwButtonState (), Fl::event_button ());
_MSG("PUSH => %s\n", processed ? "true" : "false");
if (processed) {
/* pressed dw content; give focus to the view */
- ::fltk::focus(this);
+ Fl::focus(this);
+ return true;
}
- return processed ? true : Group::handle (event);
-
- case RELEASE:
+ break;
+ case FL_RELEASE:
processed =
- theLayout->buttonRelease (this, event_clicks () + 1,
- translateViewXToCanvasX (event_x ()),
- translateViewYToCanvasY (event_y ()),
- getDwButtonState (), event_button ());
+ theLayout->buttonRelease (this, Fl::event_clicks () + 1,
+ translateViewXToCanvasX (Fl::event_x ()),
+ translateViewYToCanvasY (Fl::event_y ()),
+ getDwButtonState (), Fl::event_button ());
_MSG("RELEASE => %s\n", processed ? "true" : "false");
- return processed ? true : Group::handle (event);
-
- case MOVE:
- mouse_x = event_x();
- mouse_y = event_y();
+ if (processed)
+ return true;
+ break;
+ case FL_MOVE:
+ mouse_x = Fl::event_x();
+ mouse_y = Fl::event_y();
processed =
theLayout->motionNotify (this,
translateViewXToCanvasX (mouse_x),
translateViewYToCanvasY (mouse_y),
getDwButtonState ());
_MSG("MOVE => %s\n", processed ? "true" : "false");
- return processed ? true : Group::handle (event);
-
- case DRAG:
+ if (processed)
+ return true;
+ break;
+ case FL_DRAG:
processed =
theLayout->motionNotify (this,
- translateViewXToCanvasX (event_x ()),
- translateViewYToCanvasY (event_y ()),
+ translateViewXToCanvasX (Fl::event_x ()),
+ translateViewYToCanvasY (Fl::event_y ()),
getDwButtonState ());
_MSG("DRAG => %s\n", processed ? "true" : "false");
- return processed ? true : Group::handle (event);
-
- case ENTER:
- theLayout->enterNotify (this, translateViewXToCanvasX (event_x ()),
- translateViewYToCanvasY (event_y ()),
+ if (processed)
+ return true;
+ break;
+ case FL_ENTER:
+ theLayout->enterNotify (this,
+ translateViewXToCanvasX (Fl::event_x ()),
+ translateViewYToCanvasY (Fl::event_y ()),
getDwButtonState ());
- return Group::handle (event);
-
- case LEAVE:
+ break;
+ case FL_HIDE:
+ /* WORKAROUND: strangely, the tooltip window is not automatically hidden
+ * with its parent. Here we fake a LEAVE to achieve it. */
+ case FL_LEAVE:
theLayout->leaveNotify (this, getDwButtonState ());
- return Group::handle (event);
-
+ break;
+ case FL_FOCUS:
+ if (focused_child && find(focused_child) < children()) {
+ /* strangely, find() == children() if the child is not found */
+ focused_child->take_focus();
+ }
+ return 1;
+ case FL_UNFOCUS:
+ focused_child = fl_oldfocus;
+ return 0;
default:
- return Group::handle (event);
+ break;
}
+ return Fl_Group::handle (event);
}
// ----------------------------------------------------------------------
@@ -269,6 +306,8 @@ int FltkViewBase::handle (int event)
void FltkViewBase::setLayout (core::Layout *layout)
{
theLayout = layout;
+ if (usesViewport())
+ theLayout->viewportSizeChanged(this, w(), h());
}
void FltkViewBase::setCanvasSize (int width, int ascent, int descent)
@@ -279,55 +318,32 @@ void FltkViewBase::setCanvasSize (int width, int ascent, int descent)
void FltkViewBase::setCursor (core::style::Cursor cursor)
{
- static Cursor *mapDwToFltk[] = {
- CURSOR_CROSS,
- CURSOR_DEFAULT,
- CURSOR_HAND,
- CURSOR_MOVE,
- CURSOR_WE,
- CURSOR_NESW,
- CURSOR_NWSE,
- CURSOR_NS,
- CURSOR_NWSE,
- CURSOR_NESW,
- CURSOR_NS,
- CURSOR_WE,
- CURSOR_INSERT,
- CURSOR_WAIT,
- CURSOR_HELP
- };
-
- /*
- static char *cursorName[] = {
- "CURSOR_CROSS",
- "CURSOR_DEFAULT",
- "CURSOR_HAND",
- "CURSOR_MOVE",
- "CURSOR_WE",
- "CURSOR_NESW",
- "CURSOR_NWSE",
- "CURSOR_NS",
- "CURSOR_NWSE",
- "CURSOR_NESW",
- "CURSOR_NS",
- "CURSOR_WE",
- "CURSOR_INSERT",
- "CURSOR_WAIT",
- "CURSOR_HELP"
+ static Fl_Cursor mapDwToFltk[] = {
+ FL_CURSOR_CROSS,
+ FL_CURSOR_DEFAULT,
+ FL_CURSOR_HAND,
+ FL_CURSOR_MOVE,
+ FL_CURSOR_WE,
+ FL_CURSOR_NESW,
+ FL_CURSOR_NWSE,
+ FL_CURSOR_NS,
+ FL_CURSOR_NWSE,
+ FL_CURSOR_NESW,
+ FL_CURSOR_NS,
+ FL_CURSOR_WE,
+ FL_CURSOR_INSERT,
+ FL_CURSOR_WAIT,
+ FL_CURSOR_HELP
};
- MSG("Cursor changes to '%s'.\n", cursorName[cursor]);
- */
-
- /** \bug Does not work */
- this->cursor (mapDwToFltk[cursor]);
+ fl_cursor (mapDwToFltk[cursor]);
}
void FltkViewBase::setBgColor (core::style::Color *color)
{
bgColor = color ?
((FltkColor*)color)->colors[dw::core::style::Color::SHADING_NORMAL] :
- WHITE;
+ FL_WHITE;
}
void FltkViewBase::startDrawing (core::Rectangle *area)
@@ -342,12 +358,12 @@ void FltkViewBase::queueDraw (core::Rectangle *area)
{
drawRegion.addRectangle (area);
/** DAMAGE_VALUE is just an arbitrary value other than DAMAGE_EXPOSE here */
- redraw (DAMAGE_VALUE);
+ damage (FL_DAMAGE_USER1);
}
void FltkViewBase::queueDrawTotal ()
{
- redraw (DAMAGE_EXPOSE);
+ damage (FL_DAMAGE_EXPOSE);
}
void FltkViewBase::cancelQueueDraw ()
@@ -364,9 +380,16 @@ void FltkViewBase::drawLine (core::style::Color *color,
core::style::Color::Shading shading,
int x1, int y1, int x2, int y2)
{
- setcolor(((FltkColor*)color)->colors[shading]);
- drawline (translateCanvasXToViewX (x1), translateCanvasYToViewY (y1),
- translateCanvasXToViewX (x2), translateCanvasYToViewY (y2));
+ fl_color(((FltkColor*)color)->colors[shading]);
+ // we clip with a large border (5000px), as clipping causes artefacts
+ // with non-solid line styles.
+ // However it's still better than no clipping at all.
+ clipPoint (&x1, &y1, 5000);
+ clipPoint (&x2, &y2, 5000);
+ fl_line (translateCanvasXToViewX (x1),
+ translateCanvasYToViewY (y1),
+ translateCanvasXToViewX (x2),
+ translateCanvasYToViewY (y2));
}
void FltkViewBase::drawTypedLine (core::style::Color *color,
@@ -385,42 +408,42 @@ void FltkViewBase::drawTypedLine (core::style::Color *color,
d = len % f*width;
gap = ng ? d/ng + (w > 3 ? 2 : 0) : 0;
dashes[0] = 1; dashes[1] = f*width-gap; dashes[2] = 0;
- line_style(::fltk::DASH + ::fltk::CAP_ROUND, w, dashes);
+ fl_line_style(FL_DASH + FL_CAP_ROUND, w, dashes);
/* These formulas also work, but ain't pretty ;)
- * line_style(::fltk::DOT + ::fltk::CAP_ROUND, w);
+ * fl_line_style(FL_DOT + FL_CAP_ROUND, w);
* dashes[0] = 1; dashes[1] = 3*width-2; dashes[2] = 0;
*/
} else if (type == core::style::LINE_DASHED) {
- line_style(::fltk::DASH + ::fltk::CAP_ROUND, w);
+ fl_line_style(FL_DASH + FL_CAP_ROUND, w);
}
- setcolor(((FltkColor*)color)->colors[shading]);
+ fl_color(((FltkColor*)color)->colors[shading]);
drawLine (color, shading, x1, y1, x2, y2);
if (type != core::style::LINE_NORMAL)
- line_style(::fltk::SOLID);
+ fl_line_style(FL_SOLID);
}
void FltkViewBase::drawRectangle (core::style::Color *color,
core::style::Color::Shading shading,
bool filled,
- int x, int y, int width, int height)
+ int X, int Y, int width, int height)
{
- setcolor(((FltkColor*)color)->colors[shading]);
+ fl_color(((FltkColor*)color)->colors[shading]);
if (width < 0) {
- x += width;
+ X += width;
width = -width;
}
if (height < 0) {
- y += height;
+ Y += height;
height = -height;
}
- int x1 = translateCanvasXToViewX (x);
- int y1 = translateCanvasYToViewY (y);
- int x2 = translateCanvasXToViewX (x + width);
- int y2 = translateCanvasYToViewY (y + height);
+ int x1 = X;
+ int y1 = Y;
+ int x2 = X + width;
+ int y2 = 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.
@@ -428,11 +451,15 @@ void FltkViewBase::drawRectangle (core::style::Color *color,
clipPoint (&x1, &y1, 1);
clipPoint (&x2, &y2, 1);
- ::fltk::Rectangle rect (x1, y1, x2 - x1, y2 - y1);
+ x1 = translateCanvasXToViewX (x1);
+ y1 = translateCanvasYToViewY (y1);
+ x2 = translateCanvasXToViewX (x2);
+ y2 = translateCanvasYToViewY (y2);
+
if (filled)
- fillrect (rect);
+ fl_rectf (x1, y1, x2 - x1, y2 - y1);
else
- strokerect (rect);
+ fl_rect (x1, y1, x2 - x1, y2 - y1);
}
void FltkViewBase::drawArc (core::style::Color *color,
@@ -440,47 +467,55 @@ void FltkViewBase::drawArc (core::style::Color *color,
int centerX, int centerY, int width, int height,
int angle1, int angle2)
{
- setcolor(((FltkColor*)color)->colors[shading]);
+ fl_color(((FltkColor*)color)->colors[shading]);
int x = translateCanvasXToViewX (centerX) - width / 2;
int y = translateCanvasYToViewY (centerY) - height / 2;
- ::fltk::Rectangle rect (x, y, width, height);
- addchord(rect, angle1, angle2);
- closepath();
+
+ fl_arc(x, y, width, height, angle1, angle2);
if (filled)
- fillpath();
- else
- strokepath();
+ fl_pie(x, y, width, height, angle1, angle2);
}
void FltkViewBase::drawPolygon (core::style::Color *color,
core::style::Color::Shading shading,
- bool filled, int points[][2], int npoints)
+ bool filled, bool convex, core::Point *points,
+ int npoints)
{
if (npoints > 0) {
+ fl_color(((FltkColor*)color)->colors[shading]);
+
+ if (filled) {
+ if (convex)
+ fl_begin_polygon();
+ else
+ fl_begin_complex_polygon();
+ } else
+ fl_begin_loop();
+
for (int i = 0; i < npoints; i++) {
- points[i][0] = translateCanvasXToViewX(points[i][0]);
- points[i][1] = translateCanvasYToViewY(points[i][1]);
+ fl_vertex(translateCanvasXToViewX(points[i].x),
+ translateCanvasYToViewY(points[i].y));
}
- setcolor(((FltkColor*)color)->colors[shading]);
- addvertices(npoints, points);
- closepath();
- if (filled)
- fillpath();
- else
- strokepath();
+ if (filled) {
+ if (convex)
+ fl_end_polygon();
+ else
+ fl_end_complex_polygon();
+ } else
+ fl_end_loop();
}
}
core::View *FltkViewBase::getClippingView (int x, int y, int width, int height)
{
- push_clip (translateCanvasXToViewX (x), translateCanvasYToViewY (y),
- width, height);
+ fl_push_clip (translateCanvasXToViewX (x), translateCanvasYToViewY (y),
+ width, height);
return this;
}
void FltkViewBase::mergeClippingView (core::View *clippingView)
{
- pop_clip ();
+ fl_pop_clip ();
}
// ----------------------------------------------------------------------
@@ -495,80 +530,83 @@ FltkWidgetView::~FltkWidgetView ()
{
}
-void FltkWidgetView::layout () {
- /**
- * 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.
- */
- for (int i = children () - 1; i >= 0; i--) {
- ::fltk::Widget *widget = child (i);
-
- if (widget->layout_damage ()) {
- widget->layout ();
- }
- }
-}
-
void FltkWidgetView::drawText (core::style::Font *font,
core::style::Color *color,
core::style::Color::Shading shading,
- int x, int y, const char *text, int len)
+ int X, int Y, const char *text, int len)
{
FltkFont *ff = (FltkFont*)font;
- setfont(ff->font, ff->size);
- setcolor(((FltkColor*)color)->colors[shading]);
+ fl_font(ff->font, ff->size);
+ fl_color(((FltkColor*)color)->colors[shading]);
if (!font->letterSpacing && !font->fontVariant) {
- drawtext(text, len,
- translateCanvasXToViewX (x), translateCanvasYToViewY (y));
+ fl_draw(text, len,
+ translateCanvasXToViewX (X), translateCanvasYToViewY (Y));
} else {
/* Nonzero letter spacing adjustment, draw each glyph individually */
- int viewX = translateCanvasXToViewX (x),
- viewY = translateCanvasYToViewY (y);
+ int viewX = translateCanvasXToViewX (X),
+ viewY = translateCanvasYToViewY (Y);
int curr = 0, next = 0, nb;
char chbuf[4];
- wchar_t wc, wcu;
+ int c, cu;
- if (font->fontVariant == 1) {
+ if (font->fontVariant == core::style::FONT_VARIANT_SMALL_CAPS) {
int sc_fontsize = lout::misc::roundInt(ff->size * 0.78);
for (curr = 0; next < len; curr = next) {
next = theLayout->nextGlyph(text, curr);
- wc = utf8decode(text + curr, text + next, &nb);
- if ((wcu = towupper(wc)) == wc) {
+ c = fl_utf8decode(text + curr, text + next, &nb);
+ if ((cu = fl_toupper(c)) == c) {
/* already uppercase, just draw the character */
- setfont(ff->font, ff->size);
- drawtext(text + curr, next - curr, viewX, viewY);
+ fl_font(ff->font, ff->size);
+ fl_draw(text + curr, next - curr, viewX, viewY);
viewX += font->letterSpacing;
- viewX += (int)getwidth(text + curr, next - curr);
+ viewX += (int)fl_width(text + curr, next - curr);
} else {
/* make utf8 string for converted char */
- nb = utf8encode(wcu, chbuf);
- setfont(ff->font, sc_fontsize);
- drawtext(chbuf, nb, viewX, viewY);
+ nb = fl_utf8encode(cu, chbuf);
+ fl_font(ff->font, sc_fontsize);
+ fl_draw(chbuf, nb, viewX, viewY);
viewX += font->letterSpacing;
- viewX += (int)getwidth(chbuf, nb);
+ viewX += (int)fl_width(chbuf, nb);
}
}
} else {
while (next < len) {
next = theLayout->nextGlyph(text, curr);
- drawtext(text + curr, next - curr, viewX, viewY);
+ fl_draw(text + curr, next - curr, viewX, viewY);
viewX += font->letterSpacing +
- (int)getwidth(text + curr,next - curr);
+ (int)fl_width(text + curr,next - curr);
curr = next;
}
}
}
}
+/*
+ * "simple" in that it ignores letter-spacing, etc. This was added for image
+ * alt text where none of that matters.
+ */
+void FltkWidgetView::drawSimpleWrappedText (core::style::Font *font,
+ core::style::Color *color,
+ core::style::Color::Shading shading,
+ int X, int Y, int W, int H,
+ const char *text)
+{
+ FltkFont *ff = (FltkFont*)font;
+ fl_font(ff->font, ff->size);
+ fl_color(((FltkColor*)color)->colors[shading]);
+ fl_draw(text,
+ translateCanvasXToViewX (X), translateCanvasYToViewY (Y),
+ W, H, FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_WRAP, NULL, 0);
+}
+
void FltkWidgetView::drawImage (core::Imgbuf *imgbuf, int xRoot, int yRoot,
- int x, int y, int width, int height)
+ int X, int Y, int width, int height)
{
((FltkImgbuf*)imgbuf)->draw (this,
translateCanvasXToViewX (xRoot),
translateCanvasYToViewY (yRoot),
- x, y, width, height);
+ X, Y, width, height);
}
bool FltkWidgetView::usesFltkWidgets ()
@@ -576,36 +614,32 @@ bool FltkWidgetView::usesFltkWidgets ()
return true;
}
-void FltkWidgetView::addFltkWidget (::fltk::Widget *widget,
- core::Allocation *allocation)
+void FltkWidgetView::addFltkWidget (Fl_Widget *widget,
+ core::Allocation *allocation)
{
allocateFltkWidget (widget, allocation);
add (widget);
}
-void FltkWidgetView::removeFltkWidget (::fltk::Widget *widget)
+void FltkWidgetView::removeFltkWidget (Fl_Widget *widget)
{
remove (widget);
}
-void FltkWidgetView::allocateFltkWidget (::fltk::Widget *widget,
+void FltkWidgetView::allocateFltkWidget (Fl_Widget *widget,
core::Allocation *allocation)
{
- widget->x (translateCanvasXToViewX (allocation->x));
- widget->y (translateCanvasYToViewY (allocation->y));
- widget->w (allocation->width);
- widget->h (allocation->ascent + allocation->descent);
-
- /* widgets created tiny and later resized need this flag to display */
- uchar damage = widget->layout_damage ();
- damage |= LAYOUT_XYWH;
- widget->layout_damage (damage);
+ widget->resize (translateCanvasXToViewX (allocation->x),
+ translateCanvasYToViewY (allocation->y),
+ allocation->width,
+ allocation->ascent + allocation->descent);
}
-void FltkWidgetView::drawFltkWidget (::fltk::Widget *widget,
+void FltkWidgetView::drawFltkWidget (Fl_Widget *widget,
core::Rectangle *area)
{
draw_child (*widget);
+ draw_outside_label(*widget);
}
} // namespace fltk
diff --git a/dw/fltkviewbase.hh b/dw/fltkviewbase.hh
index b5c3ab5e..2b248803 100644
--- a/dw/fltkviewbase.hh
+++ b/dw/fltkviewbase.hh
@@ -4,45 +4,58 @@
#include <time.h> // for time_t
#include <sys/time.h> // for time_t in FreeBSD
-#include <fltk/Group.h>
-#include <fltk/Image.h>
-#include <fltk/Scrollbar.h>
+#include <FL/Fl_Group.H>
+#include <FL/x.H>
#include "fltkcore.hh"
namespace dw {
namespace fltk {
-class FltkViewBase: public FltkView, public ::fltk::Group
+class FltkViewBase: public FltkView, public Fl_Group
{
private:
+ class BackBuffer {
+ private:
+ int w;
+ int h;
+ bool created;
+
+ public:
+ Fl_Offscreen offscreen;
+
+ BackBuffer ();
+ ~BackBuffer ();
+ void setSize(int w, int h);
+ };
+
typedef enum { DRAW_PLAIN, DRAW_CLIPPED, DRAW_BUFFERED } DrawType;
int bgColor;
core::Region drawRegion;
- ::fltk::Rectangle *exposeArea;
- static ::fltk::Image *backBuffer;
+ core::Rectangle *exposeArea;
+ static BackBuffer *backBuffer;
static bool backBufferInUse;
void draw (const core::Rectangle *rect, DrawType type);
void drawChildWidgets ();
inline void clipPoint (int *x, int *y, int border) {
if (exposeArea) {
- if (*x < exposeArea->x () - border)
- *x = exposeArea->x () - border;
- if (*x > exposeArea->r () + border)
- *x = exposeArea->r () + border;
- if (*y < exposeArea->y () - border)
- *y = exposeArea->y () - border;
- if (*y > exposeArea->b () + border)
- *y = exposeArea->b () + border;
+ if (*x < exposeArea->x - border)
+ *x = exposeArea->x - border;
+ if (*x > exposeArea->x + exposeArea->width + border)
+ *x = exposeArea->x + exposeArea->width + border;
+ if (*y < exposeArea->y - border)
+ *y = exposeArea->y - border;
+ if (*y > exposeArea->y + exposeArea->height + border)
+ *y = exposeArea->y + exposeArea->height + border;
}
}
-
protected:
core::Layout *theLayout;
int canvasWidth, canvasHeight;
int mouse_x, mouse_y;
+ Fl_Widget *focused_child;
virtual int translateViewXToCanvasX (int x) = 0;
virtual int translateViewYToCanvasY (int y) = 0;
@@ -85,7 +98,8 @@ public:
int angle1, int angle2);
void drawPolygon (core::style::Color *color,
core::style::Color::Shading shading,
- bool filled, int points[][2], int npoints);
+ bool filled, bool convex,
+ core::Point *points, int npoints);
core::View *getClippingView (int x, int y, int width, int height);
void mergeClippingView (core::View *clippingView);
@@ -99,21 +113,24 @@ public:
FltkWidgetView (int x, int y, int w, int h, const char *label = 0);
~FltkWidgetView ();
- void layout();
-
void drawText (core::style::Font *font,
core::style::Color *color,
core::style::Color::Shading shading,
int x, int y, const char *text, int len);
+ void drawSimpleWrappedText (core::style::Font *font,
+ core::style::Color *color,
+ core::style::Color::Shading shading,
+ int x, int y, int w, int h,
+ const char *text);
void drawImage (core::Imgbuf *imgbuf, int xRoot, int yRoot,
int x, int y, int width, int height);
bool usesFltkWidgets ();
- void addFltkWidget (::fltk::Widget *widget, core::Allocation *allocation);
- void removeFltkWidget (::fltk::Widget *widget);
- void allocateFltkWidget (::fltk::Widget *widget,
+ void addFltkWidget (Fl_Widget *widget, core::Allocation *allocation);
+ void removeFltkWidget (Fl_Widget *widget);
+ void allocateFltkWidget (Fl_Widget *widget,
core::Allocation *allocation);
- void drawFltkWidget (::fltk::Widget *widget, core::Rectangle *area);
+ void drawFltkWidget (Fl_Widget *widget, core::Rectangle *area);
};
} // namespace fltk
diff --git a/dw/fltkviewport.cc b/dw/fltkviewport.cc
index a8555c60..19e28854 100644
--- a/dw/fltkviewport.cc
+++ b/dw/fltkviewport.cc
@@ -21,14 +21,13 @@
#include "fltkviewport.hh"
-#include <fltk/draw.h>
-#include <fltk/damage.h>
-#include <fltk/events.h>
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/names.h>
#include <stdio.h>
#include "../lout/msg.h"
-using namespace fltk;
using namespace lout;
using namespace lout::object;
using namespace lout::container::typed;
@@ -36,21 +35,39 @@ using namespace lout::container::typed;
namespace dw {
namespace fltk {
-FltkViewport::FltkViewport (int x, int y, int w, int h, const char *label):
- FltkWidgetView (x, y, w, h, label)
+/*
+ * Lets SHIFT+{Left,Right} go to the parent
+ */
+class CustScrollbar : public Fl_Scrollbar
{
- hscrollbar = new Scrollbar (0, 0, 1, 1);
- hscrollbar->set_horizontal();
+public:
+ CustScrollbar(int x, int y, int w, int h) : Fl_Scrollbar(x,y,w,h) {};
+ int handle(int e) {
+ if (e == FL_SHORTCUT && Fl::event_state() == FL_SHIFT &&
+ (Fl::event_key() == FL_Left || Fl::event_key() == FL_Right))
+ return 0;
+ return Fl_Scrollbar::handle(e);
+ }
+};
+
+FltkViewport::FltkViewport (int X, int Y, int W, int H, const char *label):
+ FltkWidgetView (X, Y, W, H, label)
+{
+ hscrollbar = new CustScrollbar (x (), y (), 1, 1);
+ hscrollbar->type(FL_HORIZONTAL);
hscrollbar->callback (hscrollbarCallback, this);
+ hscrollbar->hide();
add (hscrollbar);
- vscrollbar = new Scrollbar (0, 0, 1, 1);
- vscrollbar->set_vertical();
+ vscrollbar = new Fl_Scrollbar (x (), y(), 1, 1);
+ vscrollbar->type(FL_VERTICAL);
vscrollbar->callback (vscrollbarCallback, this);
+ vscrollbar->hide();
add (vscrollbar);
+ hasDragScroll = 1;
scrollX = scrollY = scrollDX = scrollDY = 0;
- dragScrolling = 0;
+ horScrolling = verScrolling = dragScrolling = 0;
gadgetOrientation[0] = GADGET_HORIZONTAL;
gadgetOrientation[1] = GADGET_HORIZONTAL;
@@ -58,7 +75,7 @@ FltkViewport::FltkViewport (int x, int y, int w, int h, const char *label):
gadgetOrientation[3] = GADGET_HORIZONTAL;
gadgets =
- new container::typed::List <object::TypedPointer < ::fltk::Widget> >
+ new container::typed::List <object::TypedPointer < Fl_Widget> >
(true);
}
@@ -72,6 +89,7 @@ void FltkViewport::adjustScrollbarsAndGadgetsAllocation ()
int hdiff = 0, vdiff = 0;
int visibility = 0;
+ _MSG(" >>FltkViewport::adjustScrollbarsAndGadgetsAllocation\n");
if (hscrollbar->visible ())
visibility |= 1;
if (vscrollbar->visible ())
@@ -94,32 +112,25 @@ void FltkViewport::adjustScrollbarsAndGadgetsAllocation ()
vdiff = hscrollbar->visible () ? SCROLLBAR_THICKNESS : 0;
}
- hscrollbar->x (0);
- hscrollbar->y (0 + h () - SCROLLBAR_THICKNESS);
- hscrollbar->w (w () - hdiff);
- hscrollbar->h (SCROLLBAR_THICKNESS);
-
- vscrollbar->x (0 + w () - SCROLLBAR_THICKNESS);
- vscrollbar->y (0);
- vscrollbar->h (h () - vdiff);
- vscrollbar->w (SCROLLBAR_THICKNESS);
+ hscrollbar->resize(x (), y () + h () - SCROLLBAR_THICKNESS,
+ w () - hdiff, SCROLLBAR_THICKNESS);
+ vscrollbar->resize(x () + w () - SCROLLBAR_THICKNESS, y (),
+ SCROLLBAR_THICKNESS, h () - vdiff);
- int x = w () - SCROLLBAR_THICKNESS, y = h () - SCROLLBAR_THICKNESS;
- for (Iterator <TypedPointer < ::fltk::Widget> > it = gadgets->iterator ();
+ int X = x () + w () - SCROLLBAR_THICKNESS;
+ int Y = y () + h () - SCROLLBAR_THICKNESS;
+ for (Iterator <TypedPointer < Fl_Widget> > it = gadgets->iterator ();
it.hasNext (); ) {
- ::fltk::Widget *widget = it.getNext()->getTypedValue ();
- widget->x (0);
- widget->y (0);
- widget->w (SCROLLBAR_THICKNESS);
- widget->h (SCROLLBAR_THICKNESS);
+ Fl_Widget *widget = it.getNext()->getTypedValue ();
+ widget->resize(x (), y (), SCROLLBAR_THICKNESS, SCROLLBAR_THICKNESS);
switch (gadgetOrientation [visibility]) {
case GADGET_VERTICAL:
- y -= SCROLLBAR_THICKNESS;
+ Y -= SCROLLBAR_THICKNESS;
break;
case GADGET_HORIZONTAL:
- x -= SCROLLBAR_THICKNESS;
+ X -= SCROLLBAR_THICKNESS;
break;
}
}
@@ -141,40 +152,43 @@ void FltkViewport::vscrollbarChanged ()
scroll (0, vscrollbar->value () - scrollY);
}
-void FltkViewport::vscrollbarCallback (Widget *vscrollbar, void *viewportPtr)
+void FltkViewport::vscrollbarCallback (Fl_Widget *vscrollbar,void *viewportPtr)
{
((FltkViewport*)viewportPtr)->vscrollbarChanged ();
}
-void FltkViewport::hscrollbarCallback (Widget *hscrollbar, void *viewportPtr)
+void FltkViewport::hscrollbarCallback (Fl_Widget *hscrollbar,void *viewportPtr)
{
((FltkViewport*)viewportPtr)->hscrollbarChanged ();
}
// ----------------------------------------------------------------------
-void FltkViewport::layout ()
+void FltkViewport::resize(int X, int Y, int W, int H)
{
- theLayout->viewportSizeChanged (this, w(), h());
- adjustScrollbarsAndGadgetsAllocation ();
+ bool dimension_changed = W != w() || H != h();
- FltkWidgetView::layout ();
+ Fl_Group::resize(X, Y, W, H);
+ if (dimension_changed) {
+ theLayout->viewportSizeChanged (this, W, H);
+ adjustScrollbarsAndGadgetsAllocation ();
+ }
}
-void FltkViewport::draw_area (void *data, const Rectangle& cr )
+void FltkViewport::draw_area (void *data, int x, int y, int w, int h)
{
FltkViewport *vp = (FltkViewport*) data;
- push_clip(cr);
+ fl_push_clip(x, y, w, h);
vp->FltkWidgetView::draw ();
- for (Iterator <TypedPointer < ::fltk::Widget> > it = vp->gadgets->iterator();
+ for (Iterator <TypedPointer < Fl_Widget> > it = vp->gadgets->iterator();
it.hasNext (); ) {
- ::fltk::Widget *widget = it.getNext()->getTypedValue ();
+ Fl_Widget *widget = it.getNext()->getTypedValue ();
vp->draw_child (*widget);
}
- pop_clip();
+ fl_pop_clip();
}
@@ -182,20 +196,19 @@ void FltkViewport::draw ()
{
int hdiff = vscrollbar->visible () ? SCROLLBAR_THICKNESS : 0;
int vdiff = hscrollbar->visible () ? SCROLLBAR_THICKNESS : 0;
- Rectangle cr (0, 0, w () - hdiff, h () - vdiff);
int d = damage();
- if (d & DAMAGE_SCROLL) {
- set_damage (DAMAGE_SCROLL);
- scrollrect(cr, -scrollDX, -scrollDY, draw_area, this);
- d &= ~DAMAGE_SCROLL;
- set_damage (d);
+ if (d & FL_DAMAGE_SCROLL) {
+ clear_damage (FL_DAMAGE_SCROLL);
+ fl_scroll(x(), y(), w() - hdiff, h() - vdiff,
+ -scrollDX, -scrollDY, draw_area, this);
+ clear_damage (d & ~FL_DAMAGE_SCROLL);
}
if (d) {
- draw_area(this, cr);
+ draw_area(this, x(), y(), w () - hdiff, h () - vdiff);
- if (d == DAMAGE_CHILD) {
+ if (d == FL_DAMAGE_CHILD) {
if (hscrollbar->damage ())
draw_child (*hscrollbar);
if (vscrollbar->damage ())
@@ -212,89 +225,93 @@ void FltkViewport::draw ()
int FltkViewport::handle (int event)
{
- _MSG("FltkViewport::handle %d\n", event);
-
- if (hscrollbar->Rectangle::contains (event_x (), event_y ()) &&
- !(event_state() & (SHIFT | CTRL | ALT)) &&
- hscrollbar->send (event)) {
- return 1;
- }
-
- if (vscrollbar->Rectangle::contains (event_x (), event_y ()) &&
- vscrollbar->send (event)) {
- return 1;
- }
+ _MSG("FltkViewport::handle %s\n", fl_eventnames[event]);
switch(event) {
- case ::fltk::KEY:
- /* Tell fltk we want to receive KEY events as SHORTCUT.
- * As we don't know the exact keybindings set by the user, we ask
- * for all of them (except TabKey to keep form navigation). */
- if (::fltk::event_key() != TabKey)
+ case FL_KEYBOARD:
+ /* When the viewport has focus (and not one of its children), FLTK
+ * sends the event here. Returning zero tells FLTK to resend the
+ * event as SHORTCUT, which we finally route to the parent. */
+
+ /* As we don't know the exact keybindings set by the user, we ask
+ * for all of them (except Tab to keep form navigation). */
+ if (Fl::event_key() != FL_Tab)
return 0;
break;
- case ::fltk::FOCUS:
- /** \bug Draw focus box. */
+ case FL_SHORTCUT:
+ /* send it to the parent (UI) */
+ return 0;
- /* If the user clicks with the left button we take focus
- * and thereby unfocus any form widgets.
- * Otherwise we let fltk do the focus handling.
- */
- if (::fltk::event_button() == ::fltk::LeftButton || focus_index() < 0) {
- focus_index(-1);
- return 1;
- }
+ case FL_FOCUS:
+ /** \bug Draw focus box. */
break;
- case ::fltk::UNFOCUS:
+ case FL_UNFOCUS:
/** \bug Undraw focus box. */
break;
- case ::fltk::PUSH:
- take_focus();
- if (::fltk::event_button() == ::fltk::MiddleButton) {
- /* pass event so that middle click can open link in new window */
- if (FltkWidgetView::handle (event) == 0) {
+ case FL_PUSH:
+ if (vscrollbar->visible() && Fl::event_inside(vscrollbar)) {
+ if (vscrollbar->handle(event))
+ verScrolling = 1;
+ } else if (hscrollbar->visible() && Fl::event_inside(hscrollbar)) {
+ if (hscrollbar->handle(event))
+ horScrolling = 1;
+ } else if (FltkWidgetView::handle(event) == 0 &&
+ Fl::event_button() == FL_MIDDLE_MOUSE) {
+ if (!hasDragScroll) {
+ /* let the parent widget handle it... */
+ return 0;
+ } else {
+ /* receive FL_DRAG and FL_RELEASE */
dragScrolling = 1;
- dragX = ::fltk::event_x();
- dragY = ::fltk::event_y();
+ dragX = Fl::event_x();
+ dragY = Fl::event_y();
setCursor (core::style::CURSOR_MOVE);
}
- return 1;
}
+ return 1;
break;
- case ::fltk::DRAG:
- if (::fltk::event_button() == ::fltk::MiddleButton) {
- if (dragScrolling) {
- scroll(dragX - ::fltk::event_x(), dragY - ::fltk::event_y());
- dragX = ::fltk::event_x();
- dragY = ::fltk::event_y();
- return 1;
- }
+ case FL_DRAG:
+ if (dragScrolling && Fl::event_button() == FL_MIDDLE_MOUSE) {
+ scroll(dragX - Fl::event_x(), dragY - Fl::event_y());
+ dragX = Fl::event_x();
+ dragY = Fl::event_y();
+ return 1;
+ } else if (verScrolling) {
+ vscrollbar->handle(event);
+ return 1;
+ } else if (horScrolling) {
+ hscrollbar->handle(event);
+ return 1;
}
break;
- case ::fltk:: MOUSEWHEEL:
- return (event_dx() ? hscrollbar : vscrollbar)->handle(event);
+ case FL_MOUSEWHEEL:
+ return (Fl::event_dx() ? hscrollbar : vscrollbar)->handle(event);
break;
- case ::fltk::RELEASE:
- if (::fltk::event_button() == ::fltk::MiddleButton) {
- dragScrolling = 0;
+ case FL_RELEASE:
+ if (Fl::event_button() == FL_MIDDLE_MOUSE) {
setCursor (core::style::CURSOR_DEFAULT);
+ } else if (verScrolling) {
+ vscrollbar->handle(event);
+ } else if (horScrolling) {
+ hscrollbar->handle(event);
}
+ horScrolling = verScrolling = dragScrolling = 0;
break;
- case ::fltk::ENTER:
+ case FL_ENTER:
/* could be the result of, e.g., closing another window. */
- mouse_x = ::fltk::event_x();
- mouse_y = ::fltk::event_y();
+ mouse_x = Fl::event_x();
+ mouse_y = Fl::event_y();
positionChanged();
break;
- case ::fltk::LEAVE:
+ case FL_LEAVE:
mouse_x = mouse_y = -1;
break;
}
@@ -315,7 +332,7 @@ void FltkViewport::setCanvasSize (int width, int ascent, int descent)
*/
void FltkViewport::positionChanged ()
{
- if (mouse_x != -1)
+ if (mouse_x != -1 && dragScrolling == false)
(void)theLayout->motionNotify (this,
translateViewXToCanvasX (mouse_x),
translateViewYToCanvasY (mouse_y),
@@ -324,7 +341,7 @@ void FltkViewport::positionChanged ()
/*
* For scrollbars, this currently sets the same step to both vertical and
- * horizontal. It may me differentiated if necessary.
+ * horizontal. It may be differentiated if necessary.
*/
void FltkViewport::setScrollStep(int step)
{
@@ -373,7 +390,7 @@ void FltkViewport::scrollTo (int x, int y)
scrollY = y;
adjustScrollbarValues ();
- redraw (DAMAGE_SCROLL);
+ damage(FL_DAMAGE_SCROLL);
theLayout->scrollPosChanged (this, scrollX, scrollY);
positionChanged();
}
@@ -386,9 +403,13 @@ void FltkViewport::scroll (int dx, int dy)
void FltkViewport::scroll (core::ScrollCommand cmd)
{
if (cmd == core::SCREEN_UP_CMD) {
- scroll (0, -vscrollbar->pagesize ());
+ scroll (0, -h () + vscrollbar->linesize ());
} else if (cmd == core::SCREEN_DOWN_CMD) {
- scroll (0, vscrollbar->pagesize ());
+ scroll (0, h () - vscrollbar->linesize ());
+ } else if (cmd == core::SCREEN_LEFT_CMD) {
+ scroll (-w() + hscrollbar->linesize (), 0);
+ } else if (cmd == core::SCREEN_RIGHT_CMD) {
+ scroll (w() - hscrollbar->linesize (), 0);
} else if (cmd == core::LINE_UP_CMD) {
scroll (0, (int) -vscrollbar->linesize ());
} else if (cmd == core::LINE_DOWN_CMD) {
@@ -408,52 +429,59 @@ void FltkViewport::setViewportSize (int width, int height,
int hScrollbarThickness,
int vScrollbarThickness)
{
- if (hScrollbarThickness > 0)
- hscrollbar->show ();
- else
- hscrollbar->hide ();
- if (vScrollbarThickness > 0)
- vscrollbar->show ();
- else
- vscrollbar->hide ();
+ int adjustReq =
+ (hscrollbar->visible() ? !hScrollbarThickness : hScrollbarThickness) ||
+ (vscrollbar->visible() ? !vScrollbarThickness : vScrollbarThickness);
+
+ _MSG("FltkViewport::setViewportSize old_w,old_h=%dx%d -> w,h=%dx%d\n"
+ "\t hThick=%d hVis=%d, vThick=%d vVis=%d, adjustReq=%d\n",
+ w(),h(),width,height,
+ hScrollbarThickness,hscrollbar->visible(),
+ vScrollbarThickness,vscrollbar->visible(), adjustReq);
+
+ (hScrollbarThickness > 0) ? hscrollbar->show () : hscrollbar->hide ();
+ (vScrollbarThickness > 0) ? vscrollbar->show () : vscrollbar->hide ();
/* If no scrollbar, go to the beginning */
scroll(hScrollbarThickness ? 0 : -scrollX,
vScrollbarThickness ? 0 : -scrollY);
+
+ /* Adjust when scrollbar visibility changes */
+ if (adjustReq)
+ adjustScrollbarsAndGadgetsAllocation ();
}
void FltkViewport::updateCanvasWidgets (int dx, int dy)
{
// scroll all child widgets except scroll bars
for (int i = children () - 1; i > 0; i--) {
- ::fltk::Widget *widget = child (i);
+ Fl_Widget *widget = child (i);
if (widget == hscrollbar || widget == vscrollbar)
continue;
- widget->x (widget->x () - dx);
- widget->y (widget->y () - dy);
+ widget->position(widget->x () - dx, widget->y () - dy);
}
}
-int FltkViewport::translateViewXToCanvasX (int x)
+int FltkViewport::translateViewXToCanvasX (int X)
{
- return x + scrollX;
+ return X - x () + scrollX;
}
-int FltkViewport::translateViewYToCanvasY (int y)
+int FltkViewport::translateViewYToCanvasY (int Y)
{
- return y + scrollY;
+ return Y - y () + scrollY;
}
-int FltkViewport::translateCanvasXToViewX (int x)
+int FltkViewport::translateCanvasXToViewX (int X)
{
- return x - scrollX;
+ return X + x () - scrollX;
}
-int FltkViewport::translateCanvasYToViewY (int y)
+int FltkViewport::translateCanvasYToViewY (int Y)
{
- return y - scrollY;
+ return Y + y () - scrollY;
}
// ----------------------------------------------------------------------
@@ -468,11 +496,11 @@ void FltkViewport::setGadgetOrientation (bool hscrollbarVisible,
adjustScrollbarsAndGadgetsAllocation ();
}
-void FltkViewport::addGadget (::fltk::Widget *gadget)
+void FltkViewport::addGadget (Fl_Widget *gadget)
{
/** \bug Reparent? */
- gadgets->append (new TypedPointer < ::fltk::Widget> (gadget));
+ gadgets->append (new TypedPointer < Fl_Widget> (gadget));
adjustScrollbarsAndGadgetsAllocation ();
}
diff --git a/dw/fltkviewport.hh b/dw/fltkviewport.hh
index 1e7f54f6..3df1dccb 100644
--- a/dw/fltkviewport.hh
+++ b/dw/fltkviewport.hh
@@ -1,8 +1,8 @@
#ifndef __DW_FLTKVIEWPORT_HH__
#define __DW_FLTKVIEWPORT_HH__
-#include <fltk/Group.h>
-#include <fltk/Scrollbar.h>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Scrollbar.H>
#include "core.hh"
#include "fltkcore.hh"
@@ -21,12 +21,13 @@ private:
int scrollX, scrollY;
int scrollDX, scrollDY;
- int dragScrolling, dragX, dragY;
+ int hasDragScroll, dragScrolling, dragX, dragY;
+ int horScrolling, verScrolling;
- ::fltk::Scrollbar *vscrollbar, *hscrollbar;
+ Fl_Scrollbar *vscrollbar, *hscrollbar;
GadgetOrientation gadgetOrientation[4];
- lout::container::typed::List <lout::object::TypedPointer < ::fltk::Widget> >
+ lout::container::typed::List <lout::object::TypedPointer < Fl_Widget> >
*gadgets;
void adjustScrollbarsAndGadgetsAllocation ();
@@ -35,11 +36,11 @@ private:
void vscrollbarChanged ();
void positionChanged ();
- static void hscrollbarCallback (Widget *hscrollbar, void *viewportPtr);
- static void vscrollbarCallback (Widget *vscrollbar, void *viewportPtr);
+ static void hscrollbarCallback (Fl_Widget *hscrollbar, void *viewportPtr);
+ static void vscrollbarCallback (Fl_Widget *vscrollbar, void *viewportPtr);
void updateCanvasWidgets (int oldScrollX, int oldScrollY);
- static void draw_area (void *data, const Rectangle& cr);
+ static void draw_area (void *data, int x, int y, int w, int h);
protected:
int translateViewXToCanvasX (int x);
@@ -51,7 +52,7 @@ public:
FltkViewport (int x, int y, int w, int h, const char *label = 0);
~FltkViewport ();
- void layout();
+ void resize(int x, int y, int w, int h);
void draw ();
int handle (int event);
@@ -69,7 +70,8 @@ public:
void setGadgetOrientation (bool hscrollbarVisible, bool vscrollbarVisible,
GadgetOrientation gadgetOrientation);
- void addGadget (::fltk::Widget *gadget);
+ void setDragScroll (bool enable) { hasDragScroll = enable ? 1 : 0; }
+ void addGadget (Fl_Widget *gadget);
};
} // namespace fltk
diff --git a/dw/image.cc b/dw/image.cc
index cab40ed5..1cb9ce39 100644
--- a/dw/image.cc
+++ b/dw/image.cc
@@ -157,7 +157,7 @@ Image::Image(const char *altText)
Image::~Image()
{
if (altText)
- delete altText;
+ free(altText);
if (buffer)
buffer->unref ();
if (mapKey)
@@ -315,8 +315,8 @@ bool Image::buttonPressImpl (core::EventButton *event)
{
bool ret = false;
- currLink = mapList? mapList->link (mapKey, contentX(event),contentY(event)):
- getStyle()->x_link;
+ currLink = mapList ? mapList->link(mapKey,contentX(event),contentY(event)) :
+ getStyle()->x_link;
if (event->button == 3){
(void)layout->emitLinkPress(this, currLink, getStyle()->x_img, -1, -1,
event);
@@ -330,7 +330,7 @@ bool Image::buttonPressImpl (core::EventButton *event)
bool Image::buttonReleaseImpl (core::EventButton *event)
{
- currLink = mapList ? mapList->link (mapKey, contentX(event),contentY(event)):
+ currLink = mapList ? mapList->link(mapKey,contentX(event),contentY(event)) :
getStyle()->x_link;
if (clicking) {
int x = isMap ? contentX(event) : -1;
@@ -384,12 +384,11 @@ void Image::draw (core::View *view, core::Rectangle *area)
getContentHeight());
}
- usedView->drawText (getStyle()->font, getStyle()->color,
+ usedView->drawSimpleWrappedText (getStyle()->font, getStyle()->color,
core::style::Color::SHADING_NORMAL,
allocation.x + getStyle()->boxOffsetX (),
- allocation.y + getStyle()->boxOffsetY ()
- + getStyle()->font->ascent,
- altText, strlen(altText));
+ allocation.y + getStyle()->boxOffsetY (),
+ getContentWidth(), getContentHeight(), altText);
if (clippingView)
view->mergeClippingView (clippingView);
diff --git a/dw/layout.cc b/dw/layout.cc
index 8f67e895..d2610687 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -174,7 +174,7 @@ bool Layout::LinkEmitter::emitClick (Widget *widget, int link, int img,
Layout::Anchor::~Anchor ()
{
- delete name;
+ free(name);
}
// ---------------------------------------------------------------------
@@ -194,6 +194,7 @@ Layout::Layout (Platform *platform)
canvasWidth = canvasAscent = canvasDescent = 0;
usesViewport = false;
+ drawAfterScrollReq = false;
scrollX = scrollY = 0;
viewportWidth = viewportHeight = 0;
hScrollbarThickness = vScrollbarThickness = 0;
@@ -219,14 +220,19 @@ Layout::Layout (Platform *platform)
Layout::~Layout ()
{
+ widgetAtPoint = NULL;
+
if (scrollIdleId != -1)
platform->removeIdle (scrollIdleId);
if (resizeIdleId != -1)
platform->removeIdle (resizeIdleId);
if (bgColor)
bgColor->unref ();
- if (topLevel)
- delete topLevel;
+ if (topLevel) {
+ Widget *w = topLevel;
+ topLevel = NULL;
+ delete w;
+ }
delete platform;
delete view;
delete anchorsTable;
@@ -279,9 +285,12 @@ void Layout::removeWidget ()
void Layout::setWidget (Widget *widget)
{
- if (topLevel)
- delete topLevel;
widgetAtPoint = NULL;
+ if (topLevel) {
+ Widget *w = topLevel;
+ topLevel = NULL;
+ delete w;
+ }
textZone->zoneFree ();
addWidget (widget);
@@ -449,6 +458,10 @@ void Layout::scrollIdle ()
if (xChanged || yChanged) {
adjustScrollPos ();
view->scrollTo (scrollX, scrollY);
+ if (drawAfterScrollReq) {
+ drawAfterScrollReq = false;
+ view->queueDrawTotal ();
+ }
}
scrollIdleId = -1;
@@ -496,7 +509,11 @@ void Layout::draw (View *view, Rectangle *area)
{
Rectangle widgetArea, intersection, widgetDrawArea;
- if (topLevel) {
+ if (scrollIdleId != -1) {
+ /* scroll is pending, defer draw until after scrollIdle() */
+ drawAfterScrollReq = true;
+
+ } else if (topLevel) {
/* Draw the top level widget. */
widgetArea.x = topLevel->allocation.x;
widgetArea.y = topLevel->allocation.y;
@@ -527,7 +544,7 @@ void Layout::setAnchor (const char *anchor)
_MSG("setAnchor (%s)\n", anchor);
if (requestedAnchor)
- delete requestedAnchor;
+ free(requestedAnchor);
requestedAnchor = anchor ? strdup (anchor) : NULL;
updateAnchor ();
}
@@ -672,10 +689,9 @@ void Layout::resizeIdle ()
}
// Set viewport sizes.
- if (view->usesViewport ())
- view->setViewportSize (viewportWidth, viewportHeight,
- actualHScrollbarThickness,
- actualVScrollbarThickness);
+ view->setViewportSize (viewportWidth, viewportHeight,
+ actualHScrollbarThickness,
+ actualVScrollbarThickness);
}
}
@@ -691,7 +707,7 @@ void Layout::setSizeHints ()
if (topLevel) {
topLevel->setWidth (viewportWidth
- (canvasHeightGreater ? vScrollbarThickness : 0));
- topLevel->setAscent (viewportHeight - vScrollbarThickness);
+ topLevel->setAscent (viewportHeight - hScrollbarThickness);
topLevel->setDescent (0);
}
}
@@ -808,6 +824,7 @@ void Layout::enterNotify (View *view, int x, int y, ButtonState state)
*/
void Layout::leaveNotify (View *view, ButtonState state)
{
+#if 0
Widget *lastWidget;
EventCrossing event;
@@ -820,6 +837,9 @@ void Layout::leaveNotify (View *view, ButtonState state)
event.currentWidget = widgetAtPoint;
lastWidget->leaveNotify (&event);
}
+#else
+ moveOutOfView (state);
+#endif
}
/*
@@ -838,15 +858,16 @@ Widget *Layout::getWidgetAtPoint (int x, int y)
/*
* Emit the necessary crossing events, when the mouse pointer has moved to
- * the given widget.
+ * the given widget (by mouse or scrolling).
*/
void Layout::moveToWidget (Widget *newWidgetAtPoint, ButtonState state)
{
Widget *ancestor, *w;
Widget **track;
- int trackLen, i;
+ int trackLen, i, i_a;
EventCrossing crossingEvent;
+ _MSG("moveToWidget: wap=%p nwap=%p\n",widgetAtPoint,newWidgetAtPoint);
if (newWidgetAtPoint != widgetAtPoint) {
// The mouse pointer has been moved into another widget.
if (newWidgetAtPoint && widgetAtPoint)
@@ -875,6 +896,7 @@ void Layout::moveToWidget (Widget *newWidgetAtPoint, ButtonState state)
/* first part */
for (w = widgetAtPoint; w != ancestor; w = w->getParent ())
track[i++] = w;
+ i_a = i;
track[i++] = ancestor;
if (newWidgetAtPoint) {
/* second part */
@@ -882,17 +904,32 @@ void Layout::moveToWidget (Widget *newWidgetAtPoint, ButtonState state)
for (w = newWidgetAtPoint; w != ancestor; w = w->getParent ())
track[i--] = w;
}
-
- /* Send events to all events on the track */
+#if 0
+ MSG("Track: %s[ ", widgetAtPoint ? "" : "nil ");
+ for (i = 0; i < trackLen; i++)
+ MSG("%s%p ", i == i_a ? ">" : "", track[i]);
+ MSG("] %s\n", newWidgetAtPoint ? "" : "nil");
+#endif
+
+ /* Send events to the widgets on the track */
for (i = 0; i < trackLen; i++) {
crossingEvent.state = state;
crossingEvent.currentWidget = widgetAtPoint; // ???
crossingEvent.lastWidget = widgetAtPoint; // ???
-
- if (i != 0)
- track[i]->enterNotify (&crossingEvent);
- if (i != trackLen - 1)
+ if (i < i_a) {
track[i]->leaveNotify (&crossingEvent);
+ } else if (i == i_a) { /* ancestor */
+ /* Don't touch ancestor unless:
+ * - moving into/from NULL,
+ * - ancestor becomes the newWidgetAtPoint */
+ if (i_a == trackLen-1 && !newWidgetAtPoint)
+ track[i]->leaveNotify (&crossingEvent);
+ else if ((i_a == 0 && !widgetAtPoint) ||
+ (i_a == trackLen-1 && newWidgetAtPoint))
+ track[i]->enterNotify (&crossingEvent);
+ } else {
+ track[i]->enterNotify (&crossingEvent);
+ }
}
delete[] track;
diff --git a/dw/layout.hh b/dw/layout.hh
index dc9bf227..d08eb363 100644
--- a/dw/layout.hh
+++ b/dw/layout.hh
@@ -138,7 +138,7 @@ private:
style::Cursor cursor;
int canvasWidth, canvasAscent, canvasDescent;
- bool usesViewport;
+ bool usesViewport, drawAfterScrollReq;
int scrollX, scrollY, viewportWidth, viewportHeight;
bool canvasHeightGreater;
int hScrollbarThickness, vScrollbarThickness;
@@ -152,7 +152,8 @@ private:
bool scrollIdleNotInterrupted;
/* Anchors of the widget tree */
- lout::container::typed::HashTable <lout::object::String, Anchor> *anchorsTable;
+ lout::container::typed::HashTable <lout::object::String, Anchor>
+ *anchorsTable;
SelectionState selectionState;
FindtextState findtextState;
@@ -336,6 +337,11 @@ public:
return platform->createTooltip (text);
}
+ inline void cancelTooltip ()
+ {
+ return platform->cancelTooltip ();
+ }
+
inline Imgbuf *createImgbuf (Imgbuf::Type type, int width, int height)
{
return platform->createImgbuf (type, width, height);
diff --git a/dw/platform.hh b/dw/platform.hh
index 69d1feab..b79b5346 100644
--- a/dw/platform.hh
+++ b/dw/platform.hh
@@ -131,6 +131,11 @@ public:
*/
virtual style::Tooltip *createTooltip (const char *text) = 0;
+ /**
+ * \brief Cancel a tooltip (either shown or requested)
+ */
+ virtual void cancelTooltip () = 0;
+
/*
* --------------------
* Image Buffers
diff --git a/dw/selection.cc b/dw/selection.cc
index 275eddaa..1552e80e 100644
--- a/dw/selection.cc
+++ b/dw/selection.cc
@@ -60,17 +60,6 @@ SelectionState::~SelectionState ()
reset ();
}
-
-bool SelectionState::DoubleClickEmitter::emitToReceiver (lout::signal::Receiver
- *receiver,
- int signalNo,
- int argc,
- Object **argv)
-{
- ((DoubleClickReceiver*)receiver)->doubleClick ();
- return false;
-}
-
void SelectionState::reset ()
{
resetSelection ();
@@ -98,81 +87,64 @@ void SelectionState::resetLink ()
}
bool SelectionState::buttonPress (Iterator *it, int charPos, int linkNo,
- EventButton *event, bool withinContent)
+ EventButton *event)
{
Widget *itWidget = it->getWidget ();
bool ret = false;
- if (event && event->button == 1 &&
- !withinContent && event->numPressed == 2) {
- // When the user double-clicks on empty parts, emit the double click
- // signal instead of normal processing. Used for full screen
- // mode.
- doubleClickEmitter.emitDoubleClick ();
- // Reset everything, so that dw::core::Selection::buttonRelease will
- // ignore the "release" event following soon.
- highlight (false, 0);
- reset ();
+ if (!event) return ret;
+
+ if (event->button == 3) {
+ // menu popup
+ layout->emitLinkPress (itWidget, linkNo, -1, -1, -1, event);
ret = true;
- } else {
- if (linkNo != -1) {
- // link handling
- if (event) {
- (void) layout->emitLinkPress (itWidget, linkNo, -1, -1, -1, event);
- resetLink ();
- linkState = LINK_PRESSED;
- linkButton = event->button;
- DeepIterator *newLink = new DeepIterator (it);
- if (newLink->isEmpty ()) {
- delete newLink;
- resetLink ();
- } else {
- link = newLink;
- // It may be that the user has pressed on something activatable
- // (linkNo != -1), but there is no contents, e.g. with images
- // without ALTernative text.
- if (link) {
- linkChar = correctCharPos (link, charPos);
- linkNumber = linkNo;
- }
- }
- // We do not return the value of the signal method,
- // but we do actually process this event.
- ret = true;
- }
+ } else if (linkNo != -1) {
+ // link handling
+ (void) layout->emitLinkPress (itWidget, linkNo, -1, -1, -1, event);
+ resetLink ();
+ linkState = LINK_PRESSED;
+ linkButton = event->button;
+ DeepIterator *newLink = new DeepIterator (it);
+ if (newLink->isEmpty ()) {
+ delete newLink;
+ resetLink ();
} else {
- // normal selection handling
- if (event && event->button == 1) {
- highlight (false, 0);
- resetSelection ();
-
- selectionState = SELECTING;
- DeepIterator *newFrom = new DeepIterator (it);
- if (newFrom->isEmpty ()) {
- delete newFrom;
- resetSelection ();
- } else {
- from = newFrom;
- fromChar = correctCharPos (from, charPos);
- to = from->cloneDeepIterator ();
- toChar = correctCharPos (to, charPos);
- }
- ret = true;
- } else {
- if (event && event->button == 3) {
- // menu popup
- layout->emitLinkPress (itWidget, -1, -1, -1, -1, event);
- ret = true;
- }
+ link = newLink;
+ // It may be that the user has pressed on something activatable
+ // (linkNo != -1), but there is no contents, e.g. with images
+ // without ALTernative text.
+ if (link) {
+ linkChar = correctCharPos (link, charPos);
+ linkNumber = linkNo;
}
}
+ // We do not return the value of the signal method,
+ // but we do actually process this event.
+ ret = true;
+ } else if (event->button == 1) {
+ // normal selection handling
+ highlight (false, 0);
+ resetSelection ();
+
+ selectionState = SELECTING;
+ DeepIterator *newFrom = new DeepIterator (it);
+ if (newFrom->isEmpty ()) {
+ delete newFrom;
+ resetSelection ();
+ } else {
+ from = newFrom;
+ fromChar = correctCharPos (from, charPos);
+ to = from->cloneDeepIterator ();
+ toChar = correctCharPos (to, charPos);
+ }
+ ret = true;
}
return ret;
}
bool SelectionState::buttonRelease (Iterator *it, int charPos, int linkNo,
- EventButton *event, bool withinContent)
+ EventButton *event)
{
Widget *itWidget = it->getWidget ();
bool ret = false;
@@ -214,7 +186,7 @@ bool SelectionState::buttonRelease (Iterator *it, int charPos, int linkNo,
}
bool SelectionState::buttonMotion (Iterator *it, int charPos, int linkNo,
- EventMotion *event, bool withinContent)
+ EventMotion *event)
{
if (linkState == LINK_PRESSED) {
//link handling
@@ -238,21 +210,17 @@ bool SelectionState::buttonMotion (Iterator *it, int charPos, int linkNo,
*/
bool SelectionState::handleEvent (EventType eventType, Iterator *it,
int charPos, int linkNo,
- MousePositionEvent *event,
- bool withinContent)
+ MousePositionEvent *event)
{
switch (eventType) {
case BUTTON_PRESS:
- return buttonPress (it, charPos, linkNo, (EventButton*)event,
- withinContent);
+ return buttonPress (it, charPos, linkNo, (EventButton*)event);
case BUTTON_RELEASE:
- return buttonRelease (it, charPos, linkNo, (EventButton*)event,
- withinContent);
+ return buttonRelease (it, charPos, linkNo, (EventButton*)event);
case BUTTON_MOTION:
- return buttonMotion (it, charPos, linkNo, (EventMotion*)event,
- withinContent);
+ return buttonMotion (it, charPos, linkNo, (EventMotion*)event);
default:
@@ -334,7 +302,7 @@ void SelectionState::adjustSelection (Iterator *it, int charPos)
}
} else {
if (cmpOld * cmpDiff < 0) {
- // The user has reduced the selection. Unighlight the difference.
+ // The user has reduced the selection. Unhighlight the difference.
highlight0 (false, to, 0, newTo, 0, cmpDiff);
}
diff --git a/dw/selection.hh b/dw/selection.hh
index ba03fd18..7f6b1a58 100644
--- a/dw/selection.hh
+++ b/dw/selection.hh
@@ -44,10 +44,6 @@ namespace core {
* otherwise -1
* <tr><td>dw::core::EventButton *event <td>the event itself; only the button
* is used
- * <tr><td>bool withinContent <td>true, if there is some selectable
- * content unter the mouse cursor; if
- * set to false, the "full screen"
- * feature is used on double click.
* </table>
*
* Look also at dw::core::SelectionState::handleEvent, which may be useful
@@ -184,31 +180,7 @@ class SelectionState
public:
enum { END_OF_WORD = 1 << 30 };
- class DoubleClickReceiver: public lout::signal::Receiver
- {
- public:
- virtual void doubleClick () = 0;
- };
-
private:
- class DoubleClickEmitter: public lout::signal::Emitter
- {
- private:
- enum { DOUBLE_CLICK };
-
- protected:
- bool emitToReceiver (lout::signal::Receiver *receiver, int signalNo,
- int argc, Object **argv);
-
- public:
- inline void connectDoubleClick (DoubleClickReceiver *receiver)
- { connect (receiver); }
-
- inline void emitDoubleClick () { emitVoid (DOUBLE_CLICK, 0, NULL); }
- };
-
- DoubleClickEmitter doubleClickEmitter;
-
Layout *layout;
// selection
@@ -252,19 +224,15 @@ public:
inline void setLayout (Layout *layout) { this->layout = layout; }
void reset ();
- inline void connectDoubleClick (DoubleClickReceiver *receiver)
- { doubleClickEmitter.connectDoubleClick (receiver); }
-
bool buttonPress (Iterator *it, int charPos, int linkNo,
- EventButton *event, bool withinContent);
+ EventButton *event);
bool buttonRelease (Iterator *it, int charPos, int linkNo,
- EventButton *event, bool withinContent);
+ EventButton *event);
bool buttonMotion (Iterator *it, int charPos, int linkNo,
- EventMotion *event, bool withinContent);
+ EventMotion *event);
bool handleEvent (EventType eventType, Iterator *it, int charPos,
- int linkNo, MousePositionEvent *event,
- bool withinContent);
+ int linkNo, MousePositionEvent *event);
};
} // namespace dw
diff --git a/dw/style.cc b/dw/style.cc
index ae0f4526..4276862a 100644
--- a/dw/style.cc
+++ b/dw/style.cc
@@ -431,7 +431,9 @@ static void drawBorderTop(View *view, Style *style,
int x1, int y1, int x2, int y2)
{
- int points[4][2], d, w;
+ int d, w;
+ Point points[4];
+ const bool filled = true, convex = true;
bool ridge = false, inset = false, dotted = false;
Color::Shading shading = Color::SHADING_NORMAL;
@@ -460,35 +462,38 @@ static void drawBorderTop(View *view, Style *style,
if (style->borderWidth.top == 1) {
view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2);
} else {
- points[0][0] = x1;
- points[1][0] = x2 + 1;
- points[0][1] = points[1][1] = y1;
- points[2][0] = points[1][0] - style->borderWidth.right;
- points[3][0] = x1 + style->borderWidth.left;
- points[2][1] = points[3][1] = points[0][1] + style->borderWidth.top;
- view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ points[0].x = x1;
+ points[1].x = x2 + 1;
+ points[0].y = points[1].y = y1;
+ points[2].x = points[1].x - style->borderWidth.right;
+ points[3].x = x1 + style->borderWidth.left;
+ points[2].y = points[3].y = points[0].y + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.top, shading, filled, convex,
+ points, 4);
}
break;
case BORDER_RIDGE:
ridge = true;
case BORDER_GROOVE:
d = style->borderWidth.top & 1;
- points[0][0] = x1;
- points[1][0] = x2 + 1;
- points[0][1] = points[1][1] = y1;
- points[2][0] = x2 - style->borderWidth.right / 2;
- points[3][0] = x1 + style->borderWidth.left / 2;
- points[2][1] = points[3][1] = y1 + style->borderWidth.top / 2 + d;
+ points[0].x = x1;
+ points[1].x = x2 + 1;
+ points[0].y = points[1].y = y1;
+ points[2].x = x2 - style->borderWidth.right / 2;
+ points[3].x = x1 + style->borderWidth.left / 2;
+ points[2].y = points[3].y = y1 + style->borderWidth.top / 2 + d;
shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
- view->drawPolygon (style->borderColor.top, shading, true, points, 4);
- points[0][0] = x1 + style->borderWidth.left / 2 + d;
- points[1][0] = x2 - style->borderWidth.right / 2 + 1 - d;
- points[0][1] = points[1][1] = y1 + style->borderWidth.top / 2 + d;
- points[2][0] = x2 - style->borderWidth.right + 1 - d;
- points[3][0] = x1 + style->borderWidth.left;
- points[2][1] = points[3][1] = y1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.top, shading, filled, convex,
+ points, 4);
+ points[0].x = x1 + style->borderWidth.left / 2 + d;
+ points[1].x = x2 - style->borderWidth.right / 2 + 1 - d;
+ points[0].y = points[1].y = y1 + style->borderWidth.top / 2 + d;
+ points[2].x = x2 - style->borderWidth.right + 1 - d;
+ points[3].x = x1 + style->borderWidth.left;
+ points[2].y = points[3].y = y1 + style->borderWidth.top;
shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
- view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ view->drawPolygon (style->borderColor.top, shading, filled, convex,
+ points, 4);
break;
case BORDER_DOUBLE:
w = (int) rint(style->borderWidth.top / 3.0);
@@ -499,20 +504,22 @@ static void drawBorderTop(View *view, Style *style,
view->drawLine(style->borderColor.top, shading, x1, y1, x2, y2);
break;
}
- points[0][0] = x1;
- points[1][0] = x2 + 1;
- points[0][1] = points[1][1] = y1;
- points[2][0] = points[1][0] - w_r;
- points[3][0] = points[0][0] + w_l;
- points[2][1] = points[3][1] = points[0][1] + w;
- view->drawPolygon (style->borderColor.top, shading, true, points, 4);
- points[0][0] = x1 + style->borderWidth.left - w_l;
- points[1][0] = x2 + 1 - style->borderWidth.right + w_r;
- points[0][1] = points[1][1] = y1 + w + d;
- points[2][0] = x2 + 1 - style->borderWidth.right;
- points[3][0] = x1 + style->borderWidth.left;
- points[2][1] = points[3][1] = y1 + style->borderWidth.top;
- view->drawPolygon (style->borderColor.top, shading, true, points, 4);
+ points[0].x = x1;
+ points[1].x = x2 + 1;
+ points[0].y = points[1].y = y1;
+ points[2].x = points[1].x - w_r;
+ points[3].x = points[0].x + w_l;
+ points[2].y = points[3].y = points[0].y + w;
+ view->drawPolygon (style->borderColor.top, shading, filled, convex,
+ points, 4);
+ points[0].x = x1 + style->borderWidth.left - w_l;
+ points[1].x = x2 + 1 - style->borderWidth.right + w_r;
+ points[0].y = points[1].y = y1 + w + d;
+ points[2].x = x2 + 1 - style->borderWidth.right;
+ points[3].x = x1 + style->borderWidth.left;
+ points[2].y = points[3].y = y1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.top, shading, filled, convex,
+ points, 4);
break;
}
}
@@ -521,7 +528,9 @@ static void drawBorderBottom(View *view, Style *style,
int x1, int y1, int x2, int y2)
{
- int points[4][2], d, w;
+ int d, w;
+ Point points[4];
+ const bool filled = true, convex = true;
bool ridge = false, inset = false, dotted = false;
Color::Shading shading = Color::SHADING_NORMAL;
@@ -550,13 +559,14 @@ static void drawBorderBottom(View *view, Style *style,
if (style->borderWidth.bottom == 1) { /* 1 pixel line */
view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2);
} else {
- points[0][0] = x1 - 1;
- points[1][0] = x2 + 2;
- points[0][1] = points[1][1] = y1 + 1;
- points[2][0] = points[1][0] - style->borderWidth.right;
- points[3][0] = points[0][0] + style->borderWidth.left;
- points[2][1] = points[3][1] = points[0][1]-style->borderWidth.bottom;
- view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ points[0].x = x1 - 1;
+ points[1].x = x2 + 2;
+ points[0].y = points[1].y = y1 + 1;
+ points[2].x = points[1].x - style->borderWidth.right;
+ points[3].x = points[0].x + style->borderWidth.left;
+ points[2].y = points[3].y = points[0].y-style->borderWidth.bottom;
+ view->drawPolygon (style->borderColor.bottom, shading, filled, convex,
+ points, 4);
}
break;
case BORDER_RIDGE:
@@ -564,23 +574,25 @@ static void drawBorderBottom(View *view, Style *style,
case BORDER_GROOVE:
w = style->borderWidth.bottom;
d = w & 1;
- points[0][0] = x1 - 1;
- points[1][0] = x2 + 2 - d;
- points[0][1] = points[1][1] = y1 + 1;
- points[2][0] = points[1][0] - style->borderWidth.right / 2;
- points[3][0] = points[0][0] + style->borderWidth.left / 2 + d;
- points[2][1] = points[3][1] = points[0][1] - w/2 - d;
+ points[0].x = x1 - 1;
+ points[1].x = x2 + 2 - d;
+ points[0].y = points[1].y = y1 + 1;
+ points[2].x = points[1].x - style->borderWidth.right / 2;
+ points[3].x = points[0].x + style->borderWidth.left / 2 + d;
+ points[2].y = points[3].y = points[0].y - w/2 - d;
shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
- view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ view->drawPolygon (style->borderColor.bottom, shading, filled, convex,
+ points, 4);
// clockwise
- points[0][0] = x1 + style->borderWidth.left - 1;
- points[1][0] = x2 + 1 - style->borderWidth.right + 1;
- points[0][1] = points[1][1] = y1 - w + 1;
- points[2][0] = points[1][0] + style->borderWidth.right / 2;
- points[3][0] = points[0][0] - style->borderWidth.left / 2;
- points[2][1] = points[3][1] = points[0][1] + w/2;
+ points[0].x = x1 + style->borderWidth.left - 1;
+ points[1].x = x2 + 1 - style->borderWidth.right + 1;
+ points[0].y = points[1].y = y1 - w + 1;
+ points[2].x = points[1].x + style->borderWidth.right / 2;
+ points[3].x = points[0].x - style->borderWidth.left / 2;
+ points[2].y = points[3].y = points[0].y + w/2;
shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
- view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ view->drawPolygon (style->borderColor.bottom, shading, filled, convex,
+ points, 4);
break;
case BORDER_DOUBLE:
w = (int) rint(style->borderWidth.bottom / 3.0);
@@ -591,20 +603,22 @@ static void drawBorderBottom(View *view, Style *style,
view->drawLine(style->borderColor.bottom, shading, x1, y1, x2, y2);
break;
}
- points[0][0] = x2 + 2;
- points[1][0] = x1 - 1;
- points[0][1] = points[1][1] = y1 + 1;
- points[2][0] = points[1][0] + w_l;
- points[3][0] = points[0][0] - w_r;
- points[2][1] = points[3][1] = points[0][1] - w;
- view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
- points[0][0] = x2 + 2 - style->borderWidth.right + w_r;
- points[1][0] = x1 - 1 + style->borderWidth.left - w_l;
- points[0][1] = points[1][1] = y1 + 1 - w - d;
- points[2][0] = x1 - 1 + style->borderWidth.left;
- points[3][0] = x2 + 2 - style->borderWidth.right;
- points[2][1] = points[3][1] = y1 + 1 - style->borderWidth.bottom;
- view->drawPolygon (style->borderColor.bottom, shading, true, points, 4);
+ points[0].x = x2 + 2;
+ points[1].x = x1 - 1;
+ points[0].y = points[1].y = y1 + 1;
+ points[2].x = points[1].x + w_l;
+ points[3].x = points[0].x - w_r;
+ points[2].y = points[3].y = points[0].y - w;
+ view->drawPolygon (style->borderColor.bottom, shading, filled, convex,
+ points, 4);
+ points[0].x = x2 + 2 - style->borderWidth.right + w_r;
+ points[1].x = x1 - 1 + style->borderWidth.left - w_l;
+ points[0].y = points[1].y = y1 + 1 - w - d;
+ points[2].x = x1 - 1 + style->borderWidth.left;
+ points[3].x = x2 + 2 - style->borderWidth.right;
+ points[2].y = points[3].y = y1 + 1 - style->borderWidth.bottom;
+ view->drawPolygon (style->borderColor.bottom, shading, filled, convex,
+ points, 4);
break;
}
}
@@ -613,7 +627,9 @@ static void drawBorderLeft(View *view, Style *style,
int x1, int y1, int x2, int y2)
{
- int points[4][2], d, w;
+ int d, w;
+ Point points[4];
+ bool filled = true, convex = true;
bool ridge = false, inset = false, dotted = false;
Color::Shading shading = Color::SHADING_NORMAL;
@@ -641,13 +657,14 @@ static void drawBorderLeft(View *view, Style *style,
if (style->borderWidth.left == 1) { /* 1 pixel line */
view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2);
} else {
- points[0][0] = points[1][0] = x1;
- points[0][1] = y1 - 1;
- points[1][1] = y2 + 1;
- points[2][0] = points[3][0] = points[0][0] + style->borderWidth.left;
- points[2][1] = points[1][1] - style->borderWidth.bottom;
- points[3][1] = points[0][1] + style->borderWidth.top;
- view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ points[0].x = points[1].x = x1;
+ points[0].y = y1 - 1;
+ points[1].y = y2 + 1;
+ points[2].x = points[3].x = points[0].x + style->borderWidth.left;
+ points[2].y = points[1].y - style->borderWidth.bottom;
+ points[3].y = points[0].y + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.left, shading, filled, convex,
+ points, 4);
}
break;
case BORDER_RIDGE:
@@ -655,22 +672,24 @@ static void drawBorderLeft(View *view, Style *style,
case BORDER_GROOVE:
w = style->borderWidth.left;
d = w & 1;
- points[0][0] = points[1][0] = x1;
- points[0][1] = y1;
- points[1][1] = y2;
- points[2][0] = points[3][0] = x1 + w / 2 + d;
- points[2][1] = y2 - style->borderWidth.bottom / 2;
- points[3][1] = y1 + style->borderWidth.top / 2;
+ points[0].x = points[1].x = x1;
+ points[0].y = y1;
+ points[1].y = y2;
+ points[2].x = points[3].x = x1 + w / 2 + d;
+ points[2].y = y2 - style->borderWidth.bottom / 2;
+ points[3].y = y1 + style->borderWidth.top / 2;
shading = (ridge) ? Color::SHADING_LIGHT : Color::SHADING_DARK;
- view->drawPolygon (style->borderColor.left, shading, true, points, 4);
- points[0][0] = points[1][0] = x1 + w / 2 + d;
- points[0][1] = y1 + style->borderWidth.top / 2;
- points[1][1] = y2 - style->borderWidth.bottom / 2;
- points[2][0] = points[3][0] = x1 + w;
- points[2][1] = y2 - style->borderWidth.bottom;
- points[3][1] = y1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.left, shading, filled, convex,
+ points, 4);
+ points[0].x = points[1].x = x1 + w / 2 + d;
+ points[0].y = y1 + style->borderWidth.top / 2;
+ points[1].y = y2 - style->borderWidth.bottom / 2;
+ points[2].x = points[3].x = x1 + w;
+ points[2].y = y2 - style->borderWidth.bottom;
+ points[3].y = y1 + style->borderWidth.top;
shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
- view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ view->drawPolygon (style->borderColor.left, shading, filled, convex,
+ points, 4);
break;
case BORDER_DOUBLE:
w = (int) rint(style->borderWidth.left / 3.0);
@@ -681,20 +700,22 @@ static void drawBorderLeft(View *view, Style *style,
view->drawLine(style->borderColor.left, shading, x1, y1, x2, y2-1);
break;
}
- points[0][0] = points[1][0] = x1;
- points[0][1] = y1 - 1;
- points[1][1] = y2 + 1;
- points[2][0] = points[3][0] = points[0][0] + w;
- points[2][1] = points[1][1] - w_b;
- points[3][1] = points[0][1] + w_t;
- view->drawPolygon (style->borderColor.left, shading, true, points, 4);
- points[0][0] = points[1][0] = x1 + w + d;
- points[0][1] = y1 - 1 + style->borderWidth.top - w_t;
- points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b;
- points[2][0] = points[3][0] = points[0][0] + w;
- points[2][1] = y2 + 1 - style->borderWidth.bottom;
- points[3][1] = y1 - 1 + style->borderWidth.top;
- view->drawPolygon (style->borderColor.left, shading, true, points, 4);
+ points[0].x = points[1].x = x1;
+ points[0].y = y1 - 1;
+ points[1].y = y2 + 1;
+ points[2].x = points[3].x = points[0].x + w;
+ points[2].y = points[1].y - w_b;
+ points[3].y = points[0].y + w_t;
+ view->drawPolygon (style->borderColor.left, shading, filled, convex,
+ points, 4);
+ points[0].x = points[1].x = x1 + w + d;
+ points[0].y = y1 - 1 + style->borderWidth.top - w_t;
+ points[1].y = y2 + 1 - style->borderWidth.bottom + w_b;
+ points[2].x = points[3].x = points[0].x + w;
+ points[2].y = y2 + 1 - style->borderWidth.bottom;
+ points[3].y = y1 - 1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.left, shading, filled, convex,
+ points, 4);
break;
}
}
@@ -703,7 +724,9 @@ static void drawBorderRight(View *view, Style *style,
int x1, int y1, int x2, int y2)
{
- int points[4][2], d, w;
+ int d, w;
+ Point points[4];
+ const bool filled = true, convex = true;
bool ridge = false, inset = false, dotted = false;
Color::Shading shading = Color::SHADING_NORMAL;
@@ -731,13 +754,14 @@ static void drawBorderRight(View *view, Style *style,
if (style->borderWidth.right == 1) { /* 1 pixel line */
view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2);
} else {
- points[0][0] = points[1][0] = x1 + 1;
- points[0][1] = y1 - 1;
- points[1][1] = y2 + 1;
- points[2][0] = points[3][0] = points[0][0]-style->borderWidth.right;
- points[2][1] = points[1][1] - style->borderWidth.bottom;
- points[3][1] = points[0][1] + style->borderWidth.top;
- view->drawPolygon (style->borderColor.right, shading, true,points,4);
+ points[0].x = points[1].x = x1 + 1;
+ points[0].y = y1 - 1;
+ points[1].y = y2 + 1;
+ points[2].x = points[3].x = points[0].x-style->borderWidth.right;
+ points[2].y = points[1].y - style->borderWidth.bottom;
+ points[3].y = points[0].y + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.right, shading, filled, convex,
+ points,4);
}
break;
case BORDER_RIDGE:
@@ -745,22 +769,24 @@ static void drawBorderRight(View *view, Style *style,
case BORDER_GROOVE:
w = style->borderWidth.right;
d = w & 1;
- points[0][0] = points[1][0] = x1 + 1;
- points[0][1] = y1;
- points[1][1] = y2;
- points[2][0] = points[3][0] = points[0][0] - w / 2 - d;
- points[2][1] = y2 - style->borderWidth.bottom / 2;
- points[3][1] = points[0][1] + style->borderWidth.top / 2;
+ points[0].x = points[1].x = x1 + 1;
+ points[0].y = y1;
+ points[1].y = y2;
+ points[2].x = points[3].x = points[0].x - w / 2 - d;
+ points[2].y = y2 - style->borderWidth.bottom / 2;
+ points[3].y = points[0].y + style->borderWidth.top / 2;
shading = (ridge) ? Color::SHADING_DARK : Color::SHADING_LIGHT;
- view->drawPolygon (style->borderColor.right, shading, true, points, 4);
- points[0][0] = points[1][0] = x1 + 1 - w / 2 - d;
- points[0][1] = y1 + style->borderWidth.top / 2;
- points[1][1] = y2 - style->borderWidth.bottom / 2;
- points[2][0] = points[3][0] = x1 + 1 - w;
- points[2][1] = y2 - style->borderWidth.bottom;
- points[3][1] = y1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.right, shading, filled, convex,
+ points, 4);
+ points[0].x = points[1].x = x1 + 1 - w / 2 - d;
+ points[0].y = y1 + style->borderWidth.top / 2;
+ points[1].y = y2 - style->borderWidth.bottom / 2;
+ points[2].x = points[3].x = x1 + 1 - w;
+ points[2].y = y2 - style->borderWidth.bottom;
+ points[3].y = y1 + style->borderWidth.top;
shading = (ridge) ? Color::SHADING_LIGHT: Color::SHADING_DARK;
- view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ view->drawPolygon (style->borderColor.right, shading, filled, convex,
+ points, 4);
break;
case BORDER_DOUBLE:
w = (int) rint(style->borderWidth.right / 3.0);
@@ -771,20 +797,22 @@ static void drawBorderRight(View *view, Style *style,
view->drawLine(style->borderColor.right, shading, x1, y1, x2, y2);
break;
}
- points[0][0] = points[1][0] = x1 + 1;
- points[0][1] = y1 - 1;
- points[1][1] = y2 + 1;
- points[2][0] = points[3][0] = points[0][0] - w;
- points[2][1] = points[1][1] - w_b;
- points[3][1] = points[0][1] + w_t;
- view->drawPolygon (style->borderColor.right, shading, true, points, 4);
- points[0][0] = points[1][0] = x1 + 1 - w - d;
- points[0][1] = y1 - 1 + style->borderWidth.top - w_t;
- points[1][1] = y2 + 1 - style->borderWidth.bottom + w_b;
- points[2][0] = points[3][0] = points[0][0] - w;
- points[2][1] = y2 + 1 - style->borderWidth.bottom;
- points[3][1] = y1 - 1 + style->borderWidth.top;
- view->drawPolygon (style->borderColor.right, shading, true, points, 4);
+ points[0].x = points[1].x = x1 + 1;
+ points[0].y = y1 - 1;
+ points[1].y = y2 + 1;
+ points[2].x = points[3].x = points[0].x - w;
+ points[2].y = points[1].y - w_b;
+ points[3].y = points[0].y + w_t;
+ view->drawPolygon (style->borderColor.right, shading, filled, convex,
+ points, 4);
+ points[0].x = points[1].x = x1 + 1 - w - d;
+ points[0].y = y1 - 1 + style->borderWidth.top - w_t;
+ points[1].y = y2 + 1 - style->borderWidth.bottom + w_b;
+ points[2].x = points[3].x = points[0].x - w;
+ points[2].y = y2 + 1 - style->borderWidth.bottom;
+ points[3].y = y1 - 1 + style->borderWidth.top;
+ view->drawPolygon (style->borderColor.right, shading, filled, convex,
+ points, 4);
break;
}
}
@@ -799,8 +827,7 @@ void drawBorder (View *view, Rectangle *area,
Style *style, bool inverse)
{
/** \todo a lot! */
- Color::Shading dark, light, normal;
- int xb1, yb1, xb2, yb2, xp1, yp1, xp2, yp2;
+ int xb1, yb1, xb2, yb2;
// top left and bottom right point of outer border boundary
xb1 = x + style->margin.left;
@@ -808,15 +835,17 @@ void drawBorder (View *view, Rectangle *area,
xb2 = x + (width > 0 ? width - 1 : 0) - style->margin.right;
yb2 = y + (height > 0 ? height - 1 : 0) - style->margin.bottom;
- // top left and bottom right point of inner border boundary
- xp1 = xb1 + style->borderWidth.left;
- yp1 = yb1 + style->borderWidth.top;
- xp2 = xb2 - style->borderWidth.right;
- yp2 = yb2 - style->borderWidth.bottom;
-
- light = inverse ? Color::SHADING_DARK : Color::SHADING_LIGHT;
- dark = inverse ? Color::SHADING_LIGHT : Color::SHADING_DARK;
- normal = inverse ? Color::SHADING_INVERSE : Color::SHADING_NORMAL;
+ /*
+ // top left and bottom right point of inner border boundary
+ xp1 = xb1 + style->borderWidth.left;
+ yp1 = yb1 + style->borderWidth.top;
+ xp2 = xb2 - style->borderWidth.right;
+ yp2 = yb2 - style->borderWidth.bottom;
+
+ light = inverse ? Color::SHADING_DARK : Color::SHADING_LIGHT;
+ dark = inverse ? Color::SHADING_LIGHT : Color::SHADING_DARK;
+ normal = inverse ? Color::SHADING_INVERSE : Color::SHADING_NORMAL;
+ */
drawBorderRight(view, style, xb2, yb1, xb2, yb2);
drawBorderLeft(view, style, xb1, yb1, xb1, yb2);
diff --git a/dw/table.cc b/dw/table.cc
index 6708b3f0..8a46ce7c 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -320,11 +320,19 @@ void Table::addCell (Widget *widget, int colspan, int rowspan)
for (int col = 0; col < colspanEff; col++)
for (int row = 0; row < rowspan; row++)
if (!(col == 0 && row == 0)) {
+ int i = (curRow + row) * numCols + curCol + col;
+
+ child = children->get(i);
+ if (child) {
+ MSG("Overlapping spans in table.\n");
+ assert(child->type == Child::SPAN_SPACE);
+ delete child;
+ }
child = new Child ();
child->type = Child::SPAN_SPACE;
child->spanSpace.startCol = curCol;
child->spanSpace.startRow = curRow;
- children->set ((curRow + row) * numCols + curCol + col, child);
+ children->set (i, child);
}
// Set the "root" cell.
diff --git a/dw/textblock.cc b/dw/textblock.cc
index fffbac2f..6ded2413 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -26,6 +26,15 @@
#include <math.h> // remove again
#include <limits.h>
+/*
+ * Local variables
+ */
+ /* The tooltip under mouse pointer in current textblock. No ref. hold.
+ * (having one per view looks not worth the extra clutter). */
+static dw::core::style::Tooltip *hoverTooltip = NULL;
+
+
+
using namespace lout;
namespace dw {
@@ -81,8 +90,6 @@ Textblock::Textblock (bool limitTextWidth)
availAscent = 100;
availDescent = 0;
- hoverTooltip = NULL;
-
this->limitTextWidth = limitTextWidth;
for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) {
@@ -96,7 +103,10 @@ Textblock::Textblock (bool limitTextWidth)
Textblock::~Textblock ()
{
- //_MSG ("Textblock::~Textblock\n");
+ _MSG("Textblock::~Textblock\n");
+
+ /* make sure not to call a free'd tooltip (very fast overkill) */
+ hoverTooltip = NULL;
for (int i = 0; i < words->size(); i++) {
Word *word = words->getRef (i);
@@ -372,13 +382,13 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
* http://www.dillo.org/test/img/ */
childAllocation.y =
lineYOffsetCanvasAllocation (line, allocation)
- + (line->boxAscent - word->size.ascent);
- // - word->content.widget->getStyle()->margin.top;
+ + (line->boxAscent - word->size.ascent)
+ - word->content.widget->getStyle()->margin.top;
childAllocation.width = word->size.width;
- childAllocation.ascent = word->size.ascent;
- // + word->content.widget->getStyle()->margin.top;
- childAllocation.descent = word->size.descent;
- // + word->content.widget->getStyle()->margin.bottom;
+ childAllocation.ascent = word->size.ascent
+ + word->content.widget->getStyle()->margin.top;
+ childAllocation.descent = word->size.descent
+ + word->content.widget->getStyle()->margin.bottom;
oldChildAllocation = word->content.widget->getAllocation();
@@ -609,6 +619,11 @@ bool Textblock::buttonReleaseImpl (core::EventButton *event)
return sendSelectionEvent (core::SelectionState::BUTTON_RELEASE, event);
}
+/*
+ * Handle motion inside the widget
+ * (special care is necessary when switching from another widget,
+ * because hoverLink and hoverTooltip are meaningless then).
+ */
bool Textblock::motionNotifyImpl (core::EventMotion *event)
{
if (event->state & core::BUTTON1_MASK)
@@ -630,6 +645,7 @@ bool Textblock::motionNotifyImpl (core::EventMotion *event)
hoverLink = style->x_link;
hoverTooltip = style->x_tooltip;
}
+
// Show/hide tooltip
if (tooltipOld != hoverTooltip) {
if (tooltipOld)
@@ -639,21 +655,32 @@ bool Textblock::motionNotifyImpl (core::EventMotion *event)
} else if (hoverTooltip)
hoverTooltip->onMotion ();
- if (hoverLink != linkOld)
+ _MSG("MN tb=%p tooltipOld=%p hoverTooltip=%p\n",
+ this, tooltipOld, hoverTooltip);
+ if (hoverLink != linkOld) {
+ /* LinkEnter with hoverLink == -1 is the same as LinkLeave */
return layout->emitLinkEnter (this, hoverLink, -1, -1, -1);
- else
+ } else {
return hoverLink != -1;
+ }
}
}
void Textblock::enterNotifyImpl (core::EventCrossing *event)
{
+ _MSG(" tb=%p, ENTER NotifyImpl hoverTooltip=%p\n", this, hoverTooltip);
+ /* reset hoverLink so linkEnter is detected */
+ hoverLink = -2;
}
void Textblock::leaveNotifyImpl (core::EventCrossing *event)
{
- hoverLink = -1;
- (void) layout->emitLinkEnter (this, hoverLink, -1, -1, -1);
+ _MSG(" tb=%p, LEAVE NotifyImpl: hoverTooltip=%p\n", this, hoverTooltip);
+
+ /* leaving the viewport can't be handled by motionNotifyImpl() */
+ if (hoverLink >= 0)
+ layout->emitLinkEnter (this, -1, -1, -1, -1);
+
if (hoverTooltip) {
hoverTooltip->onLeave();
hoverTooltip = NULL;
@@ -671,10 +698,9 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
int nextWordStartX, wordStartX, wordX, nextWordX, yFirst, yLast;
int charPos = 0, link = -1, prevPos, wordIndex, lineIndex;
Word *word;
- bool found, r, withinContent = true;
+ bool found, r;
if (words->size () == 0) {
- withinContent = false;
wordIndex = -1;
} else {
lastLine = lines->getRef (lines->size () - 1);
@@ -683,12 +709,10 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
lastLine->boxDescent;
if (event->yCanvas < yFirst) {
// Above the first line: take the first word.
- withinContent = false;
wordIndex = 0;
charPos = 0;
} else if (event->yCanvas >= yLast) {
// Below the last line: take the last word.
- withinContent = false;
wordIndex = words->size () - 1;
word = words->getRef (wordIndex);
charPos = word->content.type == core::Content::TEXT ?
@@ -701,13 +725,11 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
if (event->yWidget >
(lineYOffsetWidget (line) + line->boxAscent + line->boxDescent)) {
// Choose this break.
- withinContent = false;
wordIndex = line->lastWord;
charPos = 0;
} else if (event->xWidget < lineXOffsetWidget (line)) {
// Left of the first word in the line.
wordIndex = line->firstWord;
- withinContent = false;
charPos = 0;
} else {
nextWordStartX = lineXOffsetWidget (line);
@@ -761,7 +783,6 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
if (!found) {
// No word found in this line (i.e. we are on the right side),
// take the last of this line.
- withinContent = false;
wordIndex = line->lastWord;
if (wordIndex >= words->size ())
wordIndex--;
@@ -775,8 +796,7 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
}
it = new TextblockIterator (this, core::Content::SELECTION_CONTENT,
wordIndex);
- r = selectionHandleEvent (eventType, it, charPos, link, event,
- withinContent);
+ r = selectionHandleEvent (eventType, it, charPos, link, event);
it->unref ();
return r;
}
@@ -1058,29 +1078,29 @@ void Textblock::wordWrap(int wordIndex)
// lastLine->boxDescent);
if (word->content.type == core::Content::WIDGET) {
+ int collapseMarginTop = 0;
+
lastLine->marginDescent =
misc::max (lastLine->marginDescent,
word->size.descent +
word->content.widget->getStyle()->margin.bottom);
- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.descent", page->num_lines - 1,
- // lastLine->descent);
+ if (lines->size () == 1 &&
+ word->content.widget->blockLevel () &&
+ getStyle ()->borderWidth.top == 0 &&
+ getStyle ()->padding.top == 0) {
+ // collapse top margin of parent element with top margin of first child
+ // see: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
+ collapseMarginTop = getStyle ()->margin.top;
+ }
- /* If the widget is not in the first line of the paragraph, its top
- * margin may make the line higher.
- */
- if (lines->size () > 1) {
- /* Here, we know already what the break and the bottom margin
- * contributed to the space before this line.
- */
- lastLine->boxAscent =
+ lastLine->boxAscent =
misc::max (lastLine->boxAscent,
+ word->size.ascent,
word->size.ascent
- + word->content.widget->getStyle()->margin.top);
+ + word->content.widget->getStyle()->margin.top
+ - collapseMarginTop);
- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.ascent", page->num_lines - 1,
- // lastLine->boxAscent);
- }
} else {
lastLine->marginDescent =
misc::max (lastLine->marginDescent, lastLine->boxDescent);
@@ -1197,11 +1217,7 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
widget->setAscent (availAscent);
widget->setDescent (availDescent);
widget->sizeRequest (size);
-// size->ascent -= wstyle->margin.top;
-// size->descent -= wstyle->margin.bottom;
} else {
- /* TODO: Use margin.{top|bottom} here, like above.
- * (No harm for the next future.) */
if (wstyle->width == core::style::LENGTH_AUTO ||
wstyle->height == core::style::LENGTH_AUTO)
widget->sizeRequest (&requisition);
@@ -1232,6 +1248,10 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
size->descent = (int) (len * availDescent);
}
}
+
+ /* ascent and descent in words do not contain margins. */
+ size->ascent -= wstyle->margin.top;
+ size->descent -= wstyle->margin.bottom;
}
/**
@@ -1499,11 +1519,6 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
word->content.type == core::Content::WIDGET) {
if (word->size.width > 0) {
- if (word->style->hasBackground ()) {
- drawBox (view, word->style, area, xWidget,
- yWidgetBase - line->boxAscent, word->size.width,
- line->boxAscent + line->boxDescent, false);
- }
if (word->content.type == core::Content::WIDGET) {
core::Widget *child = word->content.widget;
core::Rectangle childArea;
@@ -1511,6 +1526,11 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
if (child->intersects (area, &childArea))
child->draw (view, &childArea);
} else {
+ if (word->style->hasBackground ()) {
+ drawBox (view, word->style, area, xWidget,
+ yWidgetBase - line->boxAscent, word->size.width,
+ line->boxAscent + line->boxDescent, false);
+ }
drawText(wordIndex, view, area, xWidget, yWidgetBase);
}
}
diff --git a/dw/textblock.hh b/dw/textblock.hh
index baa5e29a..ea7795b8 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -315,9 +315,7 @@ protected:
struct {int index, nChar;}
hlStart[core::HIGHLIGHT_NUM_LAYERS], hlEnd[core::HIGHLIGHT_NUM_LAYERS];
- int hoverLink; /* The link under the button. */
- core::style::Tooltip *hoverTooltip; /* The tooltip under the button. No ref
- * hold. */
+ int hoverLink; /* The link under the mouse pointer */
void queueDrawRange (int index1, int index2);
diff --git a/dw/types.cc b/dw/types.cc
index 4d94f494..074cb352 100644
--- a/dw/types.cc
+++ b/dw/types.cc
@@ -140,16 +140,15 @@ void Polygon::draw (core::View *view, core::style::Style *style, int x, int y)
{
if (points->size()) {
int i;
- const bool filled = false;
- int (*pointArray)[2] =
- (int (*)[2]) malloc(points->size() * sizeof(*pointArray));
+ const bool filled = false, convex = false;
+ Point *pointArray = (Point *)malloc(points->size()*sizeof(struct Point));
for (i = 0; i < points->size(); i++) {
- pointArray[i][0] = x + points->getRef(i)->x;
- pointArray[i][1] = y + points->getRef(i)->y;
+ pointArray[i].x = x + points->getRef(i)->x;
+ pointArray[i].y = y + points->getRef(i)->y;
}
view->drawPolygon(style->color, core::style::Color::SHADING_NORMAL,
- filled, pointArray, i);
+ filled, convex, pointArray, i);
free(pointArray);
}
}
diff --git a/dw/types.hh b/dw/types.hh
index 420a500f..b5204331 100644
--- a/dw/types.hh
+++ b/dw/types.hh
@@ -32,7 +32,8 @@ enum VPosition
VPOS_NO_CHANGE
};
-enum ScrollCommand {SCREEN_UP_CMD, SCREEN_DOWN_CMD, LINE_UP_CMD, LINE_DOWN_CMD,
+enum ScrollCommand {SCREEN_UP_CMD, SCREEN_DOWN_CMD, SCREEN_LEFT_CMD,
+ SCREEN_RIGHT_CMD, LINE_UP_CMD, LINE_DOWN_CMD,
LEFT_CMD, RIGHT_CMD, TOP_CMD, BOTTOM_CMD};
/*
diff --git a/dw/ui.cc b/dw/ui.cc
index 5d5d2bf6..35d63f6c 100644
--- a/dw/ui.cc
+++ b/dw/ui.cc
@@ -266,9 +266,9 @@ void ComplexButtonResource::LayoutReceiver::canvasSizeChanged (int width,
int descent)
{
/**
- * \todo The argument to queueResize is not always true. (But this works.)
+ * \todo Verify that this is correct.
*/
- resource->queueResize (true);
+ resource->queueResize (resource->childWidget->extremesChanged ());
}
ComplexButtonResource::ComplexButtonResource ()
diff --git a/dw/ui.hh b/dw/ui.hh
index b0a22cbf..0873217f 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -421,12 +421,10 @@ class SelectionResource: public Resource
{
public:
virtual void addItem (const char *str, bool enabled, bool selected) = 0;
-
virtual void pushGroup (const char *name, bool enabled) = 0;
virtual void popGroup () = 0;
virtual int getNumberOfItems () = 0;
- virtual const char *getItem (int index) = 0;
virtual bool isSelected (int index) = 0;
};
diff --git a/dw/view.hh b/dw/view.hh
index 08853323..da9bdce4 100644
--- a/dw/view.hh
+++ b/dw/view.hh
@@ -92,12 +92,6 @@ public:
* This will normally imply a resize of the UI widget. Width and height are
* the dimensions of the new size, \em including the scrollbar thicknesses.
*
- * \bug The rest of this comment needs to be updated.
- *
- * markerWidthDiff and markerHeightDiff are the respective dimensions of
- * the viewport markers (see dw::core::getMarkerWidthDiff and
- * dw::core::getMarkerHeightDiff), if they are 0, the respective
- * marker should not be shown at all.
*/
virtual void setViewportSize (int width, int height,
int hScrollbarThickness,
@@ -179,12 +173,16 @@ public:
int angle1, int angle2) = 0;
virtual void drawPolygon (style::Color *color,
style::Color::Shading shading,
- bool filled, int points[][2], int npoints) = 0;
+ bool filled, bool convex, Point *points,
+ int npoints) = 0;
virtual void drawText (style::Font *font,
style::Color *color,
style::Color::Shading shading,
int x, int y, const char *text, int len) = 0;
-
+ virtual void drawSimpleWrappedText (style::Font *font, style::Color *color,
+ style::Color::Shading shading,
+ int x, int y, int w, int h,
+ const char *text) = 0;
virtual void drawImage (Imgbuf *imgbuf, int xRoot, int yRoot,
int x, int y, int width, int height) = 0;
diff --git a/dw/widget.hh b/dw/widget.hh
index 3034b982..e18344c7 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -206,25 +206,21 @@ protected:
inline bool selectionButtonPress (Iterator *it, int charPos, int linkNo,
EventButton *event, bool withinContent)
- { return layout->selectionState.buttonPress (it, charPos, linkNo, event,
- withinContent); }
+ { return layout->selectionState.buttonPress (it, charPos, linkNo, event); }
inline bool selectionButtonRelease (Iterator *it, int charPos, int linkNo,
EventButton *event, bool withinContent)
- { return layout->selectionState.buttonRelease (it, charPos, linkNo, event,
- withinContent); }
+ { return layout->selectionState.buttonRelease (it, charPos, linkNo, event);}
inline bool selectionButtonMotion (Iterator *it, int charPos, int linkNo,
EventMotion *event, bool withinContent)
- { return layout->selectionState.buttonMotion (it, charPos, linkNo, event,
- withinContent); }
+ { return layout->selectionState.buttonMotion (it, charPos, linkNo, event); }
inline bool selectionHandleEvent (SelectionState::EventType eventType,
Iterator *it, int charPos, int linkNo,
- MousePositionEvent *event,
- bool withinContent)
+ MousePositionEvent *event)
{ return layout->selectionState.handleEvent (eventType, it, charPos, linkNo,
- event, withinContent); }
+ event); }
private:
void *deleteCallbackData;