From c2d7f8b8ee42a979430a8361ae062dae5d1a1cd6 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Thu, 8 Feb 2018 00:25:51 +0100 Subject: [PATCH] Refactoring of some functions --- include/final/fscrollbar.h | 4 +- include/final/fvterm.h | 5 + src/fscrollbar.cpp | 136 +++++++++++----------- src/fvterm.cpp | 224 +++++++++++++++++++++---------------- 4 files changed, 208 insertions(+), 161 deletions(-) diff --git a/include/final/fscrollbar.h b/include/final/fscrollbar.h index d9d0fd4e..7d3ad62c 100644 --- a/include/final/fscrollbar.h +++ b/include/final/fscrollbar.h @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -130,6 +130,8 @@ class FScrollbar : public FWidget void draw(); void drawButtons(); sType getClickedScrollType (int, int); + sType getVerticalClickedScrollType (int); + sType getHorizontalClickedScrollType (int); void processMiddleButton (int, int); void processScroll(); diff --git a/include/final/fvterm.h b/include/final/fvterm.h index b6755edf..e7c7592b 100644 --- a/include/final/fvterm.h +++ b/include/final/fvterm.h @@ -398,7 +398,12 @@ class FVTerm : public FTerm // Methods void init(); void finish(); + static void putAreaLine (char_data*, char_data*, int); + static void putAreaCharacter ( int, int, FVTerm* + , char_data*, char_data* ); static bool clearTerm (int = ' '); + static bool clearFullArea (term_area*, char_data&); + static void clearAreaWithShadow (term_area*, char_data&); static bool canClearToEOL (uInt, uInt); static bool canClearLeadingWS (uInt&, uInt); static bool canClearTrailingWS (uInt&, uInt); diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index 00a95e8c..ba3090ed 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -3,7 +3,7 @@ * * * This file is part of the Final Cut widget toolkit * * * -* Copyright 2012-2017 Markus Gans * +* Copyright 2012-2018 Markus Gans * * * * The Final Cut is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public License * @@ -651,76 +651,84 @@ void FScrollbar::drawButtons() //---------------------------------------------------------------------- FScrollbar::sType FScrollbar::getClickedScrollType (int x, int y) { - FScrollbar::sType stype; - if ( bar_orientation == fc::vertical ) { - if ( y == 1 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( y > 1 && y <= slider_pos + 1 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( y > slider_pos + slider_length + 1 && y < getHeight() ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( y == getHeight() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; + return getVerticalClickedScrollType(y); } else // horizontal { - if ( isNewFont() ) - { - if ( x == 1 || x == 2 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( x > 2 && x <= slider_pos + 2 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( x > slider_pos + slider_length + 2 && x < getWidth() - 1 ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( x == getWidth() - 1 || x == getWidth() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; - } - else - { - if ( x == 1 ) - { - stype = FScrollbar::scrollStepBackward; // decrement button - } - else if ( x > 1 && x <= slider_pos + 1 ) - { - stype = FScrollbar::scrollPageBackward; // before slider - } - else if ( x > slider_pos + slider_length + 1 && x < getWidth() ) - { - stype = FScrollbar::scrollPageForward; // after slider - } - else if ( x == getWidth() ) - { - stype = FScrollbar::scrollStepForward; // increment button - } - else - stype = FScrollbar::noScroll; - } + return getHorizontalClickedScrollType(x); + } +} + +//---------------------------------------------------------------------- +FScrollbar::sType FScrollbar::getVerticalClickedScrollType (int y) +{ + if ( y == 1 ) + { + return FScrollbar::scrollStepBackward; // decrement button + } + else if ( y > 1 && y <= slider_pos + 1 ) + { + return FScrollbar::scrollPageBackward; // before slider + } + else if ( y > slider_pos + slider_length + 1 && y < getHeight() ) + { + return FScrollbar::scrollPageForward; // after slider + } + else if ( y == getHeight() ) + { + return FScrollbar::scrollStepForward; // increment button } - return stype; + return FScrollbar::noScroll; +} + +//---------------------------------------------------------------------- +FScrollbar::sType FScrollbar::getHorizontalClickedScrollType (int x) +{ + if ( isNewFont() ) + { + if ( x == 1 || x == 2 ) + { + return FScrollbar::scrollStepBackward; // decrement button + } + else if ( x > 2 && x <= slider_pos + 2 ) + { + return FScrollbar::scrollPageBackward; // before slider + } + else if ( x > slider_pos + slider_length + 2 && x < getWidth() - 1 ) + { + return FScrollbar::scrollPageForward; // after slider + } + else if ( x == getWidth() - 1 || x == getWidth() ) + { + return FScrollbar::scrollStepForward; // increment button + } + + return FScrollbar::noScroll; + } + else + { + if ( x == 1 ) + { + return FScrollbar::scrollStepBackward; // decrement button + } + else if ( x > 1 && x <= slider_pos + 1 ) + { + return FScrollbar::scrollPageBackward; // before slider + } + else if ( x > slider_pos + slider_length + 1 && x < getWidth() ) + { + return FScrollbar::scrollPageForward; // after slider + } + else if ( x == getWidth() ) + { + return FScrollbar::scrollStepForward; // increment button + } + + return FScrollbar::noScroll; + } } //---------------------------------------------------------------------- diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 1b1f53d2..3c189d97 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -1620,6 +1620,7 @@ void FVTerm::getArea (int x, int y, int w, int h, term_area* area) void FVTerm::putArea (const FPoint& pos, term_area* area) { // Copies the given area block to the virtual terminal position + if ( ! area ) return; @@ -1680,59 +1681,20 @@ void FVTerm::putArea (int ax, int ay, term_area* area) if ( area->changes[y].trans_count == 0 ) { // Line has only covered characters - tc = &vterm->text[(ay + y) * vterm->width + ax]; ac = &area->text[y * line_len + ol]; - std::memcpy (tc, ac, sizeof(char_data) * unsigned(length)); + tc = &vterm->text[(ay + y) * vterm->width + ax]; + putAreaLine (ac, tc, length); } else { // Line has one or more transparent characters for (register int x = 0; x < length; x++) // column loop { - tc = &vterm->text[(ay + y) * vterm->width + (ax + x)]; + int cx = ax + x; + int cy = ay + y; ac = &area->text[y * line_len + ol + x]; - - if ( ac->attr.bit.transparent ) // transparent - { - // restore one character on vterm - char_data ch; - ch = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget); - std::memcpy (tc, &ch, sizeof(char_data)); - } - else // not transparent - { - if ( ac->attr.bit.trans_shadow ) // transparent shadow - { - // get covered character + add the current color - char_data ch; - ch = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget); - ch.fg_color = ac->fg_color; - ch.bg_color = ac->bg_color; - ch.attr.bit.reverse = false; - ch.attr.bit.standout = false; - - if ( ch.code == fc::LowerHalfBlock - || ch.code == fc::UpperHalfBlock - || ch.code == fc::LeftHalfBlock - || ch.code == fc::RightHalfBlock - || ch.code == fc::MediumShade - || ch.code == fc::FullBlock ) - ch.code = ' '; - - std::memcpy (tc, &ch, sizeof(char_data)); - } - else if ( ac->attr.bit.inherit_bg ) - { - // add the covered background to this character - char_data ch, cc; - std::memcpy (&ch, ac, sizeof(char_data)); - cc = getCoveredCharacter (ax + x + 1, ay + y + 1, area->widget); - ch.bg_color = cc.bg_color; - std::memcpy (tc, &ch, sizeof(char_data)); - } - else // default - std::memcpy (tc, ac, sizeof(char_data)); - } + tc = &vterm->text[cy * vterm->width + cx]; + putAreaCharacter (cx + 1, cy + 1, area->widget, ac, tc); } } @@ -1869,69 +1831,27 @@ void FVTerm::scrollAreaReverse (term_area* area) //---------------------------------------------------------------------- void FVTerm::clearArea (term_area* area, int fillchar) { - // clear the area with the current attributes + // Clear the area with the current attributes + char_data nc; // next character - int total_width; uInt w; - // current attributes with a space character + // Current attributes with a space character std::memcpy (&nc, &next_attribute, sizeof(char_data)); nc.code = fillchar; if ( ! (area && area->text) ) return; - total_width = area->width + area->right_shadow; - w = uInt(total_width); + w = uInt(area->width + area->right_shadow); if ( area->right_shadow == 0 ) { - int area_size = area->width * area->height; - std::fill_n (area->text, area_size, nc); - - if ( area == vdesktop ) - { - if ( clearTerm (fillchar) ) - { - nc.attr.bit.printed = true; - std::fill_n (vterm->text, area_size, nc); - } - else - { - for (int i = 0; i < vdesktop->height; i++) - { - vdesktop->changes[i].xmin = 0; - vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1; - vdesktop->changes[i].trans_count = 0; - } - - vdesktop->has_changes = true; - } - + if ( clearFullArea(area, nc) ) return; - } } else - { - char_data t_char = nc; - t_char.attr.bit.transparent = true; - - for (int y = 0; y < area->height; y++) - { - int pos = y * total_width; - // area - std::fill_n (&area->text[pos], total_width, nc); - // right shadow - std::fill_n (&area->text[pos + area->width], area->right_shadow, t_char); - } - - // bottom shadow - for (int y = 0; y < area->bottom_shadow; y++) - { - int pos = total_width * (y + area->height); - std::fill_n (&area->text[pos], total_width, t_char); - } - } + clearAreaWithShadow(area, nc); for (int i = 0; i < area->height; i++) { @@ -2327,10 +2247,67 @@ void FVTerm::finish() delete term_pos; } +//---------------------------------------------------------------------- +void FVTerm::putAreaLine (char_data* ac, char_data* tc, int length) +{ + // copy "length" characters from area to terminal + + std::memcpy (tc, ac, sizeof(char_data) * unsigned(length)); +} + +//---------------------------------------------------------------------- +void FVTerm::putAreaCharacter ( int x, int y, FVTerm* obj + , char_data* ac + , char_data* tc ) +{ + if ( ac->attr.bit.transparent ) // Transparent + { + // Restore one character on vterm + char_data ch; + ch = getCoveredCharacter (x, y, obj); + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // Mot transparent + { + if ( ac->attr.bit.trans_shadow ) // Transparent shadow + { + // Get covered character + add the current color + char_data ch; + ch = getCoveredCharacter (x, y, obj); + ch.fg_color = ac->fg_color; + ch.bg_color = ac->bg_color; + ch.attr.bit.reverse = false; + ch.attr.bit.standout = false; + + if ( ch.code == fc::LowerHalfBlock + || ch.code == fc::UpperHalfBlock + || ch.code == fc::LeftHalfBlock + || ch.code == fc::RightHalfBlock + || ch.code == fc::MediumShade + || ch.code == fc::FullBlock ) + ch.code = ' '; + + std::memcpy (tc, &ch, sizeof(char_data)); + } + else if ( ac->attr.bit.inherit_bg ) + { + // Add the covered background to this character + char_data ch, cc; + std::memcpy (&ch, ac, sizeof(char_data)); + cc = getCoveredCharacter (x, y, obj); + ch.bg_color = cc.bg_color; + std::memcpy (tc, &ch, sizeof(char_data)); + } + else // Default + std::memcpy (tc, ac, sizeof(char_data)); + } +} + //---------------------------------------------------------------------- bool FVTerm::clearTerm (int fillchar) { // Clear the real terminal and put cursor at home + char*& cl = TCAP(fc::t_clear_screen); char*& cd = TCAP(fc::t_clr_eos); char*& cb = TCAP(fc::t_clr_eol); @@ -2345,18 +2322,18 @@ bool FVTerm::clearTerm (int fillchar) return false; } - if ( cl ) + if ( cl ) // Clear screen { appendOutputBuffer (cl); term_pos->setPoint(0,0); } - else if ( cd ) + else if ( cd ) // Clear to end of screen { setTermXY (0, 0); appendOutputBuffer (cd); term_pos->setPoint(-1, -1); } - else if ( cb ) + else if ( cb ) // Clear to end of line { term_pos->setPoint(-1, -1); @@ -2373,6 +2350,61 @@ bool FVTerm::clearTerm (int fillchar) return true; } +//---------------------------------------------------------------------- +bool FVTerm::clearFullArea (term_area* area, char_data& nc) +{ + // Clear area + int area_size = area->width * area->height; + std::fill_n (area->text, area_size, nc); + + if ( area != vdesktop ) // Is the area identical to the desktop? + return false; + + // Try to clear the terminal rapidly with a control sequence + if ( clearTerm (nc.code) ) + { + nc.attr.bit.printed = true; + std::fill_n (vterm->text, area_size, nc); + } + else + { + for (int i = 0; i < vdesktop->height; i++) + { + vdesktop->changes[i].xmin = 0; + vdesktop->changes[i].xmax = uInt(vdesktop->width) - 1; + vdesktop->changes[i].trans_count = 0; + } + + vdesktop->has_changes = true; + } + + return true; +} + +//---------------------------------------------------------------------- +void FVTerm::clearAreaWithShadow (term_area* area, char_data& nc) +{ + char_data t_char = nc; + int total_width = area->width + area->right_shadow; + t_char.attr.bit.transparent = true; + + for (int y = 0; y < area->height; y++) + { + int pos = y * total_width; + // Clear area + std::fill_n (&area->text[pos], total_width, nc); + // Make right shadow transparent + std::fill_n (&area->text[pos + area->width], area->right_shadow, t_char); + } + + // Make bottom shadow transparent + for (int y = 0; y < area->bottom_shadow; y++) + { + int pos = total_width * (y + area->height); + std::fill_n (&area->text[pos], total_width, t_char); + } +} + //---------------------------------------------------------------------- bool FVTerm::canClearToEOL (uInt xmin, uInt y) {