From 597f9e772b34f63ee7cf36deb019601db31499ac Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 28 Mar 2021 23:19:01 +0200 Subject: [PATCH] New method FWidget::initLayout() for setting widget layouts after terminal initialization --- ChangeLog | 7 ++ doc/first-steps.md | 57 +++++++++++----- doc/user-theme.md | 15 +++-- examples/7segment.cpp | 24 ++++--- examples/background-color.cpp | 31 +++++---- examples/busy.cpp | 19 ++++-- examples/calculator.cpp | 46 +++++++------ examples/checklist.cpp | 23 +++---- examples/event-log.cpp | 42 ++++++------ examples/listbox.cpp | 19 ++++-- examples/listview.cpp | 15 +++-- examples/mandelbrot.cpp | 8 ++- examples/menu.cpp | 19 ++++-- examples/mouse.cpp | 42 ++++++++---- examples/scrollview.cpp | 54 +++++++++------ examples/term-attributes.cpp | 15 +++-- examples/transparent.cpp | 8 ++- examples/treeview.cpp | 17 +++-- examples/ui.cpp | 99 +++++++++++++++------------- examples/watch.cpp | 39 ++++++----- examples/windows.cpp | 29 +++++++-- src/fdialog.cpp | 8 ++- src/fmenuitem.cpp | 46 +++++++++---- src/fmessagebox.cpp | 9 ++- src/ftermcap.cpp | 112 +++++++++++++++----------------- src/ftextview.cpp | 15 +++++ src/ftooltip.cpp | 9 ++- src/fwidget.cpp | 30 ++++++++- src/include/final/fmenuitem.h | 5 ++ src/include/final/fmessagebox.h | 1 + src/include/final/ftermcap.h | 27 +++++++- src/include/final/ftextview.h | 1 + src/include/final/ftooltip.h | 1 + src/include/final/fwidget.h | 2 + 34 files changed, 586 insertions(+), 308 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e21d86b..197dde74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2021-03-28 Markus Gans + * Widget now have the virtual method initLayout() to set + the widget layouts automatically before the first drawing + on the terminal is done. Also texts in full-width characters, + whose character width is determined automatically, should be + calculated here. + 2021-03-15 Markus Gans * Dynamic adjustment of the terminal refresh rate between 5 and 60 Hz diff --git a/doc/first-steps.md b/doc/first-steps.md index 93e9c6f7..d089142a 100644 --- a/doc/first-steps.md +++ b/doc/first-steps.md @@ -378,15 +378,20 @@ class dialogWidget : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog{parent} { - setText ("Dialog"); - setGeometry (FPoint{25, 5}, FSize{23, 4}); - label.setGeometry (FPoint{1, 1}, FSize{10, 1}); label.setAlignment (Align::Right); - value.setGeometry (FPoint{11, 1}, FSize{10, 1}); id = addTimer(100); } private: + void initLayout() + { + setText ("Dialog"); + setGeometry (FPoint{25, 5}, FSize{23, 4}); + label.setGeometry (FPoint{1, 1}, FSize{10, 1}); + value.setGeometry (FPoint{11, 1}, FSize{10, 1}); + FDialog::initLayout(); + } + void onTimer (FTimerEvent* ev) override { if ( id == ev->getTimerId() && n < 9999999999 ) @@ -495,12 +500,16 @@ class dialogWidget final : public FDialog public: explicit dialogWidget (FWidget* parent = nullptr) : FDialog{"User event", parent} + { } + + private: + void initLayout() { FDialog::setGeometry (FPoint{25, 5}, FSize{40, 6}); loadavg_label.setGeometry (FPoint{2, 2}, FSize{36, 1}); + FDialog::initLayout(); } - private: void onUserEvent (FUserEvent* ev) override { const auto& lavg = ev->getData(); @@ -891,10 +900,6 @@ class dialogWidget : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog{parent} { - setText ("Callback method"); - 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 ( @@ -906,6 +911,14 @@ class dialogWidget : public FDialog } private: + void initLayout() + { + setText ("Callback method"); + setGeometry (FPoint{25, 5}, FSize{25, 7}); + button.setGeometry (FPoint{7, 3}, FSize{10, 1}); + FDialog::initLayout(); + } + FButton button{"&Quit", this}; }; @@ -954,14 +967,8 @@ class dialogWidget : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog{parent} { - setGeometry (FPoint{25, 5}, FSize{22, 7}); - setText ("Emit signal"); - const FSize size{5, 1}; - label.setGeometry (FPoint{8, 1}, size); label.setAlignment (Align::Right); label.setForegroundColor (FColor::Black); - plus.setGeometry (FPoint{3, 3}, size); - minus.setGeometry (FPoint{3, 3} + FPoint{10, 0}, size); plus.setNoUnderline(); minus.setNoUnderline(); @@ -976,6 +983,17 @@ class dialogWidget : public FDialog } private: + void initLayout() + { + setGeometry (FPoint{25, 5}, FSize{22, 7}); + setText ("Emit signal"); + const FSize size{5, 1}; + label.setGeometry (FPoint{8, 1}, size); + plus.setGeometry (FPoint{3, 3}, size); + minus.setGeometry (FPoint{3, 3} + FPoint{10, 0}, size); + FDialog::initLayout(); + } + void cb_plus() { if ( t < 100 ) @@ -1375,8 +1393,6 @@ class dialogWidget : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog{parent} { - setText ("Dialog"); - setGeometry (FPoint{28, 2}, FSize{24, 21}); scrollview.setGeometry(FPoint{1, 1}, FSize{22, 11}); scrollview.setScrollSize(FSize{60, 27}); // Attention: getColorTheme() requires an initialized terminal @@ -1420,6 +1436,13 @@ class dialogWidget : public FDialog private: typedef std::tuple direction; + void initLayout() + { + setText ("Dialog"); + setGeometry (FPoint{28, 2}, FSize{24, 21}); + FDialog::initLayout(); + } + void cb_button (const FPoint& p) { scrollview.scrollTo(p); diff --git a/doc/user-theme.md b/doc/user-theme.md index 0295b3ec..4d70c436 100644 --- a/doc/user-theme.md +++ b/doc/user-theme.md @@ -361,20 +361,15 @@ class dialogWidget final : public FDialog explicit dialogWidget (FWidget* parent = nullptr) : FDialog{"Theming test application", parent} { - FDialog::setGeometry (FPoint{15, 5}, FSize{50, 9}); - Input.setGeometry (FPoint{2, 2}, FSize{39, 1}); Input.setLabelText("File name:"); Input.setLabelOrientation(FLineEdit::LabelOrientation::Above); Input.setStatusbarMessage("Enter a file name"); - Browse.setGeometry (FPoint{43, 2}, FSize{4, 1}); Browse.addCallback ( "clicked", this, &dialogWidget::cb_FileBrowse ); - Apply.setGeometry (FPoint{24, 5}, FSize{10, 1}); Apply.setStatusbarMessage("Apply settings"); - Quit.setGeometry (FPoint{37, 5}, FSize{10, 1}); Quit.setStatusbarMessage("Exit the program"); Quit.addCallback ( @@ -391,6 +386,16 @@ class dialogWidget final : public FDialog } private: + void initLayout() + { + setGeometry (FPoint{15, 5}, FSize{50, 9}); + Input.setGeometry (FPoint{2, 2}, FSize{39, 1}); + Browse.setGeometry (FPoint{43, 2}, FSize{4, 1}); + Apply.setGeometry (FPoint{24, 5}, FSize{10, 1}); + Quit.setGeometry (FPoint{37, 5}, FSize{10, 1}); + FDialog::initLayout(); + } + void cb_FileBrowse() { auto filename = FFileDialog::fileOpenChooser(this); diff --git a/examples/7segment.cpp b/examples/7segment.cpp index 25a393ea..8d9f5c69 100644 --- a/examples/7segment.cpp +++ b/examples/7segment.cpp @@ -59,6 +59,7 @@ class SegmentView final : public finalcut::FDialog void hexEncoding(); void get7Segment (const wchar_t); void draw() override; + void initLayout() override; // Data members std::map code{}; @@ -71,26 +72,16 @@ class SegmentView final : public finalcut::FDialog SegmentView::SegmentView (finalcut::FWidget* parent) : FDialog{parent} { - // Dialog settings - // Avoids calling a virtual function from the constructor - // (CERT, OOP50-CPP) - FDialog::setText ("Seven-segment display"); - FDialog::setGeometry (FPoint{25, 5}, FSize{42, 15}); - // Set encoding hexEncoding(); // Input field - input.setGeometry (FPoint(2, 2), FSize{12, 1}); input.setLabelText (L"&Hex value"); input.setLabelText (L"&Hex-digits or (.) (:) (H) (L) (P) (U)"); input.setLabelOrientation(finalcut::FLineEdit::LabelOrientation::Above); input.setMaxLength(9); input.setInputFilter("[:.hHlLpPuU[:xdigit:]]"); - // Exit button - exit.setGeometry(FPoint{28, 11}, FSize{10, 1}); - // Add some function callbacks input.addCallback ( @@ -221,6 +212,19 @@ void SegmentView::draw() << FPoint {4, 10} << finalcut::FString{36, ' '}; } +//---------------------------------------------------------------------- +void SegmentView::initLayout() +{ + // Dialog settings + FDialog::setText ("Seven-segment display"); + FDialog::setGeometry (FPoint{25, 5}, FSize{42, 15}); + // Input field + input.setGeometry (FPoint(2, 2), FSize{12, 1}); + // Exit button + exit.setGeometry(FPoint{28, 11}, FSize{10, 1}); + FDialog::initLayout(); +} + //---------------------------------------------------------------------- // main part diff --git a/examples/background-color.cpp b/examples/background-color.cpp index 41d65433..326e1c25 100644 --- a/examples/background-color.cpp +++ b/examples/background-color.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2019-2020 Markus Gans * +* Copyright 2019-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -55,6 +55,9 @@ class Background final : public finalcut::FDialog Background& operator = (const Background&) = delete; private: + // Methods + void initLayout() override; + // Callback method void cb_changed(); void cb_choice(); @@ -92,14 +95,7 @@ class Background final : public finalcut::FDialog Background::Background (finalcut::FWidget* parent) : FDialog{parent} { - // Dialog settings - // Avoids calling a virtual function from the constructor - // (CERT, OOP50-CPP) - FDialog::setText ("Background color palette"); - FDialog::setGeometry (FPoint{25, 5}, FSize{32, 12}); - // Combobox - color_choice.setGeometry (FPoint{2, 2}, FSize{18, 1}); color_choice.setLabelOrientation (finalcut::FLineEdit::LabelOrientation::Above); color_choice.setLabelText ("Color choice"); color_choice.unsetEditable(); @@ -111,19 +107,16 @@ Background::Background (finalcut::FWidget* parent) } // Spin boxes - red.setGeometry (FPoint{2, 5}, FSize{7, 1}); red.setLabelOrientation (finalcut::FLineEdit::LabelOrientation::Above); red.setLabelText ("Red"); red.setRange (0, 255); red.setValue (0x80); - green.setGeometry (FPoint{12, 5}, FSize{7, 1}); green.setLabelOrientation (finalcut::FLineEdit::LabelOrientation::Above); green.setLabelText ("Green"); green.setRange (0, 255); green.setValue (0xa4); - blue.setGeometry (FPoint{22, 5}, FSize{7, 1}); blue.setLabelOrientation (finalcut::FLineEdit::LabelOrientation::Above); blue.setLabelText ("Blue"); blue.setRange (0, 255); @@ -138,9 +131,6 @@ Background::Background (finalcut::FWidget* parent) , int(blue.getValue()) ); } - // Quit button - quit.setGeometry(FPoint{19, 8}, FSize{10, 1}); - // Add some function callbacks quit.addCallback ( @@ -172,6 +162,19 @@ Background::Background (finalcut::FWidget* parent) //---------------------------------------------------------------------- Background::~Background() noexcept = default; // destructor +//---------------------------------------------------------------------- +void Background::initLayout() +{ + FDialog::setText ("Background color palette"); + FDialog::setGeometry (FPoint{25, 5}, FSize{32, 12}); + color_choice.setGeometry (FPoint{2, 2}, FSize{18, 1}); + red.setGeometry (FPoint{2, 5}, FSize{7, 1}); + green.setGeometry (FPoint{12, 5}, FSize{7, 1}); + blue.setGeometry (FPoint{22, 5}, FSize{7, 1}); + quit.setGeometry(FPoint{19, 8}, FSize{10, 1}); // Quit button + FDialog::initLayout(); +} + //---------------------------------------------------------------------- void Background::cb_changed() { diff --git a/examples/busy.cpp b/examples/busy.cpp index 4e06d2ae..e1265673 100644 --- a/examples/busy.cpp +++ b/examples/busy.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2020 Markus Gans * +* Copyright 2020-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -35,6 +35,7 @@ class Dialog final : public finalcut::FDialog explicit Dialog (FWidget* parent = nullptr); private: + void initLayout() override; void adjustSize() override; // Event handler @@ -54,14 +55,9 @@ class Dialog final : public finalcut::FDialog Dialog::Dialog (FWidget* parent) : finalcut::FDialog{parent} { - FDialog::setText ("Dialog"); - finalcut::FDialog::setGeometry (FPoint{26, 5}, FSize{28, 10}); - seconds.setGeometry (FPoint{10, 2}, FSize{10, 1}); seconds.setLabelText ("Seconds"); seconds.setRange (0, 60); seconds.setValue (3); - start.setGeometry (FPoint{2, 6}, FSize{10, 1}); - quit.setGeometry (FPoint{15, 6}, FSize{10, 1}); // Add button callbacks seconds.addCallback @@ -85,6 +81,17 @@ Dialog::Dialog (FWidget* parent) ); } +//---------------------------------------------------------------------- +void Dialog::initLayout() +{ + FDialog::setText ("Dialog"); + FDialog::setGeometry (FPoint{26, 5}, FSize{28, 10}); + seconds.setGeometry (FPoint{10, 2}, FSize{10, 1}); + start.setGeometry (FPoint{2, 6}, FSize{10, 1}); + quit.setGeometry (FPoint{15, 6}, FSize{10, 1}); + FDialog::initLayout(); +} + //---------------------------------------------------------------------- void Dialog::adjustSize() { diff --git a/examples/calculator.cpp b/examples/calculator.cpp index 1722da9f..d03a6a1a 100644 --- a/examples/calculator.cpp +++ b/examples/calculator.cpp @@ -112,9 +112,6 @@ void Button::onKeyPress (finalcut::FKeyEvent* ev) class Calc final : public finalcut::FDialog { public: - // Using-declaration - using FDialog::setGeometry; - // Constructor explicit Calc (finalcut::FWidget* parent = nullptr); @@ -209,6 +206,7 @@ class Calc final : public finalcut::FDialog void setInfixOperator (char); void clearInfixOperator(); void calcInfixOperator(); + void initLayout() override; void adjustSize() override; const wchar_t* getButtonText (const ButtonName&) const; void mapKeyFunctions(); @@ -257,12 +255,6 @@ class Calc final : public finalcut::FDialog Calc::Calc (FWidget* parent) : finalcut::FDialog{parent} { - // Dialog settings - // Avoids calling a virtual function from the constructor - // (CERT, OOP50-CPP) - FDialog::setText ("Calculator"); - FDialog::setGeometry (FPoint{19, 6}, FSize{37, 18}); - mapKeyFunctions(); clearInfixOperator(); @@ -271,17 +263,6 @@ Calc::Calc (FWidget* parent) auto btn = std::make_shared