From 937654710bd9b93e1be8fbb76a6a0ea96796790a Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 6 Oct 2019 22:35:00 +0200 Subject: [PATCH] Code cleaning --- README.md | 10 +- doc/virtual-terminal.txt | 10 +- src/fapplication.cpp | 2 +- src/fbutton.cpp | 8 +- src/fdialog.cpp | 2 +- src/flineedit.cpp | 2 +- src/fmenu.cpp | 2 +- src/fprogressbar.cpp | 2 +- src/fterm.cpp | 1 + src/fvterm.cpp | 1248 +++++++++++++++-------------- src/fwidget.cpp | 729 ++++++++--------- src/fwindow.cpp | 20 +- src/include/final/ffiledialog.h | 2 +- src/include/final/fmouse.h | 2 +- src/include/final/fscrollview.h | 4 +- src/include/final/ftogglebutton.h | 2 +- src/include/final/fvterm.h | 112 ++- src/include/final/fwidget.h | 85 +- 18 files changed, 1097 insertions(+), 1146 deletions(-) diff --git a/README.md b/README.md index c26ce3aa..273c0369 100644 --- a/README.md +++ b/README.md @@ -97,12 +97,12 @@ printf(...) │ │createArea(area) │ ║ │ │ │ ║ │ │ │ ║ - └───┼─────────────► ──────► updateVTerm(area) ────► ║ + └───┼────────► putArea(area) ────► ║ + │ │ ║ + │ putArea(x,y,area) ────► ║ + │ │ ║ + │ ◄──── getArea(x,y,area) ║ │ │ ║ - │ putArea(x,y,area) ║ - │ ────────────────────► ║ - │ getArea(x,y,area) ║ - │ ◄──────────────────── ║ │ │ ║ │ │ ║ │ resizeArea(area)│ ║ diff --git a/doc/virtual-terminal.txt b/doc/virtual-terminal.txt index b01bdc76..9192157f 100644 --- a/doc/virtual-terminal.txt +++ b/doc/virtual-terminal.txt @@ -23,12 +23,12 @@ printf(...) │ │createArea(area) │ ║ │ │ │ ║ │ │ │ ║ - └───┼─────────────► ──────► updateVTerm(area) ────► ║ + └───┼────────► putArea(area) ────► ║ + │ │ ║ + │ putArea(x,y,area) ────► ║ + │ │ ║ + │ ◄──── getArea(x,y,area) ║ │ │ ║ - │ putArea(x,y,area) ║ - │ ────────────────────► ║ - │ getArea(x,y,area) ║ - │ ◄──────────────────── ║ │ │ ║ │ │ ║ │ resizeArea(area)│ ║ diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 12ed54ee..415e5a9a 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -798,7 +798,7 @@ FWidget*& FApplication::determineClickedWidget() if ( window ) { // Determine the widget at the current click position - auto child = childWidgetAt (window, mouse_position); + auto child = window->childWidgetAt (mouse_position); clicked = ( child != 0 ) ? child : window; setClickedWidget (clicked); } diff --git a/src/fbutton.cpp b/src/fbutton.cpp index 8e68776f..0f215211 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -440,9 +440,9 @@ inline std::size_t FButton::clickAnimationIndent (FWidget* parent_widget) // noshadow + indent one character to the right if ( getFlags().flat ) - clearFlatBorder(); + clearFlatBorder(this); else if ( hasShadow() ) - clearShadow(); + clearShadow(this); if ( parent_widget ) setColor ( parent_widget->getForegroundColor() @@ -639,7 +639,7 @@ void FButton::draw() setReverse(false); // Dark background if ( getFlags().flat && ! button_down ) - drawFlatBorder(); + drawFlatBorder(this); hotkeypos = finalcut::getHotkeyPos(text, button_text); @@ -665,7 +665,7 @@ void FButton::draw() // Draw button shadow if ( ! getFlags().flat && getFlags().shadow && ! button_down ) - drawShadow(); + drawShadow(this); if ( isMonochron() ) setReverse(false); // Dark background diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 36022415..67dcdf31 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -748,7 +748,7 @@ void FDialog::drawDialogShadow() if ( isMonochron() && ! getFlags().trans_shadow ) return; - drawShadow(); + drawShadow(this); } //---------------------------------------------------------------------- diff --git a/src/flineedit.cpp b/src/flineedit.cpp index 5c865821..467deb8a 100644 --- a/src/flineedit.cpp +++ b/src/flineedit.cpp @@ -791,7 +791,7 @@ void FLineEdit::drawInputField() } if ( getFlags().shadow ) - drawShadow (); + drawShadow(this); // set the cursor to the insert pos. auto cursor_pos_column = getColumnWidth (text, cursor_pos); diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 58790b1b..0be7a681 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -1178,7 +1178,7 @@ void FMenu::draw() clearArea(); drawBorder(); drawItems(); - drawShadow(); + drawShadow(this); if ( isMonochron() ) setReverse(false); diff --git a/src/fprogressbar.cpp b/src/fprogressbar.cpp index 9e39ff36..cc85bf84 100644 --- a/src/fprogressbar.cpp +++ b/src/fprogressbar.cpp @@ -131,7 +131,7 @@ void FProgressbar::draw() drawProgressBar(); if ( getFlags().shadow ) - drawShadow (); + drawShadow(this); flush_out(); } diff --git a/src/fterm.cpp b/src/fterm.cpp index fe35a8aa..c3a8da0c 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -2150,6 +2150,7 @@ void FTerm::useNormalScreenBuffer() //---------------------------------------------------------------------- inline void FTerm::allocationValues() { + FStartOptions::getFStartOptions(); getFTermData(); getFSystem(); getFOptiMove(); diff --git a/src/fvterm.cpp b/src/fvterm.cpp index cf26ed97..5ba88569 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -299,7 +299,7 @@ void FVTerm::addPreprocessingHandler ( FVTerm* instance { vterm_preprocessing obj{ instance, function }; delPreprocessingHandler (instance); - print_area->preprocessing_call.push_back(obj); + print_area->preproc_list.push_back(obj); } } @@ -309,15 +309,15 @@ void FVTerm::delPreprocessingHandler (FVTerm* instance) if ( ! print_area ) FVTerm::getPrintArea(); - if ( ! print_area || print_area->preprocessing_call.empty() ) + if ( ! print_area || print_area->preproc_list.empty() ) return; - auto iter = print_area->preprocessing_call.begin(); + auto iter = print_area->preproc_list.begin(); - while ( iter != print_area->preprocessing_call.end() ) + while ( iter != print_area->preproc_list.end() ) { if ( iter->instance == instance ) - iter = print_area->preprocessing_call.erase(iter); + iter = print_area->preproc_list.erase(iter); else ++iter; } @@ -707,78 +707,6 @@ void FVTerm::resizeArea ( const FRect& box setTextToDefault (area, size); } -//---------------------------------------------------------------------- -inline void FVTerm::setTextToDefault ( term_area* area - , const FSize& size ) -{ - charData default_char; - line_changes unchanged; - - default_char.code = ' '; - default_char.fg_color = fc::Default; - default_char.bg_color = fc::Default; - default_char.attr.byte[0] = 0; - default_char.attr.byte[1] = 0; - default_char.attr.byte[2] = 0; - - std::fill_n (area->text, size.getArea(), default_char); - - unchanged.xmin = uInt(size.getWidth()); - unchanged.xmax = 0; - unchanged.trans_count = 0; - - std::fill_n (area->changes, size.getHeight(), unchanged); -} - -//---------------------------------------------------------------------- -inline bool FVTerm::reallocateTextArea ( term_area* area - , std::size_t height - , std::size_t size ) -{ - // Reallocate "height" lines for changes - // and "size" bytes for the text area - - if ( area->changes != 0 ) - delete[] area->changes; - - if ( area->text != 0 ) - delete[] area->text; - - try - { - area->changes = new line_changes[height]; - area->text = new charData[size]; - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << ex.what() << std::endl; - return false; - } - - return true; -} - -//---------------------------------------------------------------------- -inline bool FVTerm::reallocateTextArea (term_area* area, std::size_t size) -{ - // Reallocate "size" bytes for the text area - - if ( area->text != 0 ) - delete[] area->text; - - try - { - area->text = new charData[size]; - } - catch (const std::bad_alloc& ex) - { - std::cerr << bad_alloc_str << ex.what() << std::endl; - return false; - } - - return true; -} - //---------------------------------------------------------------------- void FVTerm::removeArea (term_area*& area) { @@ -851,6 +779,592 @@ void FVTerm::restoreVTerm (const FRect& box) vterm->has_changes = true; } +//---------------------------------------------------------------------- +bool FVTerm::updateVTermCursor (term_area* area) +{ + if ( ! area ) + return false; + + if ( area != active_area ) + return false; + + if ( ! area->visible ) + return false; + + if ( area->input_cursor_visible ) + { + // area offset + int ax = area->offset_left; + int ay = area->offset_top; + // area cursor position + int cx = area->input_cursor_x; + int cy = area->input_cursor_y; + // terminal position + int x = ax + cx; + int y = ay + cy; + + if ( isInsideArea (FPoint(cx, cy), area) + && isInsideTerminal (FPoint(x, y)) + && isCovered (FPoint(x, y), area) == non_covered ) + { + vterm->input_cursor_x = x; + vterm->input_cursor_y = y; + vterm->input_cursor_visible = true; + vterm->has_changes = true; + return true; + } + } + + vterm->input_cursor_visible = false; + return false; +} + +//---------------------------------------------------------------------- +void FVTerm::setAreaCursor ( const FPoint& pos + , bool visible + , term_area* area ) +{ + if ( ! area ) + return; + + area->input_cursor_x = pos.getX() - 1; + area->input_cursor_y = pos.getY() - 1; + area->input_cursor_visible = visible; +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (const FPoint& pos, term_area* area) +{ + // Copies a block from the virtual terminal position to the given area + + if ( ! area ) + return; + + int ax = pos.getX() - 1; + int ay = pos.getY() - 1; + int y_end{}, length{}; + + if ( area->height + ay > vterm->height ) + y_end = area->height - ay; + else + y_end = area->height; + + if ( area->width + ax > vterm->width ) + length = vterm->width - ax; + else + length = area->width; + + for (int y{0}; y < y_end; y++) // line loop + { + auto tc = &vterm->text[(ay + y) * vterm->width + ax]; // terminal character + auto ac = &area->text[y * area->width]; // area character + std::memcpy (ac, tc, sizeof(*ac) * unsigned(length)); + + if ( int(area->changes[y].xmin) > 0 ) + area->changes[y].xmin = 0; + + if ( int(area->changes[y].xmax) < length - 1 ) + area->changes[y].xmax = uInt(length - 1); + } +} + +//---------------------------------------------------------------------- +void FVTerm::getArea (const FRect& box, term_area* area) +{ + // Copies a block from the virtual terminal rectangle to the given area + + if ( ! area ) + return; + + int x = box.getX(); + int y = box.getY(); + int w = int(box.getWidth()); + int h = int(box.getHeight()); + int dx = x - area->offset_left + 1; + int dy = y - area->offset_top + 1; + int y_end{}, length{}; + + if ( x < 0 || y < 0 ) + return; + + if ( y - 1 + h > vterm->height ) + y_end = vterm->height - y + 1; + else + y_end = h - 1; + + if ( x - 1 + w > vterm->width ) + length = vterm->width - x + 1; + else + length = w; + + if ( length < 1 ) + return; + + for (int _y = 0; _y < y_end; _y++) // line loop + { + int line_len = area->width + area->right_shadow; + auto tc = &vterm->text[(y + _y - 1) * vterm->width + x - 1]; // terminal character + auto ac = &area->text[(dy + _y) * line_len + dx]; // area character + std::memcpy (ac, tc, sizeof(*ac) * unsigned(length)); + + if ( int(area->changes[dy + _y].xmin) > dx ) + area->changes[dy + _y].xmin = uInt(dx); + + if ( int(area->changes[dy + _y].xmax) < dx + length - 1 ) + area->changes[dy + _y].xmax = uInt(dx + length - 1); + } +} + +//---------------------------------------------------------------------- +void FVTerm::putArea (term_area* area) +{ + // Add area changes to the virtual terminal + + if ( ! area || ! area->visible ) + return; + + int ax = area->offset_left; + int ay = area->offset_top; + int width = area->width + area->right_shadow; + int height = area->height + area->bottom_shadow; + int ol{0}; // Outside left + int y_end{}; + + // Call the preprocessing handler methods + callPreprocessingHandler(area); + + if ( ax < 0 ) + { + ol = std::abs(ax); + ax = 0; + } + + if ( height + ay > vterm->height ) + y_end = vterm->height - ay; + else + y_end = height; + + for (int y{0}; y < y_end; y++) // Line loop + { + bool modified{false}; + int line_xmin = int(area->changes[y].xmin); + int line_xmax = int(area->changes[y].xmax); + + if ( line_xmin > line_xmax ) + continue; + + if ( ax == 0 ) + line_xmin = ol; + + if ( width + 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 + { + // Global terminal positions + int tx = ax + x; + int ty = ay + y; + + if ( tx < 0 || ty < 0 ) + continue; + + tx -= ol; + + if ( updateVTermCharacter(area, FPoint(x, y), FPoint(tx, ty)) ) + modified = true; + + if ( ! modified ) + line_xmin++; // Don't update covered character + } + + int _xmin = ax + line_xmin - ol; + int _xmax = ax + line_xmax; + + if ( _xmin < int(vterm->changes[ay + y].xmin) ) + vterm->changes[ay + y].xmin = uInt(_xmin); + + if ( _xmax >= vterm->width ) + _xmax = vterm->width - 1; + + if ( _xmax > int(vterm->changes[ay + y].xmax) ) + vterm->changes[ay + y].xmax = uInt(_xmax); + + area->changes[y].xmin = uInt(width); + area->changes[y].xmax = 0; + } + + vterm->has_changes = true; + updateVTermCursor(area); +} + +//---------------------------------------------------------------------- +void FVTerm::putArea (const FPoint& pos, term_area* area) +{ + // Copies the given area block to the virtual terminal position + + charData* tc{}; // terminal character + charData* ac{}; // area character + + if ( ! area || ! area->visible ) + return; + + int ax = pos.getX() - 1; + int ay = pos.getY() - 1; + int width = area->width + area->right_shadow; + int height = area->height + area->bottom_shadow; + int ol{0}; // outside left + int y_end{}, length{}; + + if ( ax < 0 ) + { + ol = std::abs(ax); + ax = 0; + } + + if ( ay + height > vterm->height ) + y_end = vterm->height - ay; + else + y_end = height; + + if ( width - ol + ax > vterm->width ) + length = vterm->width - ax; + else + length = width - ol; + + if ( length < 1 ) + return; + + for (int y{0}; y < y_end; y++) // line loop + { + if ( area->changes[y].trans_count == 0 ) + { + // Line has only covered characters + ac = &area->text[y * width + ol]; + tc = &vterm->text[(ay + y) * vterm->width + ax]; + putAreaLine (ac, tc, length); + } + else + { + // Line has one or more transparent characters + for (int x{0}; x < length; x++) // column loop + { + int cx = ax + x; + int cy = ay + y; + ac = &area->text[y * width + ol + x]; + tc = &vterm->text[cy * vterm->width + cx]; + putAreaCharacter (FPoint(cx + 1, cy + 1), area->widget, ac, tc); + } + } + + if ( ax < int(vterm->changes[ay + y].xmin) ) + vterm->changes[ay + y].xmin = uInt(ax); + + if ( ax + length - 1 > int(vterm->changes[ay + y].xmax) ) + vterm->changes[ay + y].xmax = uInt(ax + length - 1); + } + + vterm->has_changes = true; +} + +//---------------------------------------------------------------------- +void FVTerm::scrollAreaForward (term_area* area) +{ + // Scrolls the entire area up line down + charData nc{}; // next character + charData* lc{}; // last character + charData* dc{}; // destination character + + if ( ! area ) + return; + + if ( area->height <= 1 ) + return; + + int length = area->width; + int total_width = area->width + area->right_shadow; + int y_max = area->height - 1; + + for (int y{0}; y < y_max; y++) + { + int pos1 = y * total_width; + int pos2 = (y + 1) * total_width; + auto sc = &area->text[pos2]; // source character + dc = &area->text[pos1]; + std::memcpy (dc, sc, sizeof(*dc) * unsigned(length)); + area->changes[y].xmin = 0; + area->changes[y].xmax = uInt(area->width - 1); + } + + // insert a new line below + lc = &area->text[(y_max * total_width) - area->right_shadow - 1]; + std::memcpy (&nc, lc, sizeof(nc)); + nc.code = ' '; + dc = &area->text[y_max * total_width]; + std::fill_n (dc, area->width, nc); + area->changes[y_max].xmin = 0; + area->changes[y_max].xmax = uInt(area->width - 1); + area->has_changes = true; + + if ( area == vdesktop ) + { + if ( TCAP(fc::t_scroll_forward) ) + { + setTermXY (0, vdesktop->height); + FTerm::scrollTermForward(); + putArea (FPoint(1, 1), vdesktop); + + // avoid update lines from 0 to (y_max - 1) + for (int y{0}; y < y_max; y++) + { + area->changes[y].xmin = uInt(area->width - 1); + area->changes[y].xmax = 0; + } + } + } +} + +//---------------------------------------------------------------------- +void FVTerm::scrollAreaReverse (term_area* area) +{ + // Scrolls the entire area one line down + + charData nc{}; // next character + charData* lc{}; // last character + charData* dc{}; // destination character + + if ( ! area ) + return; + + if ( area->height <= 1 ) + return; + + int length = area->width; + int total_width = area->width + area->right_shadow; + int y_max = area->height - 1; + + for (int y = y_max; y > 0; y--) + { + int pos1 = (y - 1) * total_width; + int pos2 = y * total_width; + auto sc = &area->text[pos1]; // source character + dc = &area->text[pos2]; + std::memcpy (dc, sc, sizeof(*dc) * unsigned(length)); + area->changes[y].xmin = 0; + area->changes[y].xmax = uInt(area->width - 1); + } + + // insert a new line above + lc = &area->text[total_width]; + std::memcpy (&nc, lc, sizeof(nc)); + nc.code = ' '; + dc = &area->text[0]; + std::fill_n (dc, area->width, nc); + area->changes[0].xmin = 0; + area->changes[0].xmax = uInt(area->width - 1); + area->has_changes = true; + + if ( area == vdesktop ) + { + if ( TCAP(fc::t_scroll_reverse) ) + { + setTermXY (0, 0); + FTerm::scrollTermReverse(); + putArea (FPoint(1, 1), vdesktop); + + // avoid update lines from 1 to y_max + for (int y{1}; y <= y_max; y++) + { + area->changes[y].xmin = uInt(area->width - 1); + area->changes[y].xmax = 0; + } + } + } +} + +//---------------------------------------------------------------------- +void FVTerm::clearArea (term_area* area, int fillchar) +{ + // Clear the area with the current attributes + + charData nc{}; // next character + + // Current attributes with a space character + std::memcpy (&nc, &next_attribute, sizeof(nc)); + nc.code = fillchar; + + if ( ! (area && area->text) ) + { + clearTerm (fillchar); + return; + } + + uInt w = uInt(area->width + area->right_shadow); + + if ( area->right_shadow == 0 ) + { + if ( clearFullArea(area, nc) ) + return; + } + else + clearAreaWithShadow(area, nc); + + for (int i{0}; i < area->height; i++) + { + area->changes[i].xmin = 0; + area->changes[i].xmax = w - 1; + + if ( nc.attr.bit.transparent + || nc.attr.bit.trans_shadow + || nc.attr.bit.inherit_bg ) + area->changes[i].trans_count = w; + else if ( area->right_shadow != 0 ) + area->changes[i].trans_count = uInt(area->right_shadow); + else + area->changes[i].trans_count = 0; + } + + for (int i{0}; i < area->bottom_shadow; i++) + { + int y = area->height + i; + area->changes[y].xmin = 0; + area->changes[y].xmax = w - 1; + area->changes[y].trans_count = w; + } + + area->has_changes = true; +} + +//---------------------------------------------------------------------- +void FVTerm::processTerminalUpdate() +{ + // Retains terminal updates if there are unprocessed inputs + static constexpr int max_skip = 8; + + if ( ! terminal_update_pending ) + return; + + if ( ! keyboard->isInputDataPending() ) + { + updateTerminal(); + terminal_update_pending = false; + skipped_terminal_update = 0; + } + else if ( skipped_terminal_update > max_skip ) + { + force_terminal_update = true; + updateTerminal(); + force_terminal_update = false; + terminal_update_pending = false; + skipped_terminal_update = 0; + } + else + skipped_terminal_update++; +} + +//---------------------------------------------------------------------- +void FVTerm::startTerminalUpdate() +{ + // Pauses the terminal updates for the printing phase + terminal_update_complete = false; +} + +//---------------------------------------------------------------------- +void FVTerm::finishTerminalUpdate() +{ + // After the printing phase is completed, the terminal will be updated + terminal_update_complete = true; +} + +//---------------------------------------------------------------------- +void FVTerm::flush_out() +{ + while ( ! output_buffer->empty() ) + { + static FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); + FTermPutchar (output_buffer->front()); + output_buffer->pop(); + } + + std::fflush(stdout); +} + + +// private methods of FVTerm +//---------------------------------------------------------------------- +inline void FVTerm::setTextToDefault ( term_area* area + , const FSize& size ) +{ + charData default_char; + line_changes unchanged; + + default_char.code = ' '; + default_char.fg_color = fc::Default; + default_char.bg_color = fc::Default; + default_char.attr.byte[0] = 0; + default_char.attr.byte[1] = 0; + default_char.attr.byte[2] = 0; + + std::fill_n (area->text, size.getArea(), default_char); + + unchanged.xmin = uInt(size.getWidth()); + unchanged.xmax = 0; + unchanged.trans_count = 0; + + std::fill_n (area->changes, size.getHeight(), unchanged); +} + +//---------------------------------------------------------------------- +inline bool FVTerm::reallocateTextArea ( term_area* area + , std::size_t height + , std::size_t size ) +{ + // Reallocate "height" lines for changes + // and "size" bytes for the text area + + if ( area->changes != 0 ) + delete[] area->changes; + + if ( area->text != 0 ) + delete[] area->text; + + try + { + area->changes = new line_changes[height]; + area->text = new charData[size]; + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << ex.what() << std::endl; + return false; + } + + return true; +} + +//---------------------------------------------------------------------- +inline bool FVTerm::reallocateTextArea (term_area* area, std::size_t size) +{ + // Reallocate "size" bytes for the text area + + if ( area->text != 0 ) + delete[] area->text; + + try + { + area->text = new charData[size]; + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << ex.what() << std::endl; + return false; + } + + return true; +} + //---------------------------------------------------------------------- FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos , term_area* area ) @@ -1092,26 +1606,6 @@ bool FVTerm::updateVTermCharacter ( term_area* area return true; } -//---------------------------------------------------------------------- -void FVTerm::callPreprocessingHandler (term_area* area) -{ - // Call preprocessing handler - - if ( ! area->preprocessing_call.empty() ) - { - auto iter = area->preprocessing_call.begin(); - auto end = area->preprocessing_call.end(); - - while ( iter != end ) - { - // call the preprocessing handler - auto preprocessingHandler = iter->function; - preprocessingHandler(); - ++iter; - } - } -} - //---------------------------------------------------------------------- void FVTerm::updateVTerm() { @@ -1119,7 +1613,7 @@ void FVTerm::updateVTerm() if ( vdesktop && vdesktop->has_changes ) { - updateVTerm(vdesktop); + putArea(vdesktop); vdesktop->has_changes = false; } @@ -1128,170 +1622,73 @@ void FVTerm::updateVTerm() if ( ! widget->getWindowList() || widget->getWindowList()->empty() ) return; - auto iter = widget->getWindowList()->begin(); - auto end = widget->getWindowList()->end(); - - for (; iter != end; ++iter) + for (auto&& window : *(widget->getWindowList())) { - auto win = (*iter)->getVWin(); + auto vwin = window->getVWin(); - if ( ! win ) + if ( ! (vwin && vwin->visible) ) continue; - if ( ! win->visible ) - continue; - - if ( win->has_changes ) + if ( vwin->has_changes ) { - updateVTerm(win); - win->has_changes = false; + putArea(vwin); + vwin->has_changes = false; } - else if ( ! win->preprocessing_call.empty() ) + else if ( hasChildAreaChanges(vwin) ) { - auto iter2 = win->preprocessing_call.begin(); - auto end2 = win->preprocessing_call.end(); - - while ( iter2 != end2 ) - { - if ( iter2->instance->child_print_area - && iter2->instance->child_print_area->has_changes ) - { - updateVTerm(win); - iter2->instance->child_print_area->has_changes = false; - break; - } - - ++iter2; - } + putArea(vwin); // and call the child area processing handler there + clearChildAreaChanges(vwin); } } } //---------------------------------------------------------------------- -void FVTerm::updateVTerm (term_area* area) +void FVTerm::callPreprocessingHandler (term_area* area) { - // Update area data on VTerm + // Call preprocessing handler - if ( ! area || ! area->visible ) + if ( area->preproc_list.empty() ) return; - int ax = area->offset_left; - int ay = area->offset_top; - int width = area->width + area->right_shadow; - int height = area->height + area->bottom_shadow; - int ol{0}; // Outside left - int y_end{}; - - // Call the processing handler methods - callPreprocessingHandler(area); - - if ( ax < 0 ) + for (auto&& pcall : area->preproc_list) { - ol = std::abs(ax); - ax = 0; + // call the preprocessing handler + auto preprocessingHandler = pcall.function; + preprocessingHandler(); } - - if ( height + ay > vterm->height ) - y_end = vterm->height - ay; - else - y_end = height; - - for (int y{0}; y < y_end; y++) // Line loop - { - bool modified{false}; - int line_xmin = int(area->changes[y].xmin); - int line_xmax = int(area->changes[y].xmax); - - if ( line_xmin > line_xmax ) - continue; - - if ( ax == 0 ) - line_xmin = ol; - - if ( width + 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 - { - // Global terminal positions - int tx = ax + x; - int ty = ay + y; - - if ( tx < 0 || ty < 0 ) - continue; - - tx -= ol; - - if ( updateVTermCharacter(area, FPoint(x, y), FPoint(tx, ty)) ) - modified = true; - - if ( ! modified ) - line_xmin++; // Don't update covered character - } - - int _xmin = ax + line_xmin - ol; - int _xmax = ax + line_xmax; - - if ( _xmin < int(vterm->changes[ay + y].xmin) ) - vterm->changes[ay + y].xmin = uInt(_xmin); - - if ( _xmax >= vterm->width ) - _xmax = vterm->width - 1; - - if ( _xmax > int(vterm->changes[ay + y].xmax) ) - vterm->changes[ay + y].xmax = uInt(_xmax); - - area->changes[y].xmin = uInt(width); - area->changes[y].xmax = 0; - } - - vterm->has_changes = true; - updateVTermCursor(area); } //---------------------------------------------------------------------- -bool FVTerm::updateVTermCursor (term_area* area) +bool FVTerm::hasChildAreaChanges (term_area* area) { if ( ! area ) return false; - if ( area != active_area ) - return false; - - if ( ! area->visible ) - return false; - - if ( area->input_cursor_visible ) + for (auto&& pcall : area->preproc_list) { - // area offset - int ax = area->offset_left; - int ay = area->offset_top; - // area cursor position - int cx = area->input_cursor_x; - int cy = area->input_cursor_y; - // terminal position - int x = ax + cx; - int y = ay + cy; - - if ( isInsideArea (FPoint(cx, cy), area) - && isInsideTerminal (FPoint(x, y)) - && isCovered (FPoint(x, y), area) == non_covered ) - { - vterm->input_cursor_x = x; - vterm->input_cursor_y = y; - vterm->input_cursor_visible = true; - vterm->has_changes = true; + if ( pcall.instance + && pcall.instance->child_print_area + && pcall.instance->child_print_area->has_changes ) return true; - } } - vterm->input_cursor_visible = false; return false; } +//---------------------------------------------------------------------- +void FVTerm::clearChildAreaChanges (term_area* area) +{ + if ( ! area ) + return; + + for (auto&& pcall : area->preproc_list) + { + if ( pcall.instance + && pcall.instance->child_print_area ) + pcall.instance->child_print_area->has_changes = false; + } +} + //---------------------------------------------------------------------- bool FVTerm::isInsideArea (const FPoint& pos, term_area* area) { @@ -1307,339 +1704,6 @@ bool FVTerm::isInsideArea (const FPoint& pos, term_area* area) return false; } -//---------------------------------------------------------------------- -void FVTerm::setAreaCursor ( const FPoint& pos - , bool visible - , term_area* area ) -{ - if ( ! area ) - return; - - area->input_cursor_x = pos.getX() - 1; - area->input_cursor_y = pos.getY() - 1; - area->input_cursor_visible = visible; -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (const FPoint& pos, term_area* area) -{ - // Copies a block from the virtual terminal position to the given area - - if ( ! area ) - return; - - int ax = pos.getX() - 1; - int ay = pos.getY() - 1; - int y_end{}, length{}; - - if ( area->height + ay > vterm->height ) - y_end = area->height - ay; - else - y_end = area->height; - - if ( area->width + ax > vterm->width ) - length = vterm->width - ax; - else - length = area->width; - - for (int y{0}; y < y_end; y++) // line loop - { - auto tc = &vterm->text[(ay + y) * vterm->width + ax]; // terminal character - auto ac = &area->text[y * area->width]; // area character - std::memcpy (ac, tc, sizeof(*ac) * unsigned(length)); - - if ( int(area->changes[y].xmin) > 0 ) - area->changes[y].xmin = 0; - - if ( int(area->changes[y].xmax) < length - 1 ) - area->changes[y].xmax = uInt(length - 1); - } -} - -//---------------------------------------------------------------------- -void FVTerm::getArea (const FRect& box, term_area* area) -{ - // Copies a block from the virtual terminal rectangle to the given area - - if ( ! area ) - return; - - int x = box.getX(); - int y = box.getY(); - int w = int(box.getWidth()); - int h = int(box.getHeight()); - int dx = x - area->offset_left + 1; - int dy = y - area->offset_top + 1; - int y_end{}, length{}; - - if ( x < 0 || y < 0 ) - return; - - if ( y - 1 + h > vterm->height ) - y_end = vterm->height - y + 1; - else - y_end = h - 1; - - if ( x - 1 + w > vterm->width ) - length = vterm->width - x + 1; - else - length = w; - - if ( length < 1 ) - return; - - for (int _y = 0; _y < y_end; _y++) // line loop - { - int line_len = area->width + area->right_shadow; - auto tc = &vterm->text[(y + _y - 1) * vterm->width + x - 1]; // terminal character - auto ac = &area->text[(dy + _y) * line_len + dx]; // area character - std::memcpy (ac, tc, sizeof(*ac) * unsigned(length)); - - if ( int(area->changes[dy + _y].xmin) > dx ) - area->changes[dy + _y].xmin = uInt(dx); - - if ( int(area->changes[dy + _y].xmax) < dx + length - 1 ) - area->changes[dy + _y].xmax = uInt(dx + length - 1); - } -} - -//---------------------------------------------------------------------- -void FVTerm::putArea (const FPoint& pos, term_area* area) -{ - // Copies the given area block to the virtual terminal position - - charData* tc{}; // terminal character - charData* ac{}; // area character - - if ( ! area || ! area->visible ) - return; - - int ax = pos.getX() - 1; - int ay = pos.getY() - 1; - int width = area->width + area->right_shadow; - int height = area->height + area->bottom_shadow; - int ol{0}; // outside left - int y_end{}, length{}; - - if ( ax < 0 ) - { - ol = std::abs(ax); - ax = 0; - } - - if ( ay + height > vterm->height ) - y_end = vterm->height - ay; - else - y_end = height; - - if ( width - ol + ax > vterm->width ) - length = vterm->width - ax; - else - length = width - ol; - - if ( length < 1 ) - return; - - for (int y{0}; y < y_end; y++) // line loop - { - if ( area->changes[y].trans_count == 0 ) - { - // Line has only covered characters - ac = &area->text[y * width + ol]; - tc = &vterm->text[(ay + y) * vterm->width + ax]; - putAreaLine (ac, tc, length); - } - else - { - // Line has one or more transparent characters - for (int x{0}; x < length; x++) // column loop - { - int cx = ax + x; - int cy = ay + y; - ac = &area->text[y * width + ol + x]; - tc = &vterm->text[cy * vterm->width + cx]; - putAreaCharacter (FPoint(cx + 1, cy + 1), area->widget, ac, tc); - } - } - - if ( ax < int(vterm->changes[ay + y].xmin) ) - vterm->changes[ay + y].xmin = uInt(ax); - - if ( ax + length - 1 > int(vterm->changes[ay + y].xmax) ) - vterm->changes[ay + y].xmax = uInt(ax + length - 1); - } - - vterm->has_changes = true; -} - -//---------------------------------------------------------------------- -void FVTerm::scrollAreaForward (term_area* area) -{ - // Scrolls the entire area up line down - charData nc{}; // next character - charData* lc{}; // last character - charData* dc{}; // destination character - - if ( ! area ) - return; - - if ( area->height <= 1 ) - return; - - int length = area->width; - int total_width = area->width + area->right_shadow; - int y_max = area->height - 1; - - for (int y{0}; y < y_max; y++) - { - int pos1 = y * total_width; - int pos2 = (y + 1) * total_width; - auto sc = &area->text[pos2]; // source character - dc = &area->text[pos1]; - std::memcpy (dc, sc, sizeof(*dc) * unsigned(length)); - area->changes[y].xmin = 0; - area->changes[y].xmax = uInt(area->width - 1); - } - - // insert a new line below - lc = &area->text[(y_max * total_width) - area->right_shadow - 1]; - std::memcpy (&nc, lc, sizeof(nc)); - nc.code = ' '; - dc = &area->text[y_max * total_width]; - std::fill_n (dc, area->width, nc); - area->changes[y_max].xmin = 0; - area->changes[y_max].xmax = uInt(area->width - 1); - area->has_changes = true; - - if ( area == vdesktop ) - { - if ( TCAP(fc::t_scroll_forward) ) - { - setTermXY (0, vdesktop->height); - FTerm::scrollTermForward(); - putArea (FPoint(1, 1), vdesktop); - - // avoid update lines from 0 to (y_max - 1) - for (int y{0}; y < y_max; y++) - { - area->changes[y].xmin = uInt(area->width - 1); - area->changes[y].xmax = 0; - } - } - } -} - -//---------------------------------------------------------------------- -void FVTerm::scrollAreaReverse (term_area* area) -{ - // Scrolls the entire area one line down - - charData nc{}; // next character - charData* lc{}; // last character - charData* dc{}; // destination character - - if ( ! area ) - return; - - if ( area->height <= 1 ) - return; - - int length = area->width; - int total_width = area->width + area->right_shadow; - int y_max = area->height - 1; - - for (int y = y_max; y > 0; y--) - { - int pos1 = (y - 1) * total_width; - int pos2 = y * total_width; - auto sc = &area->text[pos1]; // source character - dc = &area->text[pos2]; - std::memcpy (dc, sc, sizeof(*dc) * unsigned(length)); - area->changes[y].xmin = 0; - area->changes[y].xmax = uInt(area->width - 1); - } - - // insert a new line above - lc = &area->text[total_width]; - std::memcpy (&nc, lc, sizeof(nc)); - nc.code = ' '; - dc = &area->text[0]; - std::fill_n (dc, area->width, nc); - area->changes[0].xmin = 0; - area->changes[0].xmax = uInt(area->width - 1); - area->has_changes = true; - - if ( area == vdesktop ) - { - if ( TCAP(fc::t_scroll_reverse) ) - { - setTermXY (0, 0); - FTerm::scrollTermReverse(); - putArea (FPoint(1, 1), vdesktop); - - // avoid update lines from 1 to y_max - for (int y{1}; y <= y_max; y++) - { - area->changes[y].xmin = uInt(area->width - 1); - area->changes[y].xmax = 0; - } - } - } -} - -//---------------------------------------------------------------------- -void FVTerm::clearArea (term_area* area, int fillchar) -{ - // Clear the area with the current attributes - - charData nc{}; // next character - - // Current attributes with a space character - std::memcpy (&nc, &next_attribute, sizeof(nc)); - nc.code = fillchar; - - if ( ! (area && area->text) ) - { - clearTerm (fillchar); - return; - } - - uInt w = uInt(area->width + area->right_shadow); - - if ( area->right_shadow == 0 ) - { - if ( clearFullArea(area, nc) ) - return; - } - else - clearAreaWithShadow(area, nc); - - for (int i{0}; i < area->height; i++) - { - area->changes[i].xmin = 0; - area->changes[i].xmax = w - 1; - - if ( nc.attr.bit.transparent - || nc.attr.bit.trans_shadow - || nc.attr.bit.inherit_bg ) - area->changes[i].trans_count = w; - else if ( area->right_shadow != 0 ) - area->changes[i].trans_count = uInt(area->right_shadow); - else - area->changes[i].trans_count = 0; - } - - for (int i{0}; i < area->bottom_shadow; i++) - { - int y = area->height + i; - area->changes[y].xmin = 0; - area->changes[y].xmax = w - 1; - area->changes[y].trans_count = w; - } - - area->has_changes = true; -} - //---------------------------------------------------------------------- charData FVTerm::generateCharacter (const FPoint& pos) { @@ -1792,62 +1856,6 @@ charData FVTerm::getOverlappedCharacter (const FPoint& pos, FVTerm* obj) return getCharacter (overlapped_character, pos, obj); } -//---------------------------------------------------------------------- -void FVTerm::processTerminalUpdate() -{ - // Retains terminal updates if there are unprocessed inputs - static constexpr int max_skip = 8; - - if ( ! terminal_update_pending ) - return; - - if ( ! keyboard->isInputDataPending() ) - { - updateTerminal(); - terminal_update_pending = false; - skipped_terminal_update = 0; - } - else if ( skipped_terminal_update > max_skip ) - { - force_terminal_update = true; - updateTerminal(); - force_terminal_update = false; - terminal_update_pending = false; - skipped_terminal_update = 0; - } - else - skipped_terminal_update++; -} - -//---------------------------------------------------------------------- -void FVTerm::startTerminalUpdate() -{ - // Pauses the terminal updates for the printing phase - terminal_update_complete = false; -} - -//---------------------------------------------------------------------- -void FVTerm::finishTerminalUpdate() -{ - // After the printing phase is completed, the terminal will be updated - terminal_update_complete = true; -} - -//---------------------------------------------------------------------- -void FVTerm::flush_out() -{ - while ( ! output_buffer->empty() ) - { - static FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); - FTermPutchar (output_buffer->front()); - output_buffer->pop(); - } - - std::fflush(stdout); -} - - -// private methods of FVTerm //---------------------------------------------------------------------- void FVTerm::init (bool disable_alt_screen) { @@ -2825,7 +2833,7 @@ inline bool FVTerm::isTermSizeChanged() return false; auto old_term_geometry = data->getTermGeometry(); - getFTerm().detectTermSize(); + FTerm::detectTermSize(); auto term_geometry = data->getTermGeometry(); term_geometry.move (-1, -1); diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 650ffacc..c77bc25e 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -39,18 +39,18 @@ namespace finalcut static FWidget* rootObject{nullptr}; // static class attributes -FStatusBar* FWidget::statusbar{nullptr}; -FMenuBar* FWidget::menubar{nullptr}; -FWidget* FWidget::show_root_widget{nullptr}; -FWidget* FWidget::redraw_root_widget{nullptr}; -FWidget::widgetList* FWidget::window_list{nullptr}; -FWidget::widgetList* FWidget::dialog_list{nullptr}; -FWidget::widgetList* FWidget::always_on_top_list{nullptr}; -FWidget::widgetList* FWidget::close_widget{nullptr}; -FWidgetColors FWidget::wcolors{}; -bool FWidget::init_desktop{false}; -bool FWidget::hideable{false}; -uInt FWidget::modal_dialog_counter{}; +FStatusBar* FWidget::statusbar{nullptr}; +FMenuBar* FWidget::menubar{nullptr}; +FWidget* FWidget::show_root_widget{nullptr}; +FWidget* FWidget::redraw_root_widget{nullptr}; +FWidget::FWidgetList* FWidget::window_list{nullptr}; +FWidget::FWidgetList* FWidget::dialog_list{nullptr}; +FWidget::FWidgetList* FWidget::always_on_top_list{nullptr}; +FWidget::FWidgetList* FWidget::close_widget{nullptr}; +FWidgetColors FWidget::wcolors{}; +bool FWidget::init_desktop{false}; +bool FWidget::hideable{false}; +uInt FWidget::modal_dialog_counter{}; //---------------------------------------------------------------------- // class FWidget @@ -170,9 +170,8 @@ FWidget* FWidget::getFirstFocusableWidget (FObjectList list) return 0; auto iter = list.begin(); - auto last = list.end(); - while ( iter != last ) + while ( iter != list.end() ) { if ( (*iter)->isWidget() ) { @@ -194,7 +193,6 @@ FWidget* FWidget::getLastFocusableWidget (FObjectList list) if ( list.empty() ) return 0; - auto first = list.begin(); auto iter = list.end(); do @@ -209,19 +207,11 @@ FWidget* FWidget::getLastFocusableWidget (FObjectList list) if ( child->isEnabled() && child->acceptFocus() ) return child; } - while ( iter != first ); + while ( iter != list.begin() ); return 0; } -//---------------------------------------------------------------------- -FPoint FWidget::getPrintPos() -{ - const auto cur = getPrintCursor(); - return FPoint ( cur.getX() - woffset.getX1() - getX() + 1 - , cur.getY() - woffset.getY1() - getY() + 1 ); -} - //---------------------------------------------------------------------- std::vector& FWidget::doubleFlatLine_ref (fc::sides side) { @@ -248,6 +238,14 @@ std::vector& FWidget::doubleFlatLine_ref (fc::sides side) return double_flatline_mask.left; } +//---------------------------------------------------------------------- +FPoint FWidget::getPrintPos() +{ + const auto cur = getPrintCursor(); + return FPoint ( cur.getX() - woffset.getX1() - getX() + 1 + , cur.getY() - woffset.getY1() - getY() + 1 ); +} + //---------------------------------------------------------------------- void FWidget::setMainWidget (FWidget* obj) { @@ -757,33 +755,25 @@ void FWidget::setDoubleFlatLine (fc::sides side, int pos, bool bit) } //---------------------------------------------------------------------- -FWidget* FWidget::childWidgetAt (FWidget* p, const FPoint& pos) +FWidget* FWidget::childWidgetAt (const FPoint& pos) { - if ( p && p->hasChildren() ) + if ( ! hasChildren() ) + return 0; + + for (auto&& child : getChildren()) { - auto iter = p->begin(); - auto last = p->end(); + if ( ! child->isWidget() ) + continue; - while ( iter != last ) + auto widget = static_cast(child); + + if ( widget->isEnabled() + && widget->isShown() + && ! widget->isWindowWidget() + && widget->getTermGeometry().contains(pos) ) { - if ( ! (*iter)->isWidget() ) - { - ++iter; - continue; - } - - auto widget = static_cast(*iter); - - if ( widget->isEnabled() - && widget->isShown() - && ! widget->isWindowWidget() - && widget->getTermGeometry().contains(pos) ) - { - auto child = childWidgetAt(widget, pos); - return ( child != 0 ) ? child : widget; - } - - ++iter; + auto child = widget->childWidgetAt(pos); + return ( child != 0 ) ? child : widget; } } @@ -797,22 +787,18 @@ int FWidget::numOfFocusableChildren() return 0; int num{0}; - auto iter = FObject::begin(); - auto last = FObject::end(); - while ( iter != last ) + for (auto&& child : getChildren()) { - if ( (*iter)->isWidget() ) + if ( child->isWidget() ) { - auto widget = static_cast(*iter); + auto widget = static_cast(child); if ( widget->isShown() && widget->acceptFocus() && ! widget->isWindowWidget() ) num++; } - - ++iter; } return num; @@ -921,19 +907,14 @@ void FWidget::emitCallback (const FString& emit_signal) if ( callback_objects.empty() ) return; - auto iter = callback_objects.begin(); - auto last = callback_objects.end(); - - while ( iter != last ) + for (auto&& cback : callback_objects) { - if ( iter->cb_signal == emit_signal ) + if ( cback.cb_signal == emit_signal ) { // Calling the stored function pointer - auto callback = iter->cb_function; - callback (this, iter->data); + auto callback = cback.cb_function; + callback (this, cback.data); } - - ++iter; } } @@ -1073,20 +1054,15 @@ void FWidget::show() if ( hasChildren() ) { - auto iter = FObject::begin(); - auto last = FObject::end(); - - while ( iter != last ) + for (auto&& child : getChildren()) { - if ( (*iter)->isWidget() ) + if ( child->isWidget() ) { - auto widget = static_cast(*iter); + auto widget = static_cast(child); if ( ! widget->flags.hidden ) widget->show(); } - - ++iter; } } @@ -1208,22 +1184,6 @@ bool FWidget::focusLastChild() return false; } -//---------------------------------------------------------------------- -void FWidget::detectTermSize() -{ - auto r = rootObject; - FTerm::detectTermSize(); - r->adjust_wsize.setRect (1, 1, getDesktopWidth(), getDesktopHeight()); - r->woffset.setRect (0, 0, getDesktopWidth(), getDesktopHeight()); - r->wclient_offset.setCoordinates - ( - r->padding.left, - r->padding.top, - int(getDesktopWidth()) - 1 - r->padding.right, - int(getDesktopHeight()) - 1 - r->padding.bottom - ); -} - //---------------------------------------------------------------------- void FWidget::move (const FPoint& pos) { @@ -1231,201 +1191,6 @@ void FWidget::move (const FPoint& pos) adjust_wsize.move(pos); } -//---------------------------------------------------------------------- -void FWidget::drawShadow() -{ - if ( isMonochron() && ! flags.trans_shadow ) - return; - - if ( (getEncoding() == fc::VT100 && ! flags.trans_shadow) - || (getEncoding() == fc::ASCII && ! flags.trans_shadow) ) - { - clearShadow(); - return; - } - - int x1 = 1; - int x2 = int(getWidth()); - int y1 = 1; - int y2 = int(getHeight()); - - if ( flags.trans_shadow ) - { - // transparent shadow - drawTransparentShadow (x1, y1, x2, y2); - } - else - { - // non-transparent shadow - drawBlockShadow (x1, y1, x2, y2); - } -} - -//---------------------------------------------------------------------- -void FWidget::clearShadow() -{ - if ( isMonochron() ) - return; - - int w = int(getWidth()); - int h = int(getHeight()); - - if ( isWindowWidget() ) - { - setColor (wcolors.shadow_fg, wcolors.shadow_bg); - setInheritBackground(); // current background color will be ignored - } - else if ( auto p = getParentWidget() ) - setColor (wcolors.shadow_fg, p->getBackgroundColor()); - - if ( w <= woffset.getX2() ) - { - for (std::size_t y{1}; y <= getHeight(); y++) - { - print() << FPoint(w + 1, int(y)) << ' '; // clear █ - } - } - - if ( h <= woffset.getY2() ) - { - print() << FPoint(2, h + 1); - - for (std::size_t i{1}; i <= getWidth(); i++) - print (' '); // clear ▀ - } - - if ( isWindowWidget() ) - unsetInheritBackground(); -} - -//---------------------------------------------------------------------- -void FWidget::drawFlatBorder() -{ - if ( ! isNewFont() ) - return; - - int x1 = 1; - int x2 = int(getWidth() + 1); - int y1 = 0; - int y2 = int(getHeight() + 1); - - if ( auto p = getParentWidget() ) - setColor (wcolors.dialog_fg, p->getBackgroundColor()); - else - setColor (wcolors.dialog_fg, wcolors.dialog_bg); - - for (std::size_t y{0}; y < getHeight(); y++) - { - print() << FPoint(x1 - 1, y1 + int(y) + 1); - - if ( double_flatline_mask.left[uLong(y)] ) - // left+right line (on left side) - print (fc::NF_rev_border_line_right_and_left); - else - // right line (on left side) - print (fc::NF_rev_border_line_right); - } - - print() << FPoint(x2, y1 + 1); - - for (std::size_t y{0}; y < getHeight(); y++) - { - if ( double_flatline_mask.right[y] ) - // left+right line (on right side) - print (fc::NF_rev_border_line_right_and_left); - else - // left line (on right side) - print (fc::NF_border_line_left); - - print() << FPoint(x2, y1 + int(y) + 2); - } - - print() << FPoint(x1, y1); - - for (std::size_t x{0}; x < getWidth(); x++) - { - if ( double_flatline_mask.top[x] ) - // top+bottom line (at top) - print (fc::NF_border_line_up_and_down); - else - // bottom line (at top) - print (fc::NF_border_line_bottom); - } - - print() << FPoint(x1, y2); - - for (std::size_t x{0}; x < getWidth(); x++) - { - if ( double_flatline_mask.bottom[x] ) - // top+bottom line (at bottom) - print (fc::NF_border_line_up_and_down); - else - // top line (at bottom) - print (fc::NF_border_line_upper); - } -} - -//---------------------------------------------------------------------- -void FWidget::clearFlatBorder() -{ - if ( ! isNewFont() ) - return; - - int x1 = 1; - int x2 = int(getWidth() + 1); - int y1 = 0; - int y2 = int(getHeight() + 1); - - if ( auto p = getParentWidget() ) - setColor (wcolors.dialog_fg, p->getBackgroundColor()); - else - setColor (wcolors.dialog_fg, wcolors.dialog_bg); - - // clear on left side - for (std::size_t y{0}; y < getHeight(); y++) - { - print() << FPoint(x1 - 1, y1 + int(y) + 1); - - if ( double_flatline_mask.left[y] ) - print (fc::NF_border_line_left); - else - print (' '); - } - - // clear on right side - for (std::size_t y{0}; y < getHeight(); y++) - { - print() << FPoint(x2, y1 + int(y) + 1); - - if ( double_flatline_mask.right[y] ) - print (fc::NF_rev_border_line_right); - else - print (' '); - } - - // clear at top - print() << FPoint(x1, y1); - - for (std::size_t x{0}; x < getWidth(); x++) - { - if ( double_flatline_mask.top[x] ) - print (fc::NF_border_line_upper); - else - print (' '); - } - - // clear at bottom - print() << FPoint(x1, y2); - - for (std::size_t x{0}; x < getWidth(); x++) - { - if ( double_flatline_mask.bottom[x] ) - print (fc::NF_border_line_bottom); - else - print (' '); - } -} - //---------------------------------------------------------------------- void FWidget::quit() { @@ -1566,19 +1331,15 @@ void FWidget::adjustSize() if ( hasChildren() ) { - auto iter = FObject::begin(); - auto last = FObject::end(); - - while ( iter != last ) + for (auto&& child : getChildren()) { - if ( (*iter)->isWidget() ) + if ( child->isWidget() ) { - auto widget = static_cast(*iter); + auto widget = static_cast(child); if ( ! widget->isWindowWidget() ) widget->adjustSize(); } - ++iter; } } } @@ -1940,10 +1701,10 @@ void FWidget::init() try { // Initialize widget lists - window_list = new widgetList(); - dialog_list = new widgetList(); - always_on_top_list = new widgetList(); - close_widget = new widgetList(); + window_list = new FWidgetList(); + dialog_list = new FWidgetList(); + always_on_top_list = new FWidgetList(); + close_widget = new FWidgetList(); } catch (const std::bad_alloc& ex) { @@ -2175,22 +1936,16 @@ void FWidget::drawWindows() if ( ! window_list || window_list->empty() ) return; - auto iter = window_list->begin(); - auto last = window_list->end(); - - while ( iter != last ) + for (auto&& window : *window_list) { - if ( (*iter)->isShown() ) + if ( window->isShown() ) { - auto win = (*iter)->getVWin(); + auto win = window->getVWin(); int w = win->width + win->right_shadow; int h = win->height + win->bottom_shadow; std::fill_n (win->text, w * h, default_char); - - (*iter)->redraw(); + window->redraw(); } - - ++iter; } } @@ -2201,97 +1956,18 @@ void FWidget::drawChildren() if ( ! hasChildren() ) return; - auto iter = FObject::begin(); - auto last = FObject::end(); - - while ( iter != last ) + for (auto&& child : getChildren()) { - if ( (*iter)->isWidget() ) + if ( child->isWidget() ) { - auto widget = static_cast(*iter); + auto widget = static_cast(child); if ( widget->isShown() && ! widget->isWindowWidget() ) widget->redraw(); } - - ++iter; } } -//---------------------------------------------------------------------- -void FWidget::drawTransparentShadow (int x1, int y1, int x2, int y2) -{ - // transparent shadow - - setTransparent(); - print() << FPoint(x2 + 1, y1) << " "; - unsetTransparent(); - - setColor (wcolors.shadow_bg, wcolors.shadow_fg); - setTransShadow(); - - for (std::size_t y{1}; y < getHeight(); y++) - { - print() << FPoint(x2 + 1, y1 + int(y)) << " "; - } - - unsetTransShadow(); - setTransparent(); - print() << FPoint(x1, y2 + 1) << " "; - unsetTransparent(); - - setColor (wcolors.shadow_bg, wcolors.shadow_fg); - setTransShadow(); - - for (std::size_t x{2}; x <= getWidth() + 1; x++) - print (' '); - - unsetTransShadow(); - - if ( isMonochron() ) - setReverse(false); -} - -//---------------------------------------------------------------------- -void FWidget::drawBlockShadow (int x1, int y1, int x2, int y2) -{ - // non-transparent shadow - - if ( ! hasShadowCharacter() ) - return; - - print() << FPoint(x2 + 1, y1); - - if ( isWindowWidget() ) - { - setColor (wcolors.shadow_fg, wcolors.shadow_bg); - setInheritBackground(); // current background color will be ignored - } - else if ( auto p = getParentWidget() ) - setColor (wcolors.shadow_fg, p->getBackgroundColor()); - - print (fc::LowerHalfBlock); // ▄ - - if ( isWindowWidget() ) - unsetInheritBackground(); - - for (std::size_t y{1}; y < getHeight(); y++) - { - print() << FPoint(x2 + 1, y1 + int(y)) << fc::FullBlock; // █ - } - - print() << FPoint(x1 + 1, y2 + 1); - - if ( isWindowWidget() ) - setInheritBackground(); - - for (std::size_t x{1}; x <= getWidth(); x++) - print (fc::UpperHalfBlock); // ▀ - - if ( isWindowWidget() ) - unsetInheritBackground(); -} - //---------------------------------------------------------------------- void FWidget::setColorTheme() { @@ -2305,6 +1981,22 @@ void FWidget::setColorTheme() // non-member functions +//---------------------------------------------------------------------- +void detectTermSize() +{ + auto r = rootObject; + FTerm::detectTermSize(); + r->adjust_wsize.setRect (1, 1, r->getDesktopWidth(), r->getDesktopHeight()); + r->woffset.setRect (0, 0, r->getDesktopWidth(), r->getDesktopHeight()); + r->wclient_offset.setCoordinates + ( + r->padding.left, + r->padding.top, + int(r->getDesktopWidth()) - 1 - r->padding.right, + int(r->getDesktopHeight()) - 1 - r->padding.bottom + ); +} + //---------------------------------------------------------------------- FKey getHotkey (const FString& text) { @@ -2382,6 +2074,273 @@ void setHotkeyViaString (FWidget* w, const FString& text) w->delAccelerator(); } +//---------------------------------------------------------------------- +void drawShadow (FWidget* w) +{ + if ( w->isMonochron() && ! w->flags.trans_shadow ) + return; + + if ( (w->getEncoding() == fc::VT100 && ! w->flags.trans_shadow) + || (w->getEncoding() == fc::ASCII && ! w->flags.trans_shadow) ) + { + clearShadow(w); + return; + } + + int x1 = 1; + int x2 = int(w->getWidth()); + int y1 = 1; + int y2 = int(w->getHeight()); + + if ( w->flags.trans_shadow ) + { + // transparent shadow + drawTransparentShadow (w, x1, y1, x2, y2); + } + else + { + // non-transparent shadow + drawBlockShadow (w, x1, y1, x2, y2); + } +} + +//---------------------------------------------------------------------- +void drawTransparentShadow (FWidget* w, int x1, int y1, int x2, int y2) +{ + // transparent shadow + + w->setTransparent(); + w->print() << FPoint(x2 + 1, y1) << " "; + w->unsetTransparent(); + w->setColor (w->wcolors.shadow_bg, w->wcolors.shadow_fg); + w->setTransShadow(); + + for (std::size_t y{1}; y < w->getHeight(); y++) + { + w->print() << FPoint(x2 + 1, y1 + int(y)) << " "; + } + + w->unsetTransShadow(); + w->setTransparent(); + w->print() << FPoint(x1, y2 + 1) << " "; + w->unsetTransparent(); + w->setColor (w->wcolors.shadow_bg, w->wcolors.shadow_fg); + w->setTransShadow(); + + for (std::size_t x{2}; x <= w->getWidth() + 1; x++) + w->print (' '); + + w->unsetTransShadow(); + + if ( w->isMonochron() ) + w->setReverse(false); +} + +//---------------------------------------------------------------------- +void drawBlockShadow (FWidget* w, int x1, int y1, int x2, int y2) +{ + // non-transparent shadow + + if ( ! w->hasShadowCharacter() ) + return; + + w->print() << FPoint(x2 + 1, y1); + + if ( w->isWindowWidget() ) + { + w->setColor (w->wcolors.shadow_fg, w->wcolors.shadow_bg); + w->setInheritBackground(); // current background color will be ignored + } + else if ( auto p = w->getParentWidget() ) + w->setColor (w->wcolors.shadow_fg, p->getBackgroundColor()); + + w->print (fc::LowerHalfBlock); // ▄ + + if ( w->isWindowWidget() ) + w->unsetInheritBackground(); + + for (std::size_t y{1}; y < w->getHeight(); y++) + { + w->print() << FPoint(x2 + 1, y1 + int(y)) << fc::FullBlock; // █ + } + + w->print() << FPoint(x1 + 1, y2 + 1); + + if ( w->isWindowWidget() ) + w->setInheritBackground(); + + for (std::size_t x{1}; x <= w->getWidth(); x++) + w->print (fc::UpperHalfBlock); // ▀ + + if ( w->isWindowWidget() ) + w->unsetInheritBackground(); +} + +//---------------------------------------------------------------------- +void clearShadow (FWidget* w) +{ + if ( w->isMonochron() ) + return; + + int width = int(w->getWidth()); + int height = int(w->getHeight()); + + if ( w->isWindowWidget() ) + { + w->setColor (w->wcolors.shadow_fg, w->wcolors.shadow_bg); + w->setInheritBackground(); // current background color will be ignored + } + else if ( auto p = w->getParentWidget() ) + w->setColor (w->wcolors.shadow_fg, p->getBackgroundColor()); + + if ( width <= w->woffset.getX2() ) + { + for (std::size_t y{1}; y <= w->getHeight(); y++) + { + w->print() << FPoint(width + 1, int(y)) << ' '; // clear █ + } + } + + if ( height <= w->woffset.getY2() ) + { + w->print() << FPoint(2, height + 1); + + for (std::size_t i{1}; i <= w->getWidth(); i++) + w->print (' '); // clear ▀ + } + + if ( w->isWindowWidget() ) + w->unsetInheritBackground(); +} + +//---------------------------------------------------------------------- +void drawFlatBorder (FWidget* w) +{ + if ( ! w->isNewFont() ) + return; + + int x1 = 1; + int x2 = int(w->getWidth() + 1); + int y1 = 0; + int y2 = int(w->getHeight() + 1); + + if ( auto p = w->getParentWidget() ) + w->setColor (w->wcolors.dialog_fg, p->getBackgroundColor()); + else + w->setColor (w->wcolors.dialog_fg, w->wcolors.dialog_bg); + + for (std::size_t y{0}; y < w->getHeight(); y++) + { + w->print() << FPoint(x1 - 1, y1 + int(y) + 1); + + if ( w->double_flatline_mask.left[uLong(y)] ) + // left+right line (on left side) + w->print (fc::NF_rev_border_line_right_and_left); + else + // right line (on left side) + w->print (fc::NF_rev_border_line_right); + } + + w->print() << FPoint(x2, y1 + 1); + + for (std::size_t y{0}; y < w->getHeight(); y++) + { + if ( w->double_flatline_mask.right[y] ) + // left+right line (on right side) + w->print (fc::NF_rev_border_line_right_and_left); + else + // left line (on right side) + w->print (fc::NF_border_line_left); + + w->print() << FPoint(x2, y1 + int(y) + 2); + } + + w->print() << FPoint(x1, y1); + + for (std::size_t x{0}; x < w->getWidth(); x++) + { + if ( w->double_flatline_mask.top[x] ) + // top+bottom line (at top) + w->print (fc::NF_border_line_up_and_down); + else + // bottom line (at top) + w->print (fc::NF_border_line_bottom); + } + + w->print() << FPoint(x1, y2); + + for (std::size_t x{0}; x < w->getWidth(); x++) + { + if ( w->double_flatline_mask.bottom[x] ) + // top+bottom line (at bottom) + w->print (fc::NF_border_line_up_and_down); + else + // top line (at bottom) + w->print (fc::NF_border_line_upper); + } +} + +//---------------------------------------------------------------------- +void clearFlatBorder (FWidget* w) +{ + if ( ! w->isNewFont() ) + return; + + int x1 = 1; + int x2 = int(w->getWidth() + 1); + int y1 = 0; + int y2 = int(w->getHeight() + 1); + + if ( auto p = w->getParentWidget() ) + w->setColor (w->wcolors.dialog_fg, p->getBackgroundColor()); + else + w->setColor (w->wcolors.dialog_fg, w->wcolors.dialog_bg); + + // clear on left side + for (std::size_t y{0}; y < w->getHeight(); y++) + { + w->print() << FPoint(x1 - 1, y1 + int(y) + 1); + + if ( w->double_flatline_mask.left[y] ) + w->print (fc::NF_border_line_left); + else + w->print (' '); + } + + // clear on right side + for (std::size_t y{0}; y < w->getHeight(); y++) + { + w->print() << FPoint(x2, y1 + int(y) + 1); + + if ( w->double_flatline_mask.right[y] ) + w->print (fc::NF_rev_border_line_right); + else + w->print (' '); + } + + // clear at top + w->print() << FPoint(x1, y1); + + for (std::size_t x{0}; x < w->getWidth(); x++) + { + if ( w->double_flatline_mask.top[x] ) + w->print (fc::NF_border_line_upper); + else + w->print (' '); + } + + // clear at bottom + w->print() << FPoint(x1, y2); + + for (std::size_t x{0}; x < w->getWidth(); x++) + { + if ( w->double_flatline_mask.bottom[x] ) + w->print (fc::NF_border_line_bottom); + else + w->print (' '); + } +} + //---------------------------------------------------------------------- inline void drawBox (FWidget* w, const FRect& r) { diff --git a/src/fwindow.cpp b/src/fwindow.cpp index 4dfcd3d7..6e26b034 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -107,18 +107,12 @@ void FWindow::setActiveWindow (FWindow* window) { // activate FWindow object window - if ( ! getWindowList() ) + if ( ! getWindowList() || getWindowList()->empty() ) return; - if ( getWindowList()->empty() ) - return; - - auto iter = getWindowList()->begin(); - auto end = getWindowList()->end(); - - while ( iter != end ) + for (auto&& win : *getWindowList()) { - if ( *iter == window ) + if ( win == window ) { if ( ! window->isWindowActive() ) { @@ -129,17 +123,15 @@ void FWindow::setActiveWindow (FWindow* window) } else { - auto w = static_cast(*iter); + auto w = static_cast(win); if ( w->isWindowActive() ) { w->deactivateWindow(); FEvent ev(fc::WindowInactive_Event); - FApplication::sendEvent(*iter, &ev); + FApplication::sendEvent(win, &ev); } } - - ++iter; } } @@ -478,7 +470,7 @@ void FWindow::delWindow (FWidget* obj) { if ( (*iter) == obj ) { - getWindowList()->erase (iter); + getWindowList()->erase(iter); return; } diff --git a/src/include/final/ffiledialog.h b/src/include/final/ffiledialog.h index 68c11833..bc7bc3c7 100644 --- a/src/include/final/ffiledialog.h +++ b/src/include/final/ffiledialog.h @@ -168,7 +168,7 @@ class FFileDialog : public FDialog typedef std::vector dirEntries; - // Method + // Methods void init(); void widgetSettings (const FPoint&); void initCallbacks(); diff --git a/src/include/final/fmouse.h b/src/include/final/fmouse.h index d4e2fe40..4bc42422 100644 --- a/src/include/final/fmouse.h +++ b/src/include/final/fmouse.h @@ -309,7 +309,7 @@ class FMouseX11 final : public FMouse // Constant static constexpr std::size_t MOUSE_BUF_SIZE = 4; - // Method + // Methods void setKeyState (int); void setMoveState (const FPoint&, int); void setButtonState (int, struct timeval*); diff --git a/src/include/final/fscrollview.h b/src/include/final/fscrollview.h index a106f672..bedd5ce9 100644 --- a/src/include/final/fscrollview.h +++ b/src/include/final/fscrollview.h @@ -123,7 +123,7 @@ class FScrollView : public FWidget bool hasBorder(); bool isViewportPrint(); - // Method + // Methods void clearArea (int = ' ') override; void scrollToX (int); void scrollToY (int); @@ -148,7 +148,7 @@ class FScrollView : public FWidget // Accessor term_area* getPrintArea() override; - // Method + // Methods void adjustSize() override; void copy2area(); diff --git a/src/include/final/ftogglebutton.h b/src/include/final/ftogglebutton.h index 94d6ecd4..90c02348 100644 --- a/src/include/final/ftogglebutton.h +++ b/src/include/final/ftogglebutton.h @@ -108,7 +108,7 @@ class FToggleButton : public FWidget // Inquiries bool isChecked(); - // Methods + // Method void hide() override; // Event handlers diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index 5af98cef..9a685c97 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -57,10 +57,6 @@ #include "final/fc.h" #include "final/fterm.h" -// Preprocessing handler macro -//#define F_PREPROC_HANDLER(i,h) -// static_cast((i)) -// , reinterpret_cast((h)) #define F_PREPROC_HANDLER(i,h) \ reinterpret_cast((i)), \ std::bind ( reinterpret_cast((h)) \ @@ -296,7 +292,6 @@ class FVTerm virtual void addPreprocessingHandler ( FVTerm* , FVTermPreprocessing ); virtual void delPreprocessingHandler (FVTerm*); - template int printf (const FString, Args&&...); int print (const FString&); @@ -316,13 +311,6 @@ class FVTerm static void redefineDefaultColors (bool); protected: - // Enumeration - enum character_type - { - overlapped_character, - covered_character - }; - // Accessor virtual term_area* getPrintArea(); term_area* getChildPrintArea() const; @@ -341,9 +329,6 @@ class FVTerm static void setInsertCursor (bool); static void setInsertCursor(); static void unsetInsertCursor(); - static bool setUTF8 (bool); - static bool setUTF8(); - static bool unsetUTF8(); // Inquiries bool hasPrintArea() const; @@ -353,6 +338,7 @@ class FVTerm static bool hasShadowCharacter(); // Methods + void createArea ( const FRect& , const FSize& , term_area*& ); @@ -361,15 +347,54 @@ class FVTerm , term_area* ); static void removeArea (term_area*&); static void restoreVTerm (const FRect&); + bool updateVTermCursor (term_area*); + static void setAreaCursor ( const FPoint& + , bool, term_area* ); + static void getArea (const FPoint&, term_area*); + static void getArea (const FRect&, term_area*); + void putArea (term_area*); + static void putArea (const FPoint&, term_area*); + void scrollAreaForward (term_area*); + void scrollAreaReverse (term_area*); + void clearArea (term_area*, int = ' '); + void processTerminalUpdate(); + static void startTerminalUpdate(); + static void finishTerminalUpdate(); + static void flush_out(); + static void initScreenSettings(); + static void changeTermSizeFinished(); + static void exitWithMessage (const FString&) + #if defined(__clang__) || defined(__GNUC__) + __attribute__((noreturn)) + #endif + ; + private: + // Enumerations + enum character_type + { + overlapped_character, + covered_character + }; + + enum exit_state + { + not_used, + used, + line_completely_printed + }; + + // Constants + // Buffer size for character output on the terminal + static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 32768; + + // Methods void setTextToDefault (term_area*, const FSize&); static bool reallocateTextArea ( term_area* , std::size_t , std::size_t ); static bool reallocateTextArea ( term_area* , std::size_t ); - static covered_state isCovered (const FPoint&, term_area*); - static void updateOverlappedColor ( term_area* , const FPoint& , const FPoint& ); @@ -387,50 +412,17 @@ class FVTerm static bool updateVTermCharacter ( term_area* , const FPoint& , const FPoint& ); - static void callPreprocessingHandler (term_area*); void updateVTerm(); - void updateVTerm (term_area*); - bool updateVTermCursor (term_area*); + static void callPreprocessingHandler (term_area*); + bool hasChildAreaChanges (term_area*); + void clearChildAreaChanges (term_area*); static bool isInsideArea (const FPoint&, term_area*); - static void setAreaCursor ( const FPoint& - , bool, term_area* ); - static void getArea (const FPoint&, term_area*); - static void getArea (const FRect&, term_area*); - static void putArea (const FPoint&, term_area*); - void scrollAreaForward (term_area*); - void scrollAreaReverse (term_area*); - void clearArea (term_area*, int = ' '); static charData generateCharacter (const FPoint&); static charData getCharacter ( character_type , const FPoint& , FVTerm* ); static charData getCoveredCharacter (const FPoint&, FVTerm*); static charData getOverlappedCharacter (const FPoint&, FVTerm*); - void processTerminalUpdate(); - static void startTerminalUpdate(); - static void finishTerminalUpdate(); - static void flush_out(); - static void initScreenSettings(); - static void changeTermSizeFinished(); - static void exitWithMessage (const FString&) - #if defined(__clang__) || defined(__GNUC__) - __attribute__((noreturn)) - #endif - ; - private: - // Enumeration - enum exit_state - { - not_used, - used, - line_completely_printed - }; - - // Constants - // Buffer size for character output on the terminal - static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 32768; - - // Methods void init (bool); static void init_characterLengths (FOptiMove*); void finish(); @@ -534,7 +526,7 @@ struct FVTerm::term_area // define virtual terminal character properties int input_cursor_x{-1}; // X-position input cursor int input_cursor_y{-1}; // Y-position input cursor FWidget* widget{nullptr}; // Widget that owns this term_area - FPreprocessing preprocessing_call{}; + FPreprocessing preproc_list{}; line_changes* changes{nullptr}; charData* text{nullptr}; // Text data for the output bool input_cursor_visible{false}; @@ -1125,18 +1117,6 @@ inline void FVTerm::setInsertCursor() inline void FVTerm::unsetInsertCursor() { return FTerm::setInsertCursor(false); } -//---------------------------------------------------------------------- -inline bool FVTerm::setUTF8 (bool enable) -{ return FTerm::setUTF8(enable); } - -//---------------------------------------------------------------------- -inline bool FVTerm::setUTF8() -{ return FTerm::setUTF8(true); } - -//---------------------------------------------------------------------- -inline bool FVTerm::unsetUTF8() -{ return FTerm::setUTF8(false); } - //---------------------------------------------------------------------- inline bool FVTerm::hasPrintArea() const { return print_area; } diff --git a/src/include/final/fwidget.h b/src/include/final/fwidget.h index ef327c2a..ae2ce854 100644 --- a/src/include/final/fwidget.h +++ b/src/include/final/fwidget.h @@ -146,7 +146,7 @@ class FWidget : public FVTerm, public FObject }; // Typedefs - typedef std::vector widgetList; + typedef std::vector FWidgetList; typedef std::vector Accelerators; typedef void (*FCallbackPtr)(FWidget*, FDataPtr); typedef void (FWidget::*FMemberCallback)(FWidget*, FDataPtr); @@ -197,16 +197,18 @@ class FWidget : public FVTerm, public FObject static FWidget*& getClickedWidget(); static FWidget*& getOpenMenu(); static FWidget*& getMoveSizeWidget(); + static FWidgetList*& getWindowList(); + static FMenuBar* getMenuBar(); + static FStatusBar* getStatusBar(); virtual FWidget* getFirstFocusableWidget (FObjectList); virtual FWidget* getLastFocusableWidget (FObjectList); Accelerators* getAcceleratorList() const; - static widgetList*& getWindowList(); - static FMenuBar* getMenuBar(); - static FStatusBar* getStatusBar(); FString getStatusbarMessage() const; FColor getForegroundColor() const; // get the primary FColor getBackgroundColor() const; // widget colors - int getX() const; // positioning + std::vector& doubleFlatLine_ref (fc::sides); + // Positioning and sizes accessors... + int getX() const; int getY() const; const FPoint getPos() const; int getTermX() const; @@ -233,7 +235,6 @@ class FWidget : public FVTerm, public FObject const widget_flags& getFlags() const; FPoint getCursorPos(); FPoint getPrintPos(); - std::vector& doubleFlatLine_ref (fc::sides); // Mutators static void setMainWidget (FWidget*); @@ -264,7 +265,9 @@ class FWidget : public FVTerm, public FObject void setForegroundColor (FColor); void setBackgroundColor (FColor); void setColor(); - virtual void setX (int, bool = true); // positioning + widget_flags& setFlags(); + // Positioning and sizes mutators... + virtual void setX (int, bool = true); virtual void setY (int, bool = true); virtual void setPos (const FPoint&, bool = true); virtual void setWidth (std::size_t, bool = true); @@ -295,7 +298,6 @@ class FWidget : public FVTerm, public FObject void unsetDoubleFlatLine (fc::sides); void setDoubleFlatLine (fc::sides, int, bool = true); void unsetDoubleFlatLine (fc::sides, int); - widget_flags& setFlags(); // Inquiries bool isRootWidget() const; @@ -311,7 +313,7 @@ class FWidget : public FVTerm, public FObject bool isPaddingIgnored(); // Methods - static FWidget* childWidgetAt (FWidget*, const FPoint&); + FWidget* childWidgetAt (const FPoint&); int numOfFocusableChildren(); virtual bool close(); void clearStatusbarMessage(); @@ -337,13 +339,8 @@ class FWidget : public FVTerm, public FObject virtual bool focusFirstChild(); // widget focusing virtual bool focusLastChild(); FPoint termToWidgetPos (const FPoint&); - void detectTermSize(); void print (const FPoint&) override; virtual void move (const FPoint&); - void drawShadow(); - void clearShadow(); - void drawFlatBorder(); - void clearFlatBorder(); virtual void drawBorder(); static void quit(); @@ -363,11 +360,10 @@ class FWidget : public FVTerm, public FObject term_area* getPrintArea() override; const FWidgetColors& getFWidgetColors() const; static uInt getModalDialogCounter(); - static widgetList*& getDialogList(); - static widgetList*& getAlwaysOnTopList(); - static widgetList*& getWidgetCloseList(); - void addPreprocessingHandler ( FVTerm* - , FVTermPreprocessing ) override; + static FWidgetList*& getDialogList(); + static FWidgetList*& getAlwaysOnTopList(); + static FWidgetList*& getWidgetCloseList(); + void addPreprocessingHandler (FVTerm*, FVTermPreprocessing) override; void delPreprocessingHandler (FVTerm*) override; // Inquiry @@ -420,8 +416,6 @@ class FWidget : public FVTerm, public FObject virtual void draw(); void drawWindows(); void drawChildren(); - void drawTransparentShadow (int, int, int, int); - void drawBlockShadow (int, int, int, int); static void setColorTheme(); // Data members @@ -505,10 +499,10 @@ class FWidget : public FVTerm, public FObject static FWidget* move_size_widget; static FWidget* show_root_widget; static FWidget* redraw_root_widget; - static widgetList* window_list; - static widgetList* dialog_list; - static widgetList* always_on_top_list; - static widgetList* close_widget; + static FWidgetList* window_list; + static FWidgetList* dialog_list; + static FWidgetList* always_on_top_list; + static FWidgetList* close_widget; static FWidgetColors wcolors; static uInt modal_dialog_counter; static bool init_desktop; @@ -517,15 +511,32 @@ class FWidget : public FVTerm, public FObject // Friend classes friend class FToggleButton; friend class FScrollView; + + // Friend functions + friend void detectTermSize(); + friend void drawShadow (FWidget*); + friend void drawTransparentShadow (FWidget*, int, int, int, int); + friend void drawBlockShadow (FWidget*, int, int, int, int); + friend void clearShadow (FWidget*); + friend void drawFlatBorder (FWidget*); + friend void clearFlatBorder (FWidget*); }; // non-member function forward declarations //---------------------------------------------------------------------- +void detectTermSize(); FKey getHotkey (const FString&); std::size_t getHotkeyPos (const FString& src, FString& dest); void setHotkeyViaString (FWidget*, const FString&); void drawBorder (FWidget*, FRect); +void drawShadow (FWidget*); +void drawTransparentShadow (FWidget*, int, int, int, int); +void drawBlockShadow (FWidget*, int, int, int, int); +void clearShadow (FWidget*); +void drawFlatBorder (FWidget*); +void clearFlatBorder (FWidget*); + // FWidget inline functions //---------------------------------------------------------------------- @@ -557,11 +568,7 @@ inline FWidget*& FWidget::getMoveSizeWidget() { return move_size_widget; } //---------------------------------------------------------------------- -inline FWidget::Accelerators* FWidget::getAcceleratorList() const -{ return accelerator_list; } - -//---------------------------------------------------------------------- -inline FWidget::widgetList*& FWidget::getWindowList() +inline FWidget::FWidgetList*& FWidget::getWindowList() { return window_list; } //---------------------------------------------------------------------- @@ -572,6 +579,10 @@ inline FMenuBar* FWidget::getMenuBar() inline FStatusBar* FWidget::getStatusBar() { return statusbar; } +//---------------------------------------------------------------------- +inline FWidget::Accelerators* FWidget::getAcceleratorList() const +{ return accelerator_list; } + //---------------------------------------------------------------------- inline FString FWidget::getStatusbarMessage() const { return statusbar_message; } @@ -821,6 +832,10 @@ inline void FWidget::setBackgroundColor (FColor color) background_color = color; } +//---------------------------------------------------------------------- +inline FWidget::widget_flags& FWidget::setFlags() +{ return flags; } + //---------------------------------------------------------------------- inline void FWidget::setGeometry (const FRect& box, bool adjust) { @@ -878,10 +893,6 @@ inline void FWidget::unsetDoubleFlatLine (fc::sides side) inline void FWidget::unsetDoubleFlatLine (fc::sides side, int pos) { setDoubleFlatLine(side, pos, false); } -//---------------------------------------------------------------------- -inline FWidget::widget_flags& FWidget::setFlags() -{ return flags; } - //---------------------------------------------------------------------- inline bool FWidget::isRootWidget() const { return (! hasParent()); } @@ -966,15 +977,15 @@ inline uInt FWidget::getModalDialogCounter() { return modal_dialog_counter; } //---------------------------------------------------------------------- -inline FWidget::widgetList*& FWidget::getDialogList() +inline FWidget::FWidgetList*& FWidget::getDialogList() { return dialog_list; } //---------------------------------------------------------------------- -inline FWidget::widgetList*& FWidget::getAlwaysOnTopList() +inline FWidget::FWidgetList*& FWidget::getAlwaysOnTopList() { return always_on_top_list; } //---------------------------------------------------------------------- -inline FWidget::widgetList*& FWidget::getWidgetCloseList() +inline FWidget::FWidgetList*& FWidget::getWidgetCloseList() { return close_widget; } //----------------------------------------------------------------------