From 212172f522ed1d3a119fbc9f63d4b5367c2526cc Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 3 Dec 2017 21:06:21 +0100 Subject: [PATCH] Refactoring FListBox::drawList and FListBox::onKeyPress --- ChangeLog | 4 + include/final/flistbox.h | 20 + include/final/flistview.h | 7 + include/final/foptiattr.h | 21 + include/final/fvterm.h | 2 + include/final/fwidget.h | 2 + src/flistbox.cpp | 1065 +++++++++++++++++++++---------------- src/flistview.cpp | 279 ++++++---- src/foptiattr.cpp | 124 ++--- src/fterm.cpp | 2 +- src/fvterm.cpp | 173 +++--- src/fwidget.cpp | 109 ++-- 12 files changed, 1025 insertions(+), 783 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95d5e108..67375c43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-12-02 Markus Gans + * Refactoring FListBox::drawList and FListBox::onKeyPress + * Refactoring FWidget::event + 2017-12-02 Markus Gans * Refactoring FApplication::linuxModifierKeyCorrection and FVTerm::updateVTerm diff --git a/include/final/flistbox.h b/include/final/flistbox.h index 514e73ac..4b232990 100644 --- a/include/final/flistbox.h +++ b/include/final/flistbox.h @@ -246,11 +246,31 @@ class FListBox : public FWidget void draw(); void drawLabel(); void drawList(); + void drawListLine (int, listBoxItems::iterator, bool); + void drawListBracketsLine (int, listBoxItems::iterator, bool); + void setLineAttributes (int, bool, bool, bool&); + void unsetAttributes(); + void updateDrawing (bool, bool); void recalculateHorizontalBar (int, bool); void recalculateVerticalBar (int); + void keyUp(); + void keyDown(); + void keyLeft(); + void keyRight(); + void keyPgUp(); + void keyPgDn(); + void keyHome(); + void keyEnd(); + bool keyEsc(); + void keyEnter(); + bool keySpace(); + bool keyInsert(); + bool keyBackspace(); + bool keyIncSearchInput (int); void processClick(); void processSelect(); void processChanged(); + void lazyConvert (listBoxItems::iterator, int); listBoxItems::iterator index2iterator (int); // Callback methods diff --git a/include/final/flistview.h b/include/final/flistview.h index 18559747..9210e77c 100644 --- a/include/final/flistview.h +++ b/include/final/flistview.h @@ -319,11 +319,18 @@ class FListView : public FWidget void drawColumnLabels(); void drawList(); void drawListLine (const FListViewItem*, bool, bool); + void updateDrawing (bool, bool); void recalculateHorizontalBar (int); void recalculateVerticalBar (int); FObjectIterator appendItem (FListViewItem*); void processClick(); void processChanged(); + void keyLeft (int&); + void keyRight (int&); + void keyHome(); + void keyEnd(); + bool keyPlus(); + bool keyMinus(); void setRelativePosition (int); void stepForward(); void stepBackward(); diff --git a/include/final/foptiattr.h b/include/final/foptiattr.h index f2a8be9d..043eab23 100644 --- a/include/final/foptiattr.h +++ b/include/final/foptiattr.h @@ -179,6 +179,27 @@ class FOptiAttr LightGray = 7 }; + enum attr_modes + { + standout_mode = 1, + underline_mode = 2, + reverse_mode = 4, + blink_mode = 8, + dim_mode = 16, + bold_mode = 32, + invisible_mode = 64, + protected_mode = 128, + alt_charset_mode = 256, + horizontal_mode = 512, + left_mode = 1024, + low_mode = 2048, + right_mode = 4096, + top_mode = 8192, + vertical_mode = 16384, + italic_mode = 32768, + no_mode = 65536 + }; + // Disable copy constructor FOptiAttr (const FOptiAttr&); diff --git a/include/final/fvterm.h b/include/final/fvterm.h index cfa5617d..e329f47d 100644 --- a/include/final/fvterm.h +++ b/include/final/fvterm.h @@ -305,6 +305,8 @@ class FVTerm : public FTerm , int, int, int, int ); static void updateCharacter ( term_area* , int, int, int, int ); + static bool updateVTermCharacter ( term_area* + , int, int, int, int ); static void callPreprocessingHandler (term_area*); static void updateVTerm(); static void updateVTerm (term_area*); diff --git a/include/final/fwidget.h b/include/final/fwidget.h index c21dcf52..5ff4e33a 100644 --- a/include/final/fwidget.h +++ b/include/final/fwidget.h @@ -471,6 +471,8 @@ class FWidget : public FVTerm, public FObject void init(); void finish(); void insufficientSpaceAdjust(); + void KeyPressEvent (FKeyEvent*); + void KeyDownEvent (FKeyEvent*); void processDestroy(); virtual void draw(); static void setColorTheme(); diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 7393d006..38430071 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -423,279 +423,84 @@ void FListBox::clear() //---------------------------------------------------------------------- void FListBox::onKeyPress (FKeyEvent* ev) { - static const int padding_space = 2; // 1 leading space + 1 tailing space - int element_count = int(getCount()) - , current_before = current + int current_before = current , xoffset_before = xoffset - , xoffset_end = max_line_width - getClientWidth() + padding_space , yoffset_before = yoffset - , yoffset_end = element_count - getClientHeight() - , pagesize = getClientHeight() - 1 , key = ev->key(); switch ( key ) { case fc::Fkey_return: case fc::Fkey_enter: - processClick(); - inc_search.clear(); + keyEnter(); ev->accept(); break; case fc::Fkey_up: - current--; - - if ( current < 1 ) - current = 1; - - if ( current <= yoffset ) - yoffset--; - - inc_search.clear(); + keyUp(); ev->accept(); break; case fc::Fkey_down: - current++; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset > getClientHeight() ) - yoffset++; - - inc_search.clear(); + keyDown(); ev->accept(); break; case fc::Fkey_left: - xoffset--; - - if ( xoffset < 0 ) - xoffset = 0; - - inc_search.clear(); + keyLeft(); ev->accept(); break; case fc::Fkey_right: - xoffset++; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - - if ( xoffset < 0 ) - xoffset = 0; - - inc_search.clear(); + keyRight(); ev->accept(); break; case fc::Fkey_ppage: - current -= pagesize; - - if ( current < 1 ) - current = 1; - - if ( current <= yoffset ) - { - yoffset -= pagesize; - - if ( yoffset < 0 ) - yoffset = 0; - } - - inc_search.clear(); + keyPgUp(); ev->accept(); break; case fc::Fkey_npage: - current += pagesize; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset > getClientHeight() ) - { - yoffset += pagesize; - - if ( yoffset > yoffset_end ) - yoffset = yoffset_end; - } - - inc_search.clear(); + keyPgDn(); ev->accept(); break; case fc::Fkey_home: - current = 1; - yoffset = 0; - inc_search.clear(); + keyHome(); ev->accept(); break; case fc::Fkey_end: - current = element_count; - - if ( current > getClientHeight() ) - yoffset = yoffset_end; - - inc_search.clear(); + keyEnd(); ev->accept(); break; case fc::Fkey_ic: // insert key - if ( isMultiSelection() ) - { - if ( isSelected(current) ) - unselectItem(current); - else - selectItem(current); - - processSelect(); - current++; - - if ( current > element_count ) - current = element_count; - - if ( current - yoffset >= getHeight() - 1 ) - yoffset++; - + if ( keyInsert() ) ev->accept(); - } - - inc_search.clear(); break; case fc::Fkey_space: - { - uInt inc_len = inc_search.getLength(); - - if ( inc_len > 0 ) - { - inc_search += L' '; - bool inc_found = false; - listBoxItems::iterator iter = itemlist.begin(); - - while ( iter != itemlist.end() ) - { - if ( ! inc_found - && inc_search.toLower() - == iter->getText().left(inc_len + 1).toLower() ) - { - setCurrentItem(iter); - inc_found = true; - break; - } - - ++iter; - } - - if ( ! inc_found ) - { - inc_search.remove(inc_len, 1); - ev->ignore(); - } - else - ev->accept(); - } - else if ( isMultiSelection() ) - { - if ( isSelected(current) ) - unselectItem(current); - else - selectItem(current); - - processSelect(); - inc_search.clear(); - ev->accept(); - } - } + if ( keySpace() ) + ev->accept(); break; case fc::Fkey_erase: case fc::Fkey_backspace: - { - uInt inc_len = inc_search.getLength(); - - if ( inc_len > 0 ) - { - inc_search.remove(inc_len - 1, 1); - - if ( inc_len > 1 ) - { - listBoxItems::iterator iter = itemlist.begin(); - - while ( iter != itemlist.end() ) - { - if ( inc_search.toLower() - == iter->getText().left(inc_len - 1).toLower() ) - { - setCurrentItem(iter); - break; - } - - ++iter; - } - } - - ev->accept(); - } - else - ev->ignore(); - } + if ( keyBackspace() ) + ev->accept(); break; case fc::Fkey_escape: case fc::Fkey_escape_mintty: - if ( inc_search.getLength() > 0 ) - { - inc_search.clear(); + if ( keyEsc() ) ev->accept(); - } break; default: - if ( key > 0x20 && key <= 0x10fff ) - { - // incremental search - if ( inc_search.getLength() == 0 ) - inc_search = wchar_t(key); - else - inc_search += wchar_t(key); - - uInt inc_len = inc_search.getLength(); - bool inc_found = false; - listBoxItems::iterator iter = itemlist.begin(); - - while ( iter != itemlist.end() ) - { - if ( ! inc_found - && inc_search.toLower() - == iter->getText().left(inc_len).toLower() ) - { - setCurrentItem(iter); - inc_found = true; - break; - } - - ++iter; - } - - if ( ! inc_found ) - { - inc_search.remove(inc_len - 1, 1); - - if ( inc_len == 1 ) - ev->ignore(); - else - ev->accept(); - } - else - ev->accept(); - } - else - ev->ignore(); + if ( keyIncSearchInput(key) ) + ev->accept(); } if ( current_before != current ) @@ -708,21 +513,9 @@ void FListBox::onKeyPress (FKeyEvent* ev) if ( ev->isAccepted() ) { - if ( isVisible() ) - drawList(); - - vbar->setValue (yoffset); - - if ( vbar->isVisible() && yoffset_before != yoffset ) - vbar->drawBar(); - - hbar->setValue (xoffset); - - if ( hbar->isVisible() && xoffset_before != xoffset ) - hbar->drawBar(); - - updateTerminal(); - flush_out(); + bool draw_vbar = yoffset_before != yoffset; + bool draw_hbar = xoffset_before != xoffset; + updateDrawing (draw_vbar, draw_hbar); } } @@ -1402,18 +1195,14 @@ void FListBox::drawLabel() //---------------------------------------------------------------------- void FListBox::drawList() { - FString element; - uInt start, num, inc_len; - bool isFocus; + uInt start, num; listBoxItems::iterator iter; if ( itemlist.empty() || getHeight() <= 2 || getWidth() <= 4 ) return; - isFocus = ((flags & fc::focus) != 0); - start = 0; - num = uInt(getHeight() - 2); - inc_len = inc_search.getLength(); + start = 0; + num = uInt(getHeight() - 2); if ( num > getCount() ) num = getCount(); @@ -1433,237 +1222,294 @@ void FListBox::drawList() for (uInt y = start; y < num && iter != itemlist.end() ; y++) { - bool serach_mark = false - , lineHasBrackets = hasBrackets(iter) - , isLineSelected = isSelected(iter) - , isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current)); + bool serach_mark = false; + bool lineHasBrackets = hasBrackets(iter); - if ( conv_type == lazy_convert && iter->getText().isNull() ) - { - convertToItem (*iter, source_container, int(y) + yoffset); - int len = int(iter->text.getLength()); - recalculateHorizontalBar (len, lineHasBrackets); + // Import data via lazy conversion + lazyConvert (iter, int(y)); - if ( hbar->isVisible() ) - hbar->redraw(); - } - - setPrintPos (2, 2 + int(y)); - - if ( isLineSelected ) - { - if ( isMonochron() ) - setBold(); - else - setColor (wc.selected_list_fg, wc.selected_list_bg); - } - else - { - if ( isMonochron() ) - unsetBold(); - else - setColor (wc.list_fg, wc.list_bg); - } - - if ( isCurrentLine ) - { - if ( isFocus && getMaxColor() < 16 ) - setBold(); - - if ( isLineSelected ) - { - if ( isMonochron() ) - setBold(); - else if ( isFocus ) - setColor ( wc.selected_current_element_focus_fg - , wc.selected_current_element_focus_bg ); - else - setColor ( wc.selected_current_element_fg - , wc.selected_current_element_bg ); - - setCursorPos (3, 2 + int(y)); // first character - } - else - { - if ( isMonochron() ) - unsetBold(); - - if ( isFocus ) - { - setColor ( wc.current_element_focus_fg - , wc.current_element_focus_bg ); - int b = ( lineHasBrackets ) ? 1: 0; - - if ( inc_len > 0 ) // incremental search - { - serach_mark = true; - // Place the cursor on the last found character - setCursorPos (2 + b + int(inc_len), 2 + int(y)); - } - else // only highlighted - setCursorPos (3 + b, 2 + int(y)); // first character - } - else - setColor ( wc.current_element_fg - , wc.current_element_bg ); - } - - if ( isMonochron() ) - setReverse(false); - } - else - { - if ( isMonochron() ) - setReverse(true); - else if ( isFocus && getMaxColor() < 16 ) - unsetBold(); - } + // Set screen position and attributes + setLineAttributes ( int(y), isSelected(iter), lineHasBrackets + , serach_mark ); // print the entry - if ( isMonochron() && isCurrentLine ) - print ('>'); - else - print (' '); - if ( lineHasBrackets ) { - int full_length; - uInt len - , i = 0 - , b = 0; - - if ( xoffset == 0 ) - { - b = 1; - - switch ( iter->brackets ) - { - case fc::NoBrackets: - break; - - case fc::SquareBrackets: - print ('['); - break; - - case fc::Parenthesis: - print ('('); - break; - - case fc::CurlyBrackets: - print ('{'); - break; - - case fc::AngleBrackets: - print ('<'); - break; - } - - element = getString(iter).mid ( uInt(1 + xoffset) - , uInt(getWidth() - nf_offset - 5) ); - } - else - element = getString(iter).mid ( uInt(xoffset) - , uInt(getWidth() - nf_offset - 4) ); - - const wchar_t* const& element_str = element.wc_str(); - len = element.getLength(); - - for (; i < len; i++) - { - if ( serach_mark && i == 0 ) - setColor ( wc.current_inc_search_element_fg - , wc.current_element_focus_bg ); - - if ( serach_mark && i == inc_len ) - setColor ( wc.current_element_focus_fg - , wc.current_element_focus_bg ); - - print (element_str[i]); - } - - full_length = int(getString(iter).getLength()); - - if ( b + i < uInt(getWidth() - nf_offset - 4 ) - && xoffset <= full_length + 1 ) - { - if ( serach_mark && i == inc_len ) - setColor ( wc.current_element_focus_fg - , wc.current_element_focus_bg ); - - switch ( iter->brackets ) - { - case fc::NoBrackets: - break; - - case fc::SquareBrackets: - print (']'); - break; - - case fc::Parenthesis: - print (')'); - break; - - case fc::CurlyBrackets: - print ('}'); - break; - - case fc::AngleBrackets: - print ('>'); - break; - } - - i++; - } - - if ( isMonochron() && isCurrentLine ) - { - print ('<'); - i++; - } - - for (; b + i < uInt(getWidth() - nf_offset - 3); i++) - print (' '); + drawListBracketsLine (int(y), iter, serach_mark); } else // line has no brackets { - uInt i, len; - element = getString(iter).mid ( uInt(1 + xoffset) - , uInt(getWidth() - nf_offset - 4) ); - const wchar_t* const& element_str = element.wc_str(); - len = element.getLength(); - - if ( serach_mark ) - setColor ( wc.current_inc_search_element_fg - , wc.current_element_focus_bg ); - - for (i = 0; i < len; i++) - { - if ( serach_mark && i == inc_len ) - setColor ( wc.current_element_focus_fg - , wc.current_element_focus_bg ); - - print (element_str[i]); - } - - if ( isMonochron() && isCurrentLine ) - { - print ('<'); - i++; - } - - for (; i < uInt(getWidth() - nf_offset - 3); i++) - print (' '); + drawListLine (int(y), iter, serach_mark); } ++iter; } + unsetAttributes(); + last_yoffset = yoffset; + last_current = current; +} + +//---------------------------------------------------------------------- +inline void FListBox::drawListLine ( int y, listBoxItems::iterator iter + , bool serach_mark ) +{ + uInt i, len; + uInt inc_len = inc_search.getLength(); + bool isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current)); + FString element; + element = getString(iter).mid ( uInt(1 + xoffset) + , uInt(getWidth() - nf_offset - 4) ); + const wchar_t* const& element_str = element.wc_str(); + len = element.getLength(); + + if ( isMonochron() && isCurrentLine ) + print ('>'); + else + print (' '); + + if ( serach_mark ) + setColor ( wc.current_inc_search_element_fg + , wc.current_element_focus_bg ); + + for (i = 0; i < len; i++) + { + if ( serach_mark && i == inc_len ) + setColor ( wc.current_element_focus_fg + , wc.current_element_focus_bg ); + + print (element_str[i]); + } + + if ( isMonochron() && isCurrentLine ) + { + print ('<'); + i++; + } + + for (; i < uInt(getWidth() - nf_offset - 3); i++) + print (' '); +} + +//---------------------------------------------------------------------- +inline void FListBox::drawListBracketsLine ( int y, listBoxItems::iterator iter + , bool serach_mark ) +{ + int full_length; + FString element; + uInt len + , inc_len = inc_search.getLength() + , i = 0 + , b = 0; + bool isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current)); + + if ( isMonochron() && isCurrentLine ) + print ('>'); + else + print (' '); + + if ( xoffset == 0 ) + { + b = 1; + + switch ( iter->brackets ) + { + case fc::NoBrackets: + break; + + case fc::SquareBrackets: + print ('['); + break; + + case fc::Parenthesis: + print ('('); + break; + + case fc::CurlyBrackets: + print ('{'); + break; + + case fc::AngleBrackets: + print ('<'); + break; + } + + element = getString(iter).mid ( uInt(1 + xoffset) + , uInt(getWidth() - nf_offset - 5) ); + } + else + element = getString(iter).mid ( uInt(xoffset) + , uInt(getWidth() - nf_offset - 4) ); + + const wchar_t* const& element_str = element.wc_str(); + len = element.getLength(); + + for (; i < len; i++) + { + if ( serach_mark && i == 0 ) + setColor ( wc.current_inc_search_element_fg + , wc.current_element_focus_bg ); + + if ( serach_mark && i == inc_len ) + setColor ( wc.current_element_focus_fg + , wc.current_element_focus_bg ); + + print (element_str[i]); + } + + full_length = int(getString(iter).getLength()); + + if ( b + i < uInt(getWidth() - nf_offset - 4 ) + && xoffset <= full_length + 1 ) + { + if ( serach_mark && i == inc_len ) + setColor ( wc.current_element_focus_fg + , wc.current_element_focus_bg ); + + switch ( iter->brackets ) + { + case fc::NoBrackets: + break; + + case fc::SquareBrackets: + print (']'); + break; + + case fc::Parenthesis: + print (')'); + break; + + case fc::CurlyBrackets: + print ('}'); + break; + + case fc::AngleBrackets: + print ('>'); + break; + } + + i++; + } + + if ( isMonochron() && isCurrentLine ) + { + print ('<'); + i++; + } + + for (; b + i < uInt(getWidth() - nf_offset - 3); i++) + print (' '); +} + +//---------------------------------------------------------------------- +inline void FListBox::setLineAttributes ( int y + , bool isLineSelected + , bool lineHasBrackets + , bool& serach_mark ) +{ + bool isFocus = ((flags & fc::focus) != 0) + , isCurrentLine = bool(y + uInt(yoffset) + 1 == uInt(current)); + uInt inc_len = inc_search.getLength(); + + setPrintPos (2, 2 + int(y)); + + if ( isLineSelected ) + { + if ( isMonochron() ) + setBold(); + else + setColor (wc.selected_list_fg, wc.selected_list_bg); + } + else + { + if ( isMonochron() ) + unsetBold(); + else + setColor (wc.list_fg, wc.list_bg); + } + + if ( isCurrentLine ) + { + if ( isFocus && getMaxColor() < 16 ) + setBold(); + + if ( isLineSelected ) + { + if ( isMonochron() ) + setBold(); + else if ( isFocus ) + setColor ( wc.selected_current_element_focus_fg + , wc.selected_current_element_focus_bg ); + else + setColor ( wc.selected_current_element_fg + , wc.selected_current_element_bg ); + + setCursorPos (3, 2 + int(y)); // first character + } + else + { + if ( isMonochron() ) + unsetBold(); + + if ( isFocus ) + { + setColor ( wc.current_element_focus_fg + , wc.current_element_focus_bg ); + int b = ( lineHasBrackets ) ? 1: 0; + + if ( inc_len > 0 ) // incremental search + { + serach_mark = true; + // Place the cursor on the last found character + setCursorPos (2 + b + int(inc_len), 2 + int(y)); + } + else // only highlighted + setCursorPos (3 + b, 2 + int(y)); // first character + } + else + setColor ( wc.current_element_fg + , wc.current_element_bg ); + } + + if ( isMonochron() ) + setReverse(false); + } + else + { + if ( isMonochron() ) + setReverse(true); + else if ( isFocus && getMaxColor() < 16 ) + unsetBold(); + } +} + +//---------------------------------------------------------------------- +inline void FListBox::unsetAttributes() +{ if ( isMonochron() ) // unset for the last element setReverse(false); unsetBold(); - last_yoffset = yoffset; - last_current = current; +} + +//---------------------------------------------------------------------- +inline void FListBox::updateDrawing (bool draw_vbar, bool draw_hbar) +{ + if ( isVisible() ) + drawList(); + + vbar->setValue (yoffset); + + if ( vbar->isVisible() && draw_vbar ) + vbar->drawBar(); + + hbar->setValue (xoffset); + + if ( hbar->isVisible() && draw_hbar ) + hbar->drawBar(); + + updateTerminal(); + flush_out(); } //---------------------------------------------------------------------- @@ -1672,20 +1518,21 @@ void FListBox::recalculateHorizontalBar (int len, bool has_brackets) if ( has_brackets ) len += 2; - if ( len > max_line_width ) + if ( len <= max_line_width ) + return; + + max_line_width = len; + + if ( len >= getWidth() - nf_offset - 3 ) { - max_line_width = len; + hbar->setMaximum (max_line_width - getWidth() + nf_offset + 4); + hbar->setPageSize (max_line_width, getWidth() - nf_offset - 4); + hbar->calculateSliderValues(); - if ( len >= getWidth() - nf_offset - 3 ) - { - hbar->setMaximum (max_line_width - getWidth() + nf_offset + 4); - hbar->setPageSize (max_line_width, getWidth() - nf_offset - 4); - hbar->calculateSliderValues(); - - if ( ! hbar->isVisible() ) - hbar->setVisible(); - } + if ( ! hbar->isVisible() ) + hbar->setVisible(); } + } //---------------------------------------------------------------------- @@ -1699,6 +1546,292 @@ void FListBox::recalculateVerticalBar (int element_count) vbar->setVisible(); } +//---------------------------------------------------------------------- +inline void FListBox::keyUp() +{ + current--; + + if ( current < 1 ) + current = 1; + + if ( current <= yoffset ) + yoffset--; + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyDown() +{ + int element_count = int(getCount()); + current++; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset > getClientHeight() ) + yoffset++; + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyLeft() +{ + xoffset--; + + if ( xoffset < 0 ) + xoffset = 0; + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyRight() +{ + static const int padding_space = 2; // 1 leading space + 1 tailing space + int xoffset_end = max_line_width - getClientWidth() + padding_space; + xoffset++; + + if ( xoffset > xoffset_end ) + xoffset = xoffset_end; + + if ( xoffset < 0 ) + xoffset = 0; + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyPgUp() +{ + int pagesize = getClientHeight() - 1; + current -= pagesize; + + if ( current < 1 ) + current = 1; + + if ( current <= yoffset ) + { + yoffset -= pagesize; + + if ( yoffset < 0 ) + yoffset = 0; + } + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyPgDn() +{ + int element_count = int(getCount()); + int yoffset_end = element_count - getClientHeight(); + int pagesize = getClientHeight() - 1; + current += pagesize; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset > getClientHeight() ) + { + yoffset += pagesize; + + if ( yoffset > yoffset_end ) + yoffset = yoffset_end; + } + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyHome() +{ + current = 1; + yoffset = 0; + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline void FListBox::keyEnd() +{ + int element_count = int(getCount()); + int yoffset_end = element_count - getClientHeight(); + current = element_count; + + if ( current > getClientHeight() ) + yoffset = yoffset_end; + + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline bool FListBox::keyEsc() +{ + if ( inc_search.getLength() > 0 ) + { + inc_search.clear(); + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +inline void FListBox::keyEnter() +{ + processClick(); + inc_search.clear(); +} + +//---------------------------------------------------------------------- +inline bool FListBox::keySpace() +{ + uInt inc_len = inc_search.getLength(); + + if ( inc_len > 0 ) + { + inc_search += L' '; + bool inc_found = false; + listBoxItems::iterator iter = itemlist.begin(); + + while ( iter != itemlist.end() ) + { + if ( ! inc_found + && inc_search.toLower() + == iter->getText().left(inc_len + 1).toLower() ) + { + setCurrentItem(iter); + inc_found = true; + break; + } + + ++iter; + } + + if ( ! inc_found ) + { + inc_search.remove(inc_len, 1); + return false; + } + } + else if ( isMultiSelection() ) + { + if ( isSelected(current) ) + unselectItem(current); + else + selectItem(current); + + processSelect(); + inc_search.clear(); + } + + return true; +} + +//---------------------------------------------------------------------- +inline bool FListBox::keyInsert() +{ + if ( isMultiSelection() ) + { + int element_count = int(getCount()); + + if ( isSelected(current) ) + unselectItem(current); + else + selectItem(current); + + processSelect(); + current++; + + if ( current > element_count ) + current = element_count; + + if ( current - yoffset >= getHeight() - 1 ) + yoffset++; + + return true; + } + + inc_search.clear(); + return false; +} + +//---------------------------------------------------------------------- +inline bool FListBox::keyBackspace() +{ + uInt inc_len = inc_search.getLength(); + + if ( inc_len > 0 ) + { + inc_search.remove(inc_len - 1, 1); + + if ( inc_len > 1 ) + { + listBoxItems::iterator iter = itemlist.begin(); + + while ( iter != itemlist.end() ) + { + if ( inc_search.toLower() + == iter->getText().left(inc_len - 1).toLower() ) + { + setCurrentItem(iter); + break; + } + + ++iter; + } + } + + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +inline bool FListBox::keyIncSearchInput (int key) +{ + if ( key <= 0x20 || key > 0x10fff ) + return false; + + // incremental search + if ( inc_search.getLength() == 0 ) + inc_search = wchar_t(key); + else + inc_search += wchar_t(key); + + uInt inc_len = inc_search.getLength(); + bool inc_found = false; + listBoxItems::iterator iter = itemlist.begin(); + + while ( iter != itemlist.end() ) + { + if ( ! inc_found + && inc_search.toLower() + == iter->getText().left(inc_len).toLower() ) + { + setCurrentItem(iter); + inc_found = true; + break; + } + + ++iter; + } + + if ( ! inc_found ) + { + inc_search.remove(inc_len - 1, 1); + + if ( inc_len == 1 ) + return false; + else + return true; + } + + return true; +} + //---------------------------------------------------------------------- void FListBox::processClick() { @@ -1717,6 +1850,20 @@ void FListBox::processChanged() emitCallback("row-changed"); } +//---------------------------------------------------------------------- +void FListBox::lazyConvert(listBoxItems::iterator iter, int y) +{ + if ( conv_type != lazy_convert || ! iter->getText().isNull() ) + return; + + convertToItem (*iter, source_container, y + yoffset); + int len = int(iter->text.getLength()); + recalculateHorizontalBar (len, hasBrackets(iter)); + + if ( hbar->isVisible() ) + hbar->redraw(); +} + //---------------------------------------------------------------------- void FListBox::cb_VBarChange (FWidget*, data_ptr) { diff --git a/src/flistview.cpp b/src/flistview.cpp index 96f438f0..09bd7f44 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -703,14 +703,11 @@ FObject::FObjectIterator FListView::insert ( const std::vector& cols //---------------------------------------------------------------------- void FListView::onKeyPress (FKeyEvent* ev) { - int element_count = int(getCount()) - , position_before = current_iter.getPosition() + int position_before = current_iter.getPosition() , xoffset_before = xoffset - , xoffset_end = max_line_width - getClientWidth() , first_line_position_before = first_visible_line.getPosition() , pagesize = getClientHeight() - 1 , key = ev->key(); - FListViewItem* item = getCurrentItem(); clicked_expander_pos.setPoint(-1, -1); switch ( key ) @@ -723,142 +720,52 @@ void FListView::onKeyPress (FKeyEvent* ev) case fc::Fkey_up: stepBackward(); - ev->accept(); break; case fc::Fkey_down: stepForward(); - ev->accept(); break; case fc::Fkey_left: - if ( xoffset == 0 ) - { - if ( tree_view && item->isExpandable() && item->isExpand() ) - { - // Collapse element - item->collapse(); - adjustSize(); - element_count = int(getCount()); - recalculateVerticalBar (element_count); - // Force vertical scrollbar redraw - first_line_position_before = -1; - } - else if ( item->hasParent() ) - { - // Jump to parent element - FObject* parent = item->getParent(); - - if ( parent->isInstanceOf("FListViewItem") ) - { - current_iter.parentElement(); - - if ( current_iter.getPosition() < first_line_position_before ) - { - int difference = position_before - current_iter.getPosition(); - - if ( first_visible_line.getPosition() - difference >= 0 ) - { - first_visible_line -= difference; - last_visible_line -= difference; - } - else - { - int d = first_visible_line.getPosition(); - first_visible_line -= d; - last_visible_line -= d; - } - } - } - } - } - else - { - // Scroll left - xoffset--; - - if ( xoffset < 0 ) - xoffset = 0; - } - + keyLeft (first_line_position_before); ev->accept(); break; case fc::Fkey_right: - if ( tree_view && item->isExpandable() && ! item->isExpand() ) - { - // Expand element - item->expand(); - adjustSize(); - // Force vertical scrollbar redraw - first_line_position_before = -1; - } - else - { - // Scroll right - xoffset++; - - if ( xoffset > xoffset_end ) - xoffset = xoffset_end; - - if ( xoffset < 0 ) - xoffset = 0; - } - + keyRight(first_line_position_before); ev->accept(); break; case fc::Fkey_ppage: stepBackward(pagesize); - ev->accept(); break; case fc::Fkey_npage: stepForward(pagesize); - ev->accept(); break; case fc::Fkey_home: - { - current_iter -= current_iter.getPosition(); - int difference = first_visible_line.getPosition(); - first_visible_line -= difference; - last_visible_line -= difference; - } + keyHome(); ev->accept(); break; case fc::Fkey_end: - { - current_iter += element_count - current_iter.getPosition() - 1; - int difference = element_count - last_visible_line.getPosition() - 1; - first_visible_line += difference; - last_visible_line += difference; - } - + keyEnd(); ev->accept(); break; case int('+'): - if ( tree_view && item->isExpandable() && ! item->isExpand() ) - { - item->expand(); - adjustSize(); + if ( keyPlus() ) ev->accept(); - } break; case int('-'): - if ( tree_view && item->isExpandable() && item->isExpand() ) - { - item->collapse(); - adjustSize(); + if ( keyMinus() ) ev->accept(); - } break; default: @@ -870,21 +777,10 @@ void FListView::onKeyPress (FKeyEvent* ev) if ( ev->isAccepted() ) { - if ( isVisible() ) - draw(); - - vbar->setValue (first_visible_line.getPosition()); - - if ( vbar->isVisible() && first_line_position_before != first_visible_line.getPosition() ) - vbar->drawBar(); - - hbar->setValue (xoffset); - - if ( hbar->isVisible() && xoffset_before != xoffset ) - hbar->drawBar(); - - updateTerminal(); - flush_out(); + bool draw_vbar = first_line_position_before + != first_visible_line.getPosition(); + bool draw_hbar = xoffset_before != xoffset; + updateDrawing (draw_vbar, draw_hbar); } } @@ -1746,6 +1642,26 @@ void FListView::drawListLine ( const FListViewItem* item print (' '); } +//---------------------------------------------------------------------- +void FListView::updateDrawing (bool draw_vbar, bool draw_hbar) +{ + if ( isVisible() ) + draw(); + + vbar->setValue (first_visible_line.getPosition()); + + if ( vbar->isVisible() && draw_vbar ) + vbar->drawBar(); + + hbar->setValue (xoffset); + + if ( hbar->isVisible() && draw_hbar ) + hbar->drawBar(); + + updateTerminal(); + flush_out(); +} + //---------------------------------------------------------------------- void FListView::recalculateHorizontalBar (int len) { @@ -1796,6 +1712,139 @@ void FListView::processChanged() emitCallback("row-changed"); } +//---------------------------------------------------------------------- +inline void FListView::keyLeft (int& first_line_position_before) +{ + int element_count = int(getCount()); + int position_before = current_iter.getPosition(); + FListViewItem* item = getCurrentItem(); + + if ( xoffset == 0 ) + { + if ( tree_view && item->isExpandable() && item->isExpand() ) + { + // Collapse element + item->collapse(); + adjustSize(); + element_count = int(getCount()); + recalculateVerticalBar (element_count); + // Force vertical scrollbar redraw + first_line_position_before = -1; + } + else if ( item->hasParent() ) + { + // Jump to parent element + FObject* parent = item->getParent(); + + if ( parent->isInstanceOf("FListViewItem") ) + { + current_iter.parentElement(); + + if ( current_iter.getPosition() < first_line_position_before ) + { + int difference = position_before - current_iter.getPosition(); + + if ( first_visible_line.getPosition() - difference >= 0 ) + { + first_visible_line -= difference; + last_visible_line -= difference; + } + else + { + int d = first_visible_line.getPosition(); + first_visible_line -= d; + last_visible_line -= d; + } + } + } + } + } + else + { + // Scroll left + xoffset--; + + if ( xoffset < 0 ) + xoffset = 0; + } +} + +//---------------------------------------------------------------------- +inline void FListView::keyRight (int& first_line_position_before) +{ + int xoffset_end = max_line_width - getClientWidth(); + FListViewItem* item = getCurrentItem(); + + if ( tree_view && item->isExpandable() && ! item->isExpand() ) + { + // Expand element + item->expand(); + adjustSize(); + // Force vertical scrollbar redraw + first_line_position_before = -1; + } + else + { + // Scroll right + xoffset++; + + if ( xoffset > xoffset_end ) + xoffset = xoffset_end; + + if ( xoffset < 0 ) + xoffset = 0; + } +} + +//---------------------------------------------------------------------- +inline void FListView::keyHome() +{ + current_iter -= current_iter.getPosition(); + int difference = first_visible_line.getPosition(); + first_visible_line -= difference; + last_visible_line -= difference; +} + +//---------------------------------------------------------------------- +inline void FListView::keyEnd() +{ + int element_count = int(getCount()); + current_iter += element_count - current_iter.getPosition() - 1; + int difference = element_count - last_visible_line.getPosition() - 1; + first_visible_line += difference; + last_visible_line += difference; +} + +//---------------------------------------------------------------------- +inline bool FListView::keyPlus() +{ + FListViewItem* item = getCurrentItem(); + + if ( tree_view && item->isExpandable() && ! item->isExpand() ) + { + item->expand(); + adjustSize(); + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +inline bool FListView::keyMinus() +{ + FListViewItem* item = getCurrentItem(); + + if ( tree_view && item->isExpandable() && item->isExpand() ) + { + item->collapse(); + adjustSize(); + return true; + } + + return false; +} + //---------------------------------------------------------------------- void FListView::setRelativePosition (int ry) { diff --git a/src/foptiattr.cpp b/src/foptiattr.cpp index 1b61d47f..9a251613 100644 --- a/src/foptiattr.cpp +++ b/src/foptiattr.cpp @@ -1204,96 +1204,72 @@ inline void FOptiAttr::resetColor (char_data*& attr) //---------------------------------------------------------------------- inline void FOptiAttr::prevent_no_color_video_attributes (char_data*& attr) { - // ignore attributes which can not combined with a color + // Ignore attributes which can not combined with a color - enum attr_modes - { - standout_mode = 1, - underline_mode = 2, - reverse_mode = 4, - blink_mode = 8, - dim_mode = 16, - bold_mode = 32, - invisible_mode = 64, - protected_mode = 128, - alt_charset_mode = 256, - horizontal_mode = 512, - left_mode = 1024, - low_mode = 2048, - right_mode = 4096, - top_mode = 8192, - vertical_mode = 16384, - italic_mode = 32768, - no_mode = 65536 - }; - - if ( ! attr ) + if ( ! attr || ! hasColor(attr) || attr_without_color <= 0 ) return; - if ( hasColor(attr) && attr_without_color > 0 ) + for (int bit = 1; bit < no_mode; bit <<= 1) { - for (int bit = 1; bit < no_mode; bit <<= 1) + switch ( bit & attr_without_color ) { - switch ( bit & attr_without_color ) - { - case standout_mode: - if ( attr->attr.bit.standout ) - attr->attr.bit.standout = false; - break; + case standout_mode: + if ( attr->attr.bit.standout ) + attr->attr.bit.standout = false; + break; - case underline_mode: - if ( attr->attr.bit.underline ) - attr->attr.bit.underline = false; - break; + case underline_mode: + if ( attr->attr.bit.underline ) + attr->attr.bit.underline = false; + break; - case reverse_mode: - if ( attr->attr.bit.reverse ) - { - attr->attr.bit.reverse = false; + case reverse_mode: + if ( attr->attr.bit.reverse ) + { + attr->attr.bit.reverse = false; - if ( attr->fg_color != attr->bg_color ) - fake_reverse = true; - } - break; + if ( attr->fg_color != attr->bg_color ) + fake_reverse = true; + } + break; - case blink_mode: - if ( attr->attr.bit.blink ) - attr->attr.bit.blink = false; - break; + case blink_mode: + if ( attr->attr.bit.blink ) + attr->attr.bit.blink = false; + break; - case dim_mode: - if ( attr->attr.bit.dim ) - attr->attr.bit.dim = false; - break; + case dim_mode: + if ( attr->attr.bit.dim ) + attr->attr.bit.dim = false; + break; - case bold_mode: - if ( attr->attr.bit.bold ) - attr->attr.bit.bold = false; - break; + case bold_mode: + if ( attr->attr.bit.bold ) + attr->attr.bit.bold = false; + break; - case invisible_mode: - if ( attr->attr.bit.invisible ) - attr->attr.bit.invisible = false; - break; + case invisible_mode: + if ( attr->attr.bit.invisible ) + attr->attr.bit.invisible = false; + break; - case protected_mode: - if ( attr->attr.bit.protect ) - attr->attr.bit.protect = false; - break; + case protected_mode: + if ( attr->attr.bit.protect ) + attr->attr.bit.protect = false; + break; - case alt_charset_mode: - if ( attr->attr.bit.alt_charset ) - attr->attr.bit.alt_charset = false; - break; + case alt_charset_mode: + if ( attr->attr.bit.alt_charset ) + attr->attr.bit.alt_charset = false; + break; - case italic_mode: - if ( attr->attr.bit.italic ) - attr->attr.bit.italic = false; - break; + case italic_mode: + if ( attr->attr.bit.italic ) + attr->attr.bit.italic = false; + break; - default: - break; - } + default: + break; } } } diff --git a/src/fterm.cpp b/src/fterm.cpp index 2a5ef64d..0cb6fd57 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -136,7 +136,7 @@ bool FTermcap::no_utf8_acs_chars = false; int FTermcap::max_color = 1; int FTermcap::tabstop = 8; int FTermcap::attr_without_color = 0; -FTerm::initializationValues FTerm::init_values; +FTerm::initializationValues FTerm::init_values; fc::linuxConsoleCursorStyle FTerm::linux_console_cursor_style; fc::freebsdConsoleCursorStyle FTerm::freebsd_console_cursor_style; diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 7ee62056..bf8626de 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -1256,6 +1256,49 @@ void FVTerm::updateCharacter ( term_area* area tc->attr.bit.no_changes = false; } +//---------------------------------------------------------------------- +bool FVTerm::updateVTermCharacter ( term_area* area + , int x, int y, int tx, int ty ) +{ + int& aw = area->width; + int& rsh = area->right_shadow; + int line_len = aw + rsh; + // Area character + char_data* ac = &area->text[y * line_len + x]; + + // Get covered state + covered_state is_covered = isCovered(tx, ty, area); + + if ( is_covered == fully_covered ) + return false; + + if ( is_covered == half_covered ) + { + updateOverlappedColor(area, x, y, tx, ty); + } + else if ( ac->attr.bit.transparent ) // Transparent + { + updateOverlappedCharacter(area, tx, ty); + } + else // Not transparent + { + if ( ac->attr.bit.trans_shadow ) // Transparent shadow + { + updateShadedCharacter (area, x, y, tx, ty); + } + else if ( ac->attr.bit.inherit_bg ) + { + updateInheritBackground (area, x, y, tx, ty); + } + else // Default + { + updateCharacter (area, x, y, tx, ty); + } + } + + return true; +} + //---------------------------------------------------------------------- void FVTerm::callPreprocessingHandler (term_area* area) { @@ -1339,26 +1382,21 @@ void FVTerm::updateVTerm (term_area* area) { // Update area data on VTerm - char_data* ac; // area character - - if ( ! area ) - return; - - if ( ! area->visible ) - return; - - // Call the processing handler methods - callPreprocessingHandler(area); - int ax = area->offset_left , ay = area->offset_top , aw = area->width , ah = area->height , rsh = area->right_shadow , bsh = area->bottom_shadow - , ol = 0 // outside left + , ol = 0 // Outside left , y_end; + if ( ! area || ! area->visible ) + return; + + // Call the processing handler methods + callPreprocessingHandler(area); + if ( ax < 0 ) { ol = std::abs(ax); @@ -1370,88 +1408,57 @@ void FVTerm::updateVTerm (term_area* area) else y_end = ah + bsh; - for (int y = 0; y < y_end; y++) // line loop + for (int y = 0; y < y_end; y++) // Line loop { + int _xmin, _xmax; + bool modified = false; int line_xmin = int(area->changes[y].xmin); int line_xmax = int(area->changes[y].xmax); - if ( line_xmin <= line_xmax ) + if ( line_xmin > line_xmax ) + continue; + + if ( ax == 0 ) + line_xmin = ol; + + if ( aw + rsh + ax - ol >= vterm->width ) + line_xmax = vterm->width + ol - ax - 1; + + if ( ax + line_xmin >= vterm->width ) + continue; + + for (int x = line_xmin; x <= line_xmax; x++) // Column loop { - int _xmin, _xmax; - bool modified = false; + // Global terminal positions + int tx = ax + x + , ty = ay + y; - if ( ax == 0 ) - line_xmin = ol; - - if ( aw + rsh + ax - ol >= vterm->width ) - line_xmax = vterm->width + ol - ax - 1; - - if ( ax + line_xmin >= vterm->width ) + if ( tx < 0 || ty < 0 ) continue; - for (int x = line_xmin; x <= line_xmax; x++) // column loop - { - covered_state is_covered; - // global terminal positions - int gx = ax + x - , gy = ay + y; + tx -= ol; - if ( gx < 0 || gy < 0 ) - continue; + if ( updateVTermCharacter (area, x, y, tx, ty) ) + modified = true; - int line_len = aw + rsh; - ac = &area->text[y * line_len + x]; - gx -= ol; - - is_covered = isCovered(gx, gy, area); // get covered state - - if ( is_covered != fully_covered ) - { - if ( is_covered == half_covered ) - { - updateOverlappedColor(area, x, y, gx, gy); - } - else if ( ac->attr.bit.transparent ) // transparent - { - updateOverlappedCharacter(area, gx, gy); - } - else // not transparent - { - if ( ac->attr.bit.trans_shadow ) // transparent shadow - { - updateShadedCharacter (area, x, y, gx, gy); - } - else if ( ac->attr.bit.inherit_bg ) - { - updateInheritBackground (area, x, y, gx, gy); - } - else // default - { - updateCharacter (area, x, y, gx, gy); - } - } - - modified = true; - } - else if ( ! modified ) - line_xmin++; // don't update covered character - } - - _xmin = ax + line_xmin - ol; - _xmax = ax + line_xmax; - - if ( _xmin < short(vterm->changes[ay + y].xmin) ) - vterm->changes[ay + y].xmin = uInt(_xmin); - - if ( _xmax >= vterm->width ) - _xmax = vterm->width - 1; - - if ( _xmax > short(vterm->changes[ay + y].xmax) ) - vterm->changes[ay + y].xmax = uInt(_xmax); - - area->changes[y].xmin = uInt(aw + rsh); - area->changes[y].xmax = 0; + if ( ! modified ) + line_xmin++; // Don't update covered character } + + _xmin = ax + line_xmin - ol; + _xmax = ax + line_xmax; + + if ( _xmin < short(vterm->changes[ay + y].xmin) ) + vterm->changes[ay + y].xmin = uInt(_xmin); + + if ( _xmax >= vterm->width ) + _xmax = vterm->width - 1; + + if ( _xmax > short(vterm->changes[ay + y].xmax) ) + vterm->changes[ay + y].xmax = uInt(_xmax); + + area->changes[y].xmin = uInt(aw + rsh); + area->changes[y].xmax = 0; } updateVTermCursor(area); diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 9fbcf173..dea5d170 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -2121,43 +2121,7 @@ bool FWidget::event (FEvent* ev) switch ( ev->type() ) { case fc::KeyPress_Event: - { - FKeyEvent* kev = static_cast(ev); - bool accpt_focus = false; - - if ( kev->key() == fc::Fkey_tab ) - accpt_focus = focusNextChild(); - else if ( kev->key() == fc::Fkey_btab ) - accpt_focus = focusPrevChild(); - - if ( accpt_focus ) - break; - - FWidget* widget = this; - - while ( widget ) - { - widget->onKeyPress(kev); - - if ( ! kev->isAccepted() ) - { - if ( kev->key() == fc::Fkey_right - || kev->key() == fc::Fkey_down ) - accpt_focus = focusNextChild(); - else if ( kev->key() == fc::Fkey_left - || kev->key() == fc::Fkey_up ) - accpt_focus = focusPrevChild(); - - if ( accpt_focus ) - break; - } - - if ( kev->isAccepted() || widget->isRootWidget() ) - break; - - widget = widget->getParentWidget(); - } - } + KeyPressEvent ( static_cast(ev) ); break; case fc::KeyUp_Event: @@ -2165,20 +2129,7 @@ bool FWidget::event (FEvent* ev) break; case fc::KeyDown_Event: - { - FKeyEvent* kev = static_cast(ev); - FWidget* widget = this; - - while ( widget ) - { - widget->onKeyDown(kev); - - if ( kev->isAccepted() || widget->isRootWidget() ) - break; - - widget = widget->getParentWidget(); - } - } + KeyDownEvent ( static_cast(ev) ); break; case fc::MouseDown_Event: @@ -2244,6 +2195,7 @@ bool FWidget::event (FEvent* ev) default: return false; } + return true; } @@ -2458,6 +2410,61 @@ inline void FWidget::insufficientSpaceAdjust() adjust_wsize.setHeight(1); } +//---------------------------------------------------------------------- +void FWidget::KeyPressEvent (FKeyEvent* kev) +{ + bool accpt_focus = false; + + if ( kev->key() == fc::Fkey_tab ) + accpt_focus = focusNextChild(); + else if ( kev->key() == fc::Fkey_btab ) + accpt_focus = focusPrevChild(); + + if ( accpt_focus ) + return; + + FWidget* widget = this; + + while ( widget ) + { + widget->onKeyPress(kev); + + if ( ! kev->isAccepted() ) + { + if ( kev->key() == fc::Fkey_right + || kev->key() == fc::Fkey_down ) + accpt_focus = focusNextChild(); + else if ( kev->key() == fc::Fkey_left + || kev->key() == fc::Fkey_up ) + accpt_focus = focusPrevChild(); + + if ( accpt_focus ) + return; + } + + if ( kev->isAccepted() || widget->isRootWidget() ) + return; + + widget = widget->getParentWidget(); + } +} + +//---------------------------------------------------------------------- +void FWidget::KeyDownEvent (FKeyEvent* kev) +{ + FWidget* widget = this; + + while ( widget ) + { + widget->onKeyDown(kev); + + if ( kev->isAccepted() || widget->isRootWidget() ) + break; + + widget = widget->getParentWidget(); + } +} + //---------------------------------------------------------------------- void FWidget::draw() { }