diff options
author | Sebastian Geerken <devnull@localhost> | 2012-11-02 18:48:01 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2012-11-02 18:48:01 +0100 |
commit | 163ea78f0fe31ed999d94407c780af7efa520b68 (patch) | |
tree | 0f9f5b7e29b830f06ee6217883dcd57d530a2899 | |
parent | 76cf4173b653db09c3bacbb0d01c1e153e52eac4 (diff) | |
parent | ec742a77c99526479fe57afc5fbbdf860fed4003 (diff) |
Merge.
-rw-r--r-- | dw/fltkui.cc | 49 | ||||
-rw-r--r-- | dw/textblock.cc | 40 | ||||
-rw-r--r-- | dw/textblock.hh | 16 |
3 files changed, 77 insertions, 28 deletions
diff --git a/dw/fltkui.cc b/dw/fltkui.cc index 7d2f6cc5..5e4f3c56 100644 --- a/dw/fltkui.cc +++ b/dw/fltkui.cc @@ -75,6 +75,49 @@ int CustInput2::handle(int e) return Fl_Input::handle(e); } + +/* + * Used to handle some keystrokes as shortcuts to option menuitems + * (i.e. jump to the next menuitem whose label starts with the pressed key) + */ +class CustChoice : public Fl_Choice { +public: + CustChoice (int x, int y, int w, int h, const char* l=0) : + Fl_Choice(x,y,w,h,l) {}; + int handle(int e); +}; + +int CustChoice::handle(int e) +{ + int k = Fl::event_key(); + unsigned modifier = Fl::event_state() & (FL_SHIFT|FL_CTRL|FL_ALT|FL_META); + + _MSG("CustChoice::handle %p e=%d active=%d focus=%d\n", + this, e, active(), (Fl::focus() == this)); + if (Fl::focus() != this) { + ; // Not Focused, let FLTK handle it + } else if (e == FL_KEYDOWN) { + if (modifier == 0 && isalnum(k)) { + int t = value()+1 >= size() ? 0 : value()+1; + while (t != value()) { + const Fl_Menu_Item *mi = &(menu()[t]); + if (mi->submenu()) // submenu? + ; + else if (mi->label() && mi->active()) { // menu item? + if (k == tolower(mi->label()[0])) { + value(mi); + return 1; // Let FLTK know we used this key + } + } + if (++t == size()) + t = 0; + } + } + } + + return Fl_Choice::handle(e); +} + //---------------------------------------------------------------------------- namespace dw { @@ -995,9 +1038,9 @@ Fl_Widget *FltkOptionMenuResource::createNewWidget (core::Allocation *allocation) { Fl_Choice *choice = - new Fl_Choice (allocation->x, allocation->y, - allocation->width, - allocation->ascent + allocation->descent); + new CustChoice (allocation->x, allocation->y, + allocation->width, + allocation->ascent + allocation->descent); choice->menu(menu); return choice; } diff --git a/dw/textblock.cc b/dw/textblock.cc index 31493c15..0c291e1f 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -1791,22 +1791,9 @@ void Textblock::fillSpace (Word *word, core::style::Style *style) // TODO: This line does not work: addBreakOption (word, style); + // Do not override a previously set break penalty. if (!word->content.space) { - // Do not override a previously set break penalty. - if (!word->badnessAndPenalty.lineMustBeBroken()) { - switch (style->whiteSpace) { - case core::style::WHITE_SPACE_NORMAL: - case core::style::WHITE_SPACE_PRE_LINE: - word->badnessAndPenalty.setPenalty (0); - break; - - case core::style::WHITE_SPACE_PRE: - case core::style::WHITE_SPACE_NOWRAP: - case core::style::WHITE_SPACE_PRE_WRAP: - word->badnessAndPenalty.setPenaltyProhibitBreak (); - break; - } - } + setBreakOption (word, style); word->content.space = true; word->effSpace = word->origSpace = style->font->spaceWidth + @@ -1830,6 +1817,29 @@ void Textblock::fillSpace (Word *word, core::style::Style *style) } } +/** + * Set a break option, if allowed by the style. Called by fillSpace + * (and so addSpace), but may be called, via addBreakOption(), as an + * alternative, e. g. for ideographic characters. + */ +void Textblock::setBreakOption (Word *word, core::style::Style *style) +{ + if (!word->badnessAndPenalty.lineMustBeBroken()) { + switch (style->whiteSpace) { + case core::style::WHITE_SPACE_NORMAL: + case core::style::WHITE_SPACE_PRE_LINE: + word->badnessAndPenalty.setPenalty (0); + break; + + case core::style::WHITE_SPACE_PRE: + case core::style::WHITE_SPACE_NOWRAP: + case core::style::WHITE_SPACE_PRE_WRAP: + word->badnessAndPenalty.setPenaltyProhibitBreak (); + break; + } + } +} + void Textblock::addHyphen () { int wordIndex = words->size () - 1; diff --git a/dw/textblock.hh b/dw/textblock.hh index 70759079..ccc209c5 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -424,6 +424,7 @@ protected: void fillWord (Word *word, int width, int ascent, int descent, bool canBeHyphenated, core::style::Style *style); void fillSpace (Word *word, core::style::Style *style); + void setBreakOption (Word *word, core::style::Style *style); int textWidth (const char *text, int start, int len, core::style::Style *style); void calcTextSize (const char *text, size_t len, core::style::Style *style, @@ -621,20 +622,15 @@ public: bool addAnchor (const char *name, core::style::Style *style); void addSpace (core::style::Style *style); + /** + * Add a break option (see setBreakOption() for details). Used + * instead of addStyle for ideographic characters. + */ inline void addBreakOption (core::style::Style *style) { int wordIndex = words->size () - 1; if (wordIndex >= 0) - addBreakOption (words->getRef(wordIndex), style); - } - - // TODO Re-evaluate again. When needed, which penalty values, etc. - inline void addBreakOption (Word *word, core::style::Style *style) - { - if (style->whiteSpace != core::style::WHITE_SPACE_NOWRAP && - style->whiteSpace != core::style::WHITE_SPACE_PRE) - if (word->badnessAndPenalty.lineMustBeBroken()) - word->badnessAndPenalty.setPenalty (0); + setBreakOption (words->getRef(wordIndex), style); } void addHyphen(); |