I promised you all something more substantial than whitespace and comment fixes next, didn't I? This patch implements the dw::fltk::ui::FltkMultiLineTextResource class, using ::fltk:LMultiLineInput to create the widget. It also adds a FltkMultiLineTextResource to the dw-ui-test example. This isn't complete yet; the number of rows and columns are hardwired. Comments are welcome. Regards, Jeremy Henty diff -pru -- dw2-ref/dw/fltkplatform.cc dw2-cur/dw/fltkplatform.cc --- dw2-ref/dw/fltkplatform.cc 2007-12-06 17:29:59.000000000 +0000 +++ dw2-cur/dw/fltkplatform.cc 2007-12-15 01:41:02.000000000 +0000 @@ -144,8 +144,7 @@ FltkPlatform::FltkResourceFactory::creat core::ui::MultiLineTextResource * FltkPlatform::FltkResourceFactory::createMultiLineTextResource () { - /** \bug Not implemented. */ - return NULL; + return new ui::FltkMultiLineTextResource (platform); } core::ui::CheckButtonResource * diff -pru -- dw2-ref/dw/fltkui.cc dw2-cur/dw/fltkui.cc --- dw2-ref/dw/fltkui.cc 2007-12-06 17:29:59.000000000 +0000 +++ dw2-cur/dw/fltkui.cc 2007-12-15 02:34:13.000000000 +0000 @@ -30,6 +30,7 @@ #include <fltk/Group.h> #include <fltk/Input.h> #include <fltk/SecretInput.h> +#include <fltk/MultiLineInput.h> #include <fltk/RadioButton.h> #include <fltk/CheckButton.h> #include <fltk/Choice.h> @@ -527,6 +528,107 @@ void FltkEntryResource::setEditable (boo // ---------------------------------------------------------------------- +FltkMultiLineTextResource::FltkMultiLineTextResource (FltkPlatform *platform): + FltkSpecificResource <dw::core::ui::MultiLineTextResource> (platform) +{ + initText = NULL; + editable = false; + + init (platform); +} + +FltkMultiLineTextResource::~FltkMultiLineTextResource () +{ + if (initText) + delete initText; +} + +::fltk::Widget *FltkMultiLineTextResource::createNewWidget (core::Allocation + *allocation) +{ + ::fltk::MultiLineInput *input = + new ::fltk::MultiLineInput (allocation->x, allocation->y, + allocation->width, + allocation->ascent + allocation->descent); + input->callback (widgetCallback, this); + input->when (::fltk::WHEN_ENTER_KEY_ALWAYS); + + if (viewsAndWidgets->isEmpty ()) { + // First widget created, attach the set text. + if (initText) + input->value (initText); + } else + input->value + (((::fltk::MultiLineInput*)viewsAndWidgets->getFirst()->widget)->value ()); + + return input; +} + +void FltkMultiLineTextResource::sizeRequest (core::Requisition *requisition) +{ + if (style) { + FltkFont *font = (FltkFont*)style->font; + requisition->width = + (int)::fltk::getwidth ("M", 1) * 20 + + 2 * RELIEF_X_THICKNESS; + requisition->ascent = RELIEF_Y_THICKNESS; + requisition->descent = + (font->ascent + font->descent) * 10 + RELIEF_Y_THICKNESS; + } else { + requisition->width = 1; + requisition->ascent = 1; + requisition->descent = 0; + } +} + +void FltkMultiLineTextResource::widgetCallback (::fltk::Widget *widget, + void *data) +{ + /* 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 + */ + printf ("when = %d\n", widget->when ()); + if ((widget->when () & ::fltk::WHEN_ENTER_KEY_ALWAYS) && + (::fltk::event_key() == ::fltk::ReturnKey)) + ((FltkMultiLineTextResource*)data)->emitActivate (); +} + +const char *FltkMultiLineTextResource::getText () +{ + if (viewsAndWidgets->isEmpty ()) + return initText; + else + return ((::fltk::MultiLineInput*)viewsAndWidgets->getFirst()->widget)->value (); +} + +void FltkMultiLineTextResource::setText (const char *text) +{ + if (initText) + delete initText; + initText = strdup (text); + + for (Iterator <ViewAndWidget> it = viewsAndWidgets->iterator (); + it.hasNext(); ) { + ViewAndWidget *viewAndWidget = it.getNext (); + ((::fltk::MultiLineInput*)viewAndWidget->widget)->value (initText); + } +} + +bool FltkMultiLineTextResource::isEditable () +{ + return editable; +} + +void FltkMultiLineTextResource::setEditable (bool editable) +{ + this->editable = editable; +} + +// ---------------------------------------------------------------------- + template <class I> FltkToggleButtonResource<I>::FltkToggleButtonResource (FltkPlatform *platform, bool activated): diff -pru -- dw2-ref/dw/fltkui.hh dw2-cur/dw/fltkui.hh --- dw2-ref/dw/fltkui.hh 2007-10-06 23:03:01.000000000 +0100 +++ dw2-cur/dw/fltkui.hh 2007-12-15 01:28:53.000000000 +0000 @@ -313,6 +313,31 @@ public: }; +class FltkMultiLineTextResource: + public FltkSpecificResource <dw::core::ui::MultiLineTextResource> +{ +private: + const char *initText; + bool editable; + + static void widgetCallback (::fltk::Widget *widget, void *data); + +protected: + ::fltk::Widget *createNewWidget (core::Allocation *allocation); + +public: + FltkMultiLineTextResource (FltkPlatform *platform); + ~FltkMultiLineTextResource (); + + void sizeRequest (core::Requisition *requisition); + + const char *getText (); + void setText (const char *text); + bool isEditable (); + void setEditable (bool editable); +}; + + template <class I> class FltkToggleButtonResource: public FltkSpecificResource <I> { diff -pru -- dw2-ref/test/dw_ui_test.cc dw2-cur/test/dw_ui_test.cc --- dw2-ref/test/dw_ui_test.cc 2007-10-06 23:03:01.000000000 +0100 +++ dw2-cur/test/dw_ui_test.cc 2007-12-15 02:35:22.000000000 +0000 @@ -44,10 +44,10 @@ int main(int argc, char **argv) FltkPlatform *platform = new FltkPlatform (); Layout *layout = new Layout (platform); - ::fltk::Window *window = new ::fltk::Window(300, 300, "Dw UI Test"); + ::fltk::Window *window = new ::fltk::Window(400, 400, "Dw UI Test"); window->begin(); - FltkViewport *viewport = new FltkViewport (0, 0, 300, 300); + FltkViewport *viewport = new FltkViewport (0, 0, 400, 400); layout->attachView (viewport); StyleAttrs styleAttrs; @@ -83,6 +83,8 @@ int main(int argc, char **argv) entryres1->setText ("Hi!"); EntryResource *entryres2 = layout->getResourceFactory()->createEntryResource (10, true); + MultiLineTextResource *textres = + layout->getResourceFactory()->createMultiLineTextResource (); RadioButtonResource *radiores1 = layout->getResourceFactory()->createRadioButtonResource (NULL, false); RadioButtonResource *radiores2 = @@ -115,6 +117,7 @@ int main(int argc, char **argv) form::Form *form = new form::Form(); form->addTextResource ("val1", entryres1); form->addTextResource ("val2", entryres2); + form->addTextResource ("text", textres); const char *radiovalues[] = { "radio1", "radio2", NULL }; form->addRadioButtonResource ("val3", radiores1, radiovalues); form->addCheckButtonResource ("check", checkres); @@ -151,6 +154,19 @@ int main(int argc, char **argv) table->addCell (input2, 1, 1); table->addRow (cellStyle); + + Textblock *label = new Textblock(false); + label->setStyle (cellStyle); + table->addCell (label, 1, 1); + label->addText (strdup ("text = "), cellStyle); + label->flush (); + + Embed *text = new Embed (textres); + text->setStyle (cellStyle); + table->addCell (text, 1, 1); + + table->addRow (cellStyle); + Textblock *radiolabel1 = new Textblock(false); radiolabel1->setStyle (cellStyle); table->addCell (radiolabel1, 2, 1);