From c4df64c5bca84b9fcf3064d1d19f2d451624775c Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Thu, 24 Jan 2019 00:23:00 +0100 Subject: [PATCH] Refactoring of some methods in FVTerm and FDialog --- ChangeLog | 3 + doc/first-steps.md | 65 +++++++++++------ src/fdialog.cpp | 129 +++++++++++++-------------------- src/fvterm.cpp | 140 ++++++++++++++++-------------------- src/include/final/fdialog.h | 1 + 5 files changed, 158 insertions(+), 180 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f8c0012..318c5a4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2019-01-24 Markus Gans + * Refactoring of some methods in FVTerm and FDialog + 2019-01-21 Markus Gans * More accurate interfaces through the strict use of FPoint() and FSize() diff --git a/doc/first-steps.md b/doc/first-steps.md index 4d198b0c..5d5561b2 100644 --- a/doc/first-steps.md +++ b/doc/first-steps.md @@ -2,6 +2,21 @@ First steps with the Final Cut widget toolkit ============================================= +Table of Contents +----------------- + + +- [How to use the library](#how-to-use-the-library) +- [Memory Management](#memory-management) +- [Event Processing](#event-processing) + - [Event handler reimplementation](#event-handler-reimplementation) +- [Signals and Callbacks](#signals-and-callbacks) + - [Default signals](#the-final-cut-widgets-emit-the-following-default-signals) +- [Callback function](#example-of-a-callback-function) +- [Callback method](#example-of-a-callback-function) +- [Custom signals](#send-custom-signals) + + How to use the library ---------------------- @@ -20,7 +35,9 @@ int main (int argc, char* argv[]) finalcut::FApplication app(argc, argv); finalcut::FDialog dialog(&app); dialog.setText ("A dialog"); - dialog.setGeometry (25, 5, 30, 10); + const finalcut::FPoint position(25, 5); + const finalcut::FSize size(30, 10); + dialog.setGeometry (position, size); app.setMainWidget(&dialog); dialog.show(); return app.exec(); @@ -69,7 +86,9 @@ dialog.setText ("A dialog"); The title bar of the dialog box gets the text "A dialog". ```cpp -dialog.setGeometry (25, 5, 30, 10); +finalcut::FPoint position(25, 5); +finalcut::FSize size(30, 10); +dialog.setGeometry (position, size); ``` The dialog window gets a width of 30 and a height of 10 characters. The position of the window in the terminal is at x=25 and @@ -147,11 +166,11 @@ int main (int argc, char* argv[]) // The object dialog is managed by app FDialog* dialog = new FDialog(&app); dialog->setText ("Window Title"); - dialog->setGeometry (25, 5, 40, 8); + dialog->setGeometry (FPoint(25, 5), FSize(40, 8)); // The object input is managed by dialog FLineEdit* input = new FLineEdit("predefined text", dialog); - input->setGeometry(8, 2, 29, 1); + input->setGeometry(FPoint(8, 2), FSize(29, 1)); input->setLabelText (L"&Input"); // The object label is managed by dialog @@ -159,7 +178,7 @@ int main (int argc, char* argv[]) "adipiscing elit, sed do eiusmod tempor " "incididunt ut labore et dolore magna aliqua." , dialog ); - label->setGeometry (2, 4, 36, 1); + label->setGeometry (FPoint(2, 4), FSize(36, 1)); app.setMainWidget(dialog); dialog->show(); return app.exec(); @@ -260,10 +279,10 @@ class dialogWidget : public FDialog : FDialog(parent) { setText ("Dialog"); - setGeometry (25, 5, 23, 4); - label.setGeometry (1, 1, 10, 1); + setGeometry (FPoint(25, 5), FSize(23, 4)); + label.setGeometry (FPoint(1, 1), FSize(10, 1)); label.setAlignment (fc::alignRight); - value.setGeometry (11, 1, 10, 1); + value.setGeometry (FPoint(11, 1), FSize(10, 1)); id = addTimer(100); } @@ -300,7 +319,7 @@ int main (int argc, char* argv[]) After entering the source code in *timer.cpp* you can compile the above program with gcc: ```cpp -g++ -O2 -std=c++11 -lfinal timer.cpp -o timer +g++ -O2 -lfinal -std=c++11 timer.cpp -o timer ``` @@ -396,6 +415,9 @@ use `delCallbacks()` to remove all existing callbacks from an object.
FToggleButton
"clicked"
"toggled"
+ +
FWidget
+
"destroy"
  @@ -423,14 +445,14 @@ int main (int argc, char* argv[]) FApplication app(argc, argv); FDialog dialog(&app); dialog.setText ("A dialog with callback function"); - dialog.setGeometry (25, 5, 45, 9); + dialog.setGeometry (FRect(25, 5, 45, 9)); FLabel label (&dialog); label = "The button has never been pressed before"; - label.setGeometry (2, 2, 41, 1); + label.setGeometry (FPoint(2, 2), FSize(41, 1)); FButton button (&dialog); // Character follows '&' will be used as the accelerator key button = "&Click me"; - button.setGeometry (15, 5, 14, 1); + button.setGeometry (FPoint(15, 5), FSize(14, 1)); // Connect the button signal "clicked" with the callback function button.addCallback @@ -472,8 +494,8 @@ class dialogWidget : public FDialog : FDialog(parent) { setText ("Callback method"); - setGeometry (25, 5, 25, 7); - button.setGeometry (7, 3, 10, 1); + setGeometry (FPoint(25, 5), FSize(25, 7)); + button.setGeometry (FPoint(7, 3), FSize(10, 1)); // Connect the button signal "clicked" with the callback method button.addCallback @@ -504,7 +526,7 @@ int main (int argc, char* argv[]) After entering the source code in *callback-method.cpp* you can compile the above program with gcc: ```cpp -g++ -O2 -std=c++11 -lfinal callback-method.cpp -o callback-method +g++ -O2 -lfinal -std=c++11 callback-method.cpp -o callback-method ```   @@ -527,13 +549,14 @@ class dialogWidget : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog(parent) { - setGeometry (25, 5, 22, 7); + setGeometry (FPoint(25, 5), FSize(22, 7)); setText ("Emit signal"); - label.setGeometry (8, 1, 5, 1); + FSize size(5, 1); + label.setGeometry (FPoint(8, 1), size); label.setAlignment (fc::alignRight); label.setForegroundColor (fc::Black); - plus.setGeometry (3, 3, 5, 1); - minus.setGeometry (13, 3, 5, 1); + plus.setGeometry (FPoint(3, 3), size); + minus.setGeometry (FPoint(13, 3), size); plus.setNoUnderline(); minus.setNoUnderline(); @@ -641,6 +664,6 @@ int main (int argc, char* argv[]) After entering the source code in *emit-signal.cpp* you can compile the above program with gcc: ```cpp -g++ -O2 -std=c++11 -lfinal emit-signal.cpp -o emit-signal +g++ -O2 -lfinal -std=c++11 emit-signal.cpp -o emit-signal ``` -The FINAL CUT widgets emit the following default signals: \ No newline at end of file +The FINAL CUT widgets emit the following default signals: diff --git a/src/fdialog.cpp b/src/fdialog.cpp index da888f19..1c3cb5de 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -163,44 +163,24 @@ int FDialog::exec() //---------------------------------------------------------------------- void FDialog::setPos (const FPoint& pos, bool) { - int rsw, bsh, width, height; - int x = pos.getX(); - int y = pos.getY(); - FRect old_geometry; + FRect old_geometry, restore; setPos_error = false; - if ( getX() == x && getY() == y ) - { - setPos_error = true; - return; - } - - width = int(getWidth()); - height = int(getHeight()); - // Avoid to move widget completely outside the terminal - if ( x + width <= 1 - || x > int(getMaxWidth()) - || y < 1 - || y > int(getMaxHeight()) ) + // or moving a zoomed dialog or a motionless dialog + if ( isOutsideTerminal(pos) || isZoomed() || getPos() == pos ) { setPos_error = true; return; } - if ( isZoomed() ) - { - setPos_error = true; - return; - } - - int dx = getX() - x - , dy = getY() - y - , old_x = getTermX() - , old_y = getTermY(); + int dx = getX() - pos.getX(); + int dy = getY() - pos.getY(); + int old_x = getTermX(); + int old_y = getTermY(); const auto& shadow = getShadow(); - rsw = int(shadow.getWidth()); // right shadow width; - bsh = int(shadow.getHeight()); // bottom shadow height + std::size_t width = getWidth() + shadow.getWidth(); // width + right shadow + std::size_t height = getHeight() + shadow.getHeight(); // height + bottom shadow old_geometry = getTermGeometryWithShadow(); // move to the new position @@ -217,28 +197,34 @@ void FDialog::setPos (const FPoint& pos, bool) // dy = 0 : move horizontal // dy < 0 : move down + std::size_t d_width = std::size_t(std::abs(dx)); + std::size_t d_height = std::size_t(std::abs(dy)); + if ( dx > 0 ) { if ( dy > 0 ) - restoreVTerm (FRect ( old_x + width + rsw - dx, old_y - , std::size_t(dx), std::size_t(height + bsh - dy) )); + restore.setRect ( old_x + int(width) - dx, old_y + , d_width, height - d_height ); else - restoreVTerm (FRect ( old_x + width + rsw - dx, old_y + std::abs(dy) - , std::size_t(dx), std::size_t(height + bsh - std::abs(dy)) )); + restore.setRect ( old_x + int(width) - dx, old_y - dy + , d_width, height - d_height ); } else { if ( dy > 0 ) - restoreVTerm (FRect(old_x, old_y, std::size_t(std::abs(dx)), std::size_t(height + bsh - dy))); + restore.setRect (old_x, old_y, d_width, height - d_height); else - restoreVTerm (FRect ( old_x, old_y + std::abs(dy) - , std::size_t(std::abs(dx)), std::size_t(height + bsh - std::abs(dy)) )); + restore.setRect (old_x, old_y - dy, d_width, height - d_height); } + restoreVTerm (restore); + if ( dy > 0 ) - restoreVTerm (FRect(old_x, old_y + height + bsh - dy, std::size_t(width + rsw), std::size_t(dy))); + restore.setRect ( old_x, old_y + int(height) - dy, width, d_height); else - restoreVTerm (FRect(old_x, old_y, std::size_t(width + rsw), std::size_t(std::abs(dy)))); + restore.setRect ( old_x, old_y, width, d_height); + + restoreVTerm (restore); } else { @@ -290,33 +276,22 @@ void FDialog::setSize (const FSize& size, bool adjust) { setSize_error = false; - if ( getSize() == size ) + if ( getSize() == size || isZoomed() ) { setSize_error = true; return; } - if ( isZoomed() ) - { - setSize_error = true; - return; - } - - int x = getTermX() - , y = getTermY() - , old_width = int(getWidth()) - , old_height = int(getHeight()) - , dw = old_width - int(size.getWidth()) - , dh = old_height - int(size.getHeight()); + int x = getTermX(); + int y = getTermY(); + int dw = int(getWidth()) - int(size.getWidth()); + int dh = int(getHeight()) - int(size.getHeight()); const auto& shadow = getShadow(); - int rsw = int(shadow.getWidth()); // right shadow width; - int bsh = int(shadow.getHeight()); // bottom shadow height - FWindow::setSize (size, adjust); // get adjust width and height - std::size_t w = getWidth(); - std::size_t h = getHeight(); + std::size_t w = getWidth() + shadow.getWidth(); + std::size_t h = getHeight()+ shadow.getHeight(); // dw > 0 : scale down width // dw = 0 : scale only height @@ -325,39 +300,23 @@ void FDialog::setSize (const FSize& size, bool adjust) // dh = 0 : scale only width // dh < 0 : scale up height + std::size_t d_width = std::size_t(dw); + std::size_t d_height = std::size_t(dh); + // restoring the non-covered terminal areas if ( dw > 0 ) - restoreVTerm (FRect(x + int(w) + rsw, y, std::size_t(dw), h + std::size_t(bsh + dh))); // restore right + restoreVTerm (FRect(x + int(w), y, d_width, h + d_height)); // restore right if ( dh > 0 ) - restoreVTerm (FRect(x, y + int(h) + bsh, w + std::size_t(rsw + dw), std::size_t(dh))); // restore bottom + restoreVTerm (FRect(x, y + int(h), w + d_width, d_height)); // restore bottom redraw(); // handle overlaid windows - if ( window_list && ! window_list->empty() ) - { - bool overlaid = false; - - for (auto&& win : *window_list) - { - if ( overlaid ) - putArea (win->getTermPos(), win->getVWin()); - - if ( vwin == win->getVWin() ) - overlaid = true; - } - } + restoreOverlaidWindows(); // set the cursor to the focus widget - auto focus = FWidget::getFocusWidget(); - if ( focus - && focus->isShown() - && focus->hasVisibleCursor() ) - { - FPoint cursor_pos = focus->getCursorPos(); - focus->setCursorPos(cursor_pos); - } + setCursorToFocusWidget(); } //---------------------------------------------------------------------- @@ -1486,6 +1445,18 @@ inline void FDialog::lowerActivateDialog() updateTerminal(); } +//---------------------------------------------------------------------- +bool FDialog::isOutsideTerminal (const FPoint& pos) +{ + if ( pos.getX() + int(getWidth()) <= 1 + || pos.getX() > int(getMaxWidth()) + || pos.getY() < 1 + || pos.getY() > int(getMaxHeight()) ) + return true; + + return false; +} + //---------------------------------------------------------------------- bool FDialog::isLowerRightResizeCorner (const mouseStates& ms) { diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 6450eb74..14167d25 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -664,13 +664,13 @@ void FVTerm::resizeArea ( const FRect& box if ( ! realloc_success ) return; - area->offset_left = offset_left; - area->offset_top = offset_top; - area->width = width; - area->height = height; - area->right_shadow = rsw; - area->bottom_shadow = bsh; - area->has_changes = false; + area->offset_left = offset_left; + area->offset_top = offset_top; + area->width = width; + area->height = height; + area->right_shadow = rsw; + area->bottom_shadow = bsh; + area->has_changes = false; FSize size(std::size_t(width + rsw), std::size_t(height + bsh)); setTextToDefault (area, size); @@ -854,10 +854,10 @@ FVTerm::covered_state FVTerm::isCovered ( const FPoint& pos if ( found && geometry.contains(pos) ) { - int line_len = win->width + win->right_shadow; + int width = win->width + win->right_shadow; int x = pos.getX(); int y = pos.getY(); - auto tmp = &win->text[(y - win_y) * line_len + (x - win_x)]; + auto tmp = &win->text[(y - win_y) * width + (x - win_x)]; if ( tmp->attr.bit.trans_shadow ) { @@ -885,15 +885,13 @@ void FVTerm::updateOverlappedColor ( term_area* area { // Add the overlapping color to this character - int& aw = area->width; - int& rsh = area->right_shadow; - int x = area_pos.getX(); - int y = area_pos.getY(); - int tx = terminal_pos.getX(); - int ty = terminal_pos.getY(); - int line_len = aw + rsh; + int x = area_pos.getX(); + int y = area_pos.getY(); + int tx = terminal_pos.getX(); + int ty = terminal_pos.getY(); + int width = area->width + area->right_shadow; // Area character - auto ac = &area->text[y * line_len + x]; + auto ac = &area->text[y * width + x]; // Terminal character auto tc = &vterm->text[ty * vterm->width + tx]; // New character @@ -941,15 +939,13 @@ void FVTerm::updateShadedCharacter ( term_area* area { // Get covered character + add the current color - int& aw = area->width; - int& rsh = area->right_shadow; - int x = area_pos.getX(); - int y = area_pos.getY(); - int tx = terminal_pos.getX(); - int ty = terminal_pos.getY(); - int line_len = aw + rsh; + int x = area_pos.getX(); + int y = area_pos.getY(); + int tx = terminal_pos.getX(); + int ty = terminal_pos.getY(); + int width = area->width + area->right_shadow; // Area character - auto ac = &area->text[y * line_len + x]; + auto ac = &area->text[y * width + x]; // Terminal character auto tc = &vterm->text[ty * vterm->width + tx]; // Overlapped character @@ -978,15 +974,13 @@ void FVTerm::updateInheritBackground ( term_area* area { // Add the covered background to this character - int& aw = area->width; - int& rsh = area->right_shadow; - int x = area_pos.getX(); - int y = area_pos.getY(); - int tx = terminal_pos.getX(); - int ty = terminal_pos.getY(); - int line_len = aw + rsh; + int x = area_pos.getX(); + int y = area_pos.getY(); + int tx = terminal_pos.getX(); + int ty = terminal_pos.getY(); + int width = area->width + area->right_shadow; // Area character - auto ac = &area->text[y * line_len + x]; + auto ac = &area->text[y * width + x]; // Terminal character auto tc = &vterm->text[ty * vterm->width + tx]; // New character @@ -1006,15 +1000,13 @@ void FVTerm::updateCharacter ( term_area* area { // Copy a area character to the virtual terminal - int& aw = area->width; - int& rsh = area->right_shadow; - int x = area_pos.getX(); - int y = area_pos.getY(); - int tx = terminal_pos.getX(); - int ty = terminal_pos.getY(); - int line_len = aw + rsh; + int x = area_pos.getX(); + int y = area_pos.getY(); + int tx = terminal_pos.getX(); + int ty = terminal_pos.getY(); + int width = area->width + area->right_shadow; // Area character - auto ac = &area->text[y * line_len + x]; + auto ac = &area->text[y * width + x]; // Terminal character auto tc = &vterm->text[ty * vterm->width + tx]; std::memcpy (tc, ac, sizeof(*tc)); @@ -1030,13 +1022,11 @@ bool FVTerm::updateVTermCharacter ( term_area* area , const FPoint& area_pos , const FPoint& terminal_pos ) { - int& aw = area->width; - int& rsh = area->right_shadow; - int x = area_pos.getX(); - int y = area_pos.getY(); - int line_len = aw + rsh; + int x = area_pos.getX(); + int y = area_pos.getY(); + int width = area->width + area->right_shadow; // Area character - auto ac = &area->text[y * line_len + x]; + auto ac = &area->text[y * width + x]; // Get covered state auto is_covered = isCovered(terminal_pos, area); @@ -1154,14 +1144,12 @@ void FVTerm::updateVTerm (term_area* area) if ( ! area || ! area->visible ) return; - 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 - , y_end; + 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); @@ -1172,10 +1160,10 @@ void FVTerm::updateVTerm (term_area* area) ax = 0; } - if ( ah + bsh + ay > vterm->height ) + if ( height + ay > vterm->height ) y_end = vterm->height - ay; else - y_end = ah + bsh; + y_end = height; for (int y = 0; y < y_end; y++) // Line loop { @@ -1190,7 +1178,7 @@ void FVTerm::updateVTerm (term_area* area) if ( ax == 0 ) line_xmin = ol; - if ( aw + rsh + ax - ol >= vterm->width ) + if ( width + ax - ol >= vterm->width ) line_xmax = vterm->width + ol - ax - 1; if ( ax + line_xmin >= vterm->width ) @@ -1226,7 +1214,7 @@ void FVTerm::updateVTerm (term_area* area) if ( _xmax > int(vterm->changes[ay + y].xmax) ) vterm->changes[ay + y].xmax = uInt(_xmax); - area->changes[y].xmin = uInt(aw + rsh); + area->changes[y].xmin = uInt(width); area->changes[y].xmax = 0; } @@ -1394,21 +1382,15 @@ void FVTerm::putArea (const FPoint& pos, term_area* area) charData* tc; // terminal character charData* ac; // area character - if ( ! area ) + if ( ! area || ! area->visible ) return; - if ( ! area->visible ) - return; - - int ax = pos.getX() - 1; - int ay = pos.getY() - 1; - int aw = area->width; - int ah = area->height; - int rsh = area->right_shadow; - int bsh = area->bottom_shadow; - int ol = 0; // outside left - int y_end; - int length; + 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 ) { @@ -1416,27 +1398,25 @@ void FVTerm::putArea (const FPoint& pos, term_area* area) ax = 0; } - if ( ay + ah + bsh > vterm->height ) + if ( ay + height > vterm->height ) y_end = vterm->height - ay; else - y_end = ah + bsh; + y_end = height; - if ( aw + rsh - ol + ax > vterm->width ) + if ( width - ol + ax > vterm->width ) length = vterm->width - ax; else - length = aw + rsh - ol; + length = width - ol; if ( length < 1 ) return; for (int y = 0; y < y_end; y++) // line loop { - int line_len = aw + rsh; - if ( area->changes[y].trans_count == 0 ) { // Line has only covered characters - ac = &area->text[y * line_len + ol]; + ac = &area->text[y * width + ol]; tc = &vterm->text[(ay + y) * vterm->width + ax]; putAreaLine (ac, tc, length); } @@ -1447,7 +1427,7 @@ void FVTerm::putArea (const FPoint& pos, term_area* area) { int cx = ax + x; int cy = ay + y; - ac = &area->text[y * line_len + ol + x]; + ac = &area->text[y * width + ol + x]; tc = &vterm->text[cy * vterm->width + cx]; putAreaCharacter (FPoint(cx + 1, cy + 1), area->widget, ac, tc); } diff --git a/src/include/final/fdialog.h b/src/include/final/fdialog.h index 242a6dea..e912c467 100644 --- a/src/include/final/fdialog.h +++ b/src/include/final/fdialog.h @@ -205,6 +205,7 @@ class FDialog : public FWindow void moveSizeKey (FKeyEvent*); void raiseActivateDialog(); void lowerActivateDialog(); + bool isOutsideTerminal (const FPoint&); bool isLowerRightResizeCorner (const mouseStates&); void resizeMouseDown (const mouseStates&); void resizeMouseUpMove (const mouseStates&, bool = false);