diff --git a/.travis.yml b/.travis.yml index 378cf041..1346db87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,11 @@ matrix: - TEST="Coverity Scan" addons: apt: + sources: + - ubuntu-toolchain-r-test packages: + - ca-certificates + - gcc - g++ - gpm - libgpm-dev diff --git a/ChangeLog b/ChangeLog index d8cf3b63..d515ef6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2019-12-16 Markus Gans + * New widget class FComboBox to provide a dropdown list + with an input field + 2019-11-17 Markus Gans * Revision of FString number input stream diff --git a/README.md b/README.md index ef17b9aa..8674d8c9 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,9 @@ Class digramm │ ┌───────────┐ ├────┤ FTextView │ │ └───────────┘ + │ ┌───────────┐1 1┌──────────────────┐ + ├────┤ FComboBox ├------┤ FDropDownListBox │ + │ └───────────┘ └──────────────────┘ ┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐ │ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │ └─────────────┘ │ └──────────┘ └──────────────┘ diff --git a/doc/class-diagram.txt b/doc/class-diagram.txt index a48e9d16..56bca269 100644 --- a/doc/class-diagram.txt +++ b/doc/class-diagram.txt @@ -71,6 +71,9 @@ │ ┌───────────┐ ├────┤ FTextView │ │ └───────────┘ + │ ┌───────────┐1 1┌──────────────────┐ + ├────┤ FComboBox ├------┤ FDropDownListBox │ + │ └───────────┘ └──────────────────┘ ┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐ │ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │ └─────────────┘ │ └──────────┘ └──────────────┘ diff --git a/doc/first-steps.md b/doc/first-steps.md index 3092699c..eee5ea02 100644 --- a/doc/first-steps.md +++ b/doc/first-steps.md @@ -410,6 +410,9 @@ use `delCallbacks()` to remove all existing callbacks from an object.
FScrollbar
"change-value"
+
FSpinBox
+
"changed"
+
FStatusBar
"activate"
@@ -420,7 +423,7 @@ use `delCallbacks()` to remove all existing callbacks from an object.
"clicked"
"toggled"
FWidget
-
"destroy"
+
"destroy"
"focus-in"
"focus-out"
"mouse-press"
"mouse-release"
"mouse-move"
"mouse-wheel-down"
"mouse-wheel-up"
  diff --git a/examples/background-color.cpp b/examples/background-color.cpp index a15fa407..6561d3b8 100644 --- a/examples/background-color.cpp +++ b/examples/background-color.cpp @@ -20,7 +20,8 @@ * . * ***********************************************************************/ -#include +#include +#include #include #include @@ -36,6 +37,10 @@ using finalcut::FSize; class Background : public finalcut::FDialog { public: + // Typedef + typedef std::tuple RGB; + + // Constructors explicit Background (finalcut::FWidget* = nullptr); // Disable copy constructor @@ -50,12 +55,35 @@ class Background : public finalcut::FDialog private: // Callback method void cb_changed (finalcut::FWidget*, FDataPtr); + void cb_choice (finalcut::FWidget*, FDataPtr); // Data members + finalcut::FComboBox color_choice{this}; finalcut::FSpinBox red{this}; finalcut::FSpinBox green{this}; finalcut::FSpinBox blue{this}; finalcut::FButton quit{"&Quit", this}; + std::vector> color_list + { + { "Light blue" , std::make_tuple(0x80, 0xa4, 0xec) }, + { "Vivid blue" , std::make_tuple(0x37, 0x97, 0xfd) }, + { "Bright blue" , std::make_tuple(0x3c, 0x85, 0xd2) }, + { "Strong blue" , std::make_tuple(0x32, 0x64, 0x9f) }, + { "Light cyan" , std::make_tuple(0x6c, 0xfe, 0xfe) }, + { "Vivid cyan" , std::make_tuple(0x0b, 0xdd, 0xd4) }, + { "Soft cyan" , std::make_tuple(0x49, 0xa8, 0xac) }, + { "Light green" , std::make_tuple(0x81, 0xdf, 0xbb) }, + { "Vivid green" , std::make_tuple(0x5c, 0x9e, 0x4a) }, + { "Bright green" , std::make_tuple(0x0f, 0xba, 0x78) }, + { "Strong green" , std::make_tuple(0x03, 0x8f, 0x68) }, + { "Mint green" , std::make_tuple(0x4a, 0xfd, 0x91) }, + { "Green" , std::make_tuple(0x6b, 0xe8, 0x1b) }, + { "Dark green" , std::make_tuple(0x01, 0x65, 0x05) }, + { "Dark sea green", std::make_tuple(0x7d, 0xb6, 0x96) }, + { "Bright purple" , std::make_tuple(0x83, 0x76, 0xa2) }, + { "Taupe" , std::make_tuple(0xa6, 0x8c, 0x99) }, + { "Silver" , std::make_tuple(0xc1, 0xc1, 0xcb) } + }; }; //---------------------------------------------------------------------- @@ -64,36 +92,48 @@ Background::Background (finalcut::FWidget* parent) { // Dialog settings setText ("Background color palette"); - setGeometry (FPoint(25, 5), FSize(32, 9)); + setGeometry (FPoint(25, 5), FSize(32, 12)); + + // Combobox + color_choice.setGeometry (FPoint(2, 2), FSize(18, 1)); + color_choice.setLabelOrientation (finalcut::FLineEdit::label_above); + color_choice.setLabelText ("Color choice"); + color_choice.unsetEditable(); + + for (auto& c : color_list) + { + FDataPtr data_ptr = reinterpret_cast(&c.second); + finalcut::FListBoxItem item (c.first, data_ptr); + color_choice.insert(item); + } // Spin boxes - red.setGeometry (FPoint(2, 2), FSize(7, 1)); + red.setGeometry (FPoint(2, 5), FSize(7, 1)); red.setLabelOrientation (finalcut::FLineEdit::label_above); red.setLabelText ("Red"); red.setRange (0, 255); red.setValue (0x80); - green.setGeometry (FPoint(12, 2), FSize(7, 1)); + green.setGeometry (FPoint(12, 5), FSize(7, 1)); green.setLabelOrientation (finalcut::FLineEdit::label_above); green.setLabelText ("Green"); green.setRange (0, 255); green.setValue (0xa4); - blue.setGeometry (FPoint(22, 2), FSize(7, 1)); + blue.setGeometry (FPoint(22, 5), FSize(7, 1)); blue.setLabelOrientation (finalcut::FLineEdit::label_above); blue.setLabelText ("Blue"); blue.setRange (0, 255); blue.setValue (0xec); // Set the initial palette values - const auto& wc = getFWidgetColors(); - finalcut::FTerm::setPalette ( wc.term_bg + finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta , int(red.getValue()) , int(green.getValue()) , int(blue.getValue()) ); // Quit button - quit.setGeometry(FPoint(19, 5), FSize(10, 1)); + quit.setGeometry(FPoint(19, 8), FSize(10, 1)); // Add some function callbacks quit.addCallback @@ -119,6 +159,18 @@ Background::Background (finalcut::FWidget* parent) "changed", F_METHOD_CALLBACK (this, &Background::cb_changed) ); + + color_choice.addCallback + ( + "clicked", + F_METHOD_CALLBACK (this, &Background::cb_choice) + ); + + color_choice.addCallback + ( + "row-changed", + F_METHOD_CALLBACK (this, &Background::cb_choice) + ); } //---------------------------------------------------------------------- @@ -128,8 +180,25 @@ Background::~Background() // destructor //---------------------------------------------------------------------- void Background::cb_changed (finalcut::FWidget*, FDataPtr) { - const auto& wc = getFWidgetColors(); - finalcut::FTerm::setPalette ( wc.term_bg + finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta + , int(red.getValue()) + , int(green.getValue()) + , int(blue.getValue()) ); + redraw(); + updateTerminal(); +} + +//---------------------------------------------------------------------- +void Background::cb_choice (finalcut::FWidget*, FDataPtr) +{ + uChar r{}, g{}, b{}; + FDataPtr data_ptr = color_choice.getItemData(); + RGB* rgb = reinterpret_cast(data_ptr); + std::tie(r, g, b) = *rgb; + red.setValue(r); + green.setValue(g); + blue.setValue(b); + finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta , int(red.getValue()) , int(green.getValue()) , int(blue.getValue()) ); @@ -145,6 +214,7 @@ void Background::cb_changed (finalcut::FWidget*, FDataPtr) int main (int argc, char* argv[]) { finalcut::FApplication app(argc, argv); + app.setBackgroundColor(finalcut::fc::LightMagenta); Background dialog(&app); app.setMainWidget(&dialog); dialog.show(); diff --git a/examples/listbox.cpp b/examples/listbox.cpp index 557be176..b0c16d20 100644 --- a/examples/listbox.cpp +++ b/examples/listbox.cpp @@ -65,7 +65,7 @@ FString& doubleToString (std::list::const_iterator iter) } FString& mapToString ( std::map::const_iterator iter ) + , FString>::const_iterator iter ) { auto temp = temp_str.lock(); return *temp = iter->first + ": " + iter->second; diff --git a/examples/opti-move.cpp b/examples/opti-move.cpp index 14f40591..feaa42f5 100644 --- a/examples/opti-move.cpp +++ b/examples/opti-move.cpp @@ -86,7 +86,7 @@ void term_boundaries (int& x, int& y) //---------------------------------------------------------------------- void move (int xold, int yold, int xnew, int ynew) { - // prints the cursor move escape sequence + // Prints the cursor move escape sequence finalcut::FString buffer{}, sequence{}, from{}, to{}, byte{}; const std::string ctrl_character[] = { @@ -100,7 +100,7 @@ void move (int xold, int yold, int xnew, int ynew) term_boundaries(xold, yold); term_boundaries(xnew, ynew); - // get the move string + // Get the move string buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew); for (auto&& ch : buffer) diff --git a/examples/transparent.cpp b/examples/transparent.cpp index fb9ec398..929e2dd3 100644 --- a/examples/transparent.cpp +++ b/examples/transparent.cpp @@ -267,7 +267,7 @@ void MainWindow::onTimer (finalcut::FTimerEvent*) line1 = line1.right(length - 1) + first_Char[0]; line2 = line2.right(length - 1) + first_Char[1]; redraw(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- diff --git a/examples/ui.cpp b/examples/ui.cpp index e3e7e016..0879d02f 100644 --- a/examples/ui.cpp +++ b/examples/ui.cpp @@ -136,7 +136,7 @@ void ProgressDialog::onTimer (finalcut::FTimerEvent*) { auto p = progressBar.getPercentage(); progressBar.setPercentage(++p); - flushOutputBuffer(); + flush(); if ( p != 100 ) return; @@ -154,7 +154,7 @@ void ProgressDialog::onTimer (finalcut::FTimerEvent*) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index b2c716df..8271087f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,6 +45,7 @@ libfinal_la_SOURCES = \ fkey_map.cpp \ fcharmap.cpp \ fspinbox.cpp \ + fcombobox.cpp \ fstartoptions.cpp \ fstatusbar.cpp \ ftermcap.cpp \ @@ -119,6 +120,7 @@ finalcutinclude_HEADERS = \ include/final/fscrollbar.h \ include/final/fscrollview.h \ include/final/fspinbox.h \ + include/final/fcombobox.h \ include/final/fstartoptions.h \ include/final/fstatusbar.h \ include/final/fstring.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index 3ef869e8..518bddb1 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -44,6 +44,7 @@ INCLUDE_HEADERS = \ fscrollbar.h \ fscrollview.h \ fspinbox.h \ + fcombobox.h \ fstatusbar.h \ fstring.h \ fmouse.h \ @@ -106,6 +107,7 @@ OBJS = \ fwindow.o \ fscrollview.o \ fspinbox.o \ + fcombobox.o \ fmessagebox.o \ ftooltip.o \ ffiledialog.o \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index eb51839d..eb8e67c2 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -44,6 +44,7 @@ INCLUDE_HEADERS = \ fscrollbar.h \ fscrollview.h \ fspinbox.h \ + fcombobox.h \ fstatusbar.h \ fstring.h \ fmouse.h \ @@ -106,6 +107,7 @@ OBJS = \ fwindow.o \ fscrollview.o \ fspinbox.o \ + fcombobox.o \ fmessagebox.o \ ftooltip.o \ ffiledialog.o \ diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 4576ebef..4b3c9ffd 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -669,7 +669,7 @@ void FApplication::processKeyboardEvent() return; findKeyboardWidget(); - flushOutputBuffer(); + flush(); keyboard->clearKeyBufferOnTimeout(); if ( isKeyPressed() ) @@ -815,46 +815,15 @@ void FApplication::unsetMoveSizeMode() } //---------------------------------------------------------------------- -void FApplication::closeOpenMenu() +void FApplication::closeDropDown() { // Close the open menu - auto openmenu = FWidget::getOpenMenu(); - auto menu = static_cast(openmenu); - - if ( ! openmenu || ( mouse && mouse->isMoved()) ) + if ( mouse && mouse->isMoved() ) return; - if ( mouse ) - { - const auto& mouse_position = mouse->getPos(); - - if ( menu->containsMenuStructure(mouse_position) ) - return; - } - - bool is_window_menu{false}; - auto super = menu->getSuperMenu(); - - if ( super && menu->isWindowsMenu(super) ) - is_window_menu = true; - else - is_window_menu = false; - - menu->unselectItem(); - menu->hide(); - menu->hideSubMenus(); - menu->hideSuperMenus(); - - // No widget was been clicked and the menu is no dialog menu - if ( ! (FWidget::getClickedWidget() || is_window_menu) ) - FWindow::switchToPrevWindow(this); - - if ( FWidget::getStatusBar() ) - FWidget::getStatusBar()->drawMessage(); - - updateTerminal(); - flushOutputBuffer(); + const auto& mouse_position = mouse->getPos(); + finalcut::closeDropDown (this, mouse_position); } //---------------------------------------------------------------------- @@ -889,7 +858,7 @@ void FApplication::unselectMenubarItems() FWidget::getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -1124,7 +1093,7 @@ void FApplication::processMouseEvent() determineClickedWidget(); unsetMoveSizeMode(); - closeOpenMenu(); + closeDropDown(); unselectMenubarItems(); sendMouseEvent(); @@ -1135,14 +1104,14 @@ void FApplication::processMouseEvent() //---------------------------------------------------------------------- void FApplication::processResizeEvent() { - if ( hasChangedTermSize() ) - { - FResizeEvent r_ev(fc::Resize_Event); - sendEvent(app_object, &r_ev); + if ( ! hasChangedTermSize() ) + return; - if ( r_ev.isAccepted() ) - changeTermSizeFinished(); - } + FResizeEvent r_ev(fc::Resize_Event); + sendEvent(app_object, &r_ev); + + if ( r_ev.isAccepted() ) + changeTermSizeFinished(); } //---------------------------------------------------------------------- diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 43e2b656..d2eb64c1 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -364,7 +364,7 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev) { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -539,7 +539,7 @@ void FButtonGroup::directFocus() { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } diff --git a/src/fcombobox.cpp b/src/fcombobox.cpp new file mode 100644 index 00000000..e955d3ed --- /dev/null +++ b/src/fcombobox.cpp @@ -0,0 +1,733 @@ +/*********************************************************************** +* fcombobox.cpp - Widget FComboBox * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2019 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 * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include "final/fapplication.h" +#include "final/fcolorpair.h" +#include "final/fcombobox.h" +#include "final/fevent.h" +#include "final/flabel.h" +#include "final/flineedit.h" +#include "final/flistbox.h" +#include "final/fmouse.h" +#include "final/fpoint.h" +#include "final/fsize.h" +#include "final/fstatusbar.h" +#include "final/fwidgetcolors.h" + +namespace finalcut +{ + +//---------------------------------------------------------------------- +// class FDropDownListBox +//---------------------------------------------------------------------- + +// constructor and destructor +//---------------------------------------------------------------------- +FDropDownListBox::FDropDownListBox (FWidget* parent) + : FWindow(parent) +{ + init(); +} + +//---------------------------------------------------------------------- +FDropDownListBox::~FDropDownListBox() // destructor +{ + auto fapp = FApplication::getApplicationObject(); + + if ( fapp->isQuit() ) + return; + + FWindow* parent_win{nullptr}; + + if ( auto parent = getParentWidget() ) + parent_win = getWindowWidget(parent); + + if ( parent_win ) + setActiveWindow (parent_win); + else + switchToPrevWindow(this); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::setGeometry ( const FPoint& pos, const FSize& size + , bool adjust ) +{ + FWindow::setGeometry (pos, size, adjust); + + if ( isNewFont() ) + { + FSize new_size(size); + new_size.scaleBy(-1, 0); + list.setGeometry (FPoint(2, 1), new_size, adjust); + } + else + list.setGeometry (FPoint(1, 1), size, adjust); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::show() +{ + if ( ! isVisible() ) + return; + + FWindow::show(); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::hide() +{ + if ( ! isVisible() ) + return; + + FWindow::hide(); + setOpenMenu(nullptr); + const auto& t_geometry = getTermGeometryWithShadow(); + restoreVTerm (t_geometry); + updateTerminal(); + flush(); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::onKeyPress (FKeyEvent* ev) +{ + switch ( ev->key() ) + { + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + hide(); + break; + + default: + break; + } +} + +// private methods of FDropDownListBox +//---------------------------------------------------------------------- +void FDropDownListBox::init() +{ + setAlwaysOnTop(); + ignorePadding(); + setShadow(); + // initialize geometry values + setGeometry (FPoint(1, 1), FSize(3, 3), false); + setMinimumSize (FSize(3, 3)); + hide(); + list.setGeometry (FPoint(1, 1), FSize(3, 3), false); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::draw() +{ + // Fill the background + const auto& wc = getFWidgetColors(); + setColor (wc.menu_active_fg, wc.menu_active_bg); + + if ( isMonochron() ) + setReverse(true); + + clearArea(); + drawShadow(); + + if ( isMonochron() ) + setReverse(false); +} + +//---------------------------------------------------------------------- +void FDropDownListBox::drawShadow() +{ + const auto& wc = getFWidgetColors(); + finalcut::drawShadow(this); + setColor (wc.shadow_fg, wc.shadow_bg); + print() << FPoint(int(getWidth()) + 1, 1) << fc::FullBlock; // █ +} + +//---------------------------------------------------------------------- +bool FDropDownListBox::containsWidget (const FPoint& p) +{ + // Check mouse click position for item, menu and all sub menus + + FWidget* parent = getParentWidget(); + + if ( getTermGeometry().contains(p) ) + return true; + else if ( parent && parent->isInstanceOf("FComboBox") ) + return static_cast(parent)->getTermGeometry().contains(p); + else + return false; +} + + +//---------------------------------------------------------------------- +// class FComboBox +//---------------------------------------------------------------------- + +// constructors and destructor +//---------------------------------------------------------------------- +FComboBox::FComboBox (FWidget* parent) + : FWidget(parent) +{ + init(); +} + +//---------------------------------------------------------------------- +FComboBox::~FComboBox() // destructor +{ } + + +// public methods of FComboBox +//---------------------------------------------------------------------- +void FComboBox::setGeometry ( const FPoint& pos, const FSize& size + , bool adjust ) +{ + FWidget::setGeometry (pos, size, adjust); + FSize input_field_size(size); + input_field_size.scaleBy(-(1 + nf), 0); + input_field.setGeometry (FPoint(1, 1), input_field_size, adjust); +} + +//---------------------------------------------------------------------- +bool FComboBox::setEnable (bool enable) +{ + FWidget::setEnable(enable); + input_field.setEnable(enable); + return enable; +} + +//---------------------------------------------------------------------- +bool FComboBox::setFocus (bool enable) +{ + FWidget::setFocus(enable); + input_field.setFocus(enable); + return enable; +} + +//---------------------------------------------------------------------- +bool FComboBox::setShadow (bool enable) +{ + if ( enable + && getEncoding() != fc::VT100 + && getEncoding() != fc::ASCII ) + { + setFlags().shadow = true; + setShadowSize(FSize(1, 1)); + } + else + { + setFlags().shadow = false; + setShadowSize(FSize(0, 0)); + } + + return getFlags().shadow; +} + +//---------------------------------------------------------------------- +bool FComboBox::setEditable (bool enable) +{ + if ( is_editable == enable ) + return is_editable; + + if ( enable ) + unsetVisibleCursor(); + else + setVisibleCursor(); + + input_field.setReadOnly(! enable); + return (is_editable = enable); +} + +//---------------------------------------------------------------------- +void FComboBox::setMaxVisibleItems (std::size_t items) +{ + // Sets the maximum height of the combo box in elements + + if ( items > getCount() ) + max_items = getCount(); + else + max_items = items; +} + +//---------------------------------------------------------------------- +void FComboBox::insert (FListBoxItem listItem) +{ + list_window.list.insert(listItem); + + if ( getCount() == 1 ) + input_field = list_window.list.getItem(1).getText(); +} + +//---------------------------------------------------------------------- +void FComboBox::remove (std::size_t item) +{ + list_window.list.remove(item); + + if ( ! list_window.isEmpty() ) + { + std::size_t i = list_window.list.currentItem(); + input_field = list_window.list.getItem(i).getText(); + input_field.redraw(); + } + + if ( list_window.isShown() ) + { + // Adjusting the size of the drop-down list + hideDropDown(); + showDropDown(); + } +} + +//---------------------------------------------------------------------- +void FComboBox::clear() +{ + if ( list_window.isShown() ) + hideDropDown(); + + list_window.list.clear(); + input_field.clear(); + redraw(); +} + +//---------------------------------------------------------------------- +void FComboBox::showDropDown() +{ + if ( list_window.isEmpty() ) + return; + + static constexpr std::size_t border = 2; // Size of the top and bottom border + setOpenMenu(&list_window); + FPoint p(getTermPos()); + p.move(0 - int(nf), 1); + setClickedWidget(&list_window.list); + std::size_t w = getWidth(); + std::size_t h = getCount(); + + if ( h > max_items) + h = max_items; + + list_window.setGeometry(p, FSize(w + std::size_t(nf), h + border)); + list_window.show(); + list_window.list.setFocus(); + list_window.redraw(); +} + +//---------------------------------------------------------------------- +void FComboBox::hideDropDown() +{ + if ( list_window.isHidden() ) + return; + + list_window.hide(); + input_field.setFocus(); + input_field.redraw(); +} + +//---------------------------------------------------------------------- +void FComboBox::onKeyPress (FKeyEvent* ev) +{ + if ( ! isEnabled() ) + return; + + switch ( ev->key() ) + { + case fc::Fkey_tab: + focusNextChild(); + break; + + case fc::Fkey_btab: + focusPrevChild(); + break; + + case fc::Fkey_up: + onePosUp(); + ev->accept(); + break; + + case fc::Fkey_down: + onePosDown(); + ev->accept(); + break; + + case fc::Fmkey_up: + case fc::Fckey_up: + hideDropDown(); + ev->accept(); + break; + + case fc::Fkey_f4: + case fc::Fmkey_down: + case fc::Fckey_down: + showDropDown(); + ev->accept(); + break; + + default: + break; + } +} + +//---------------------------------------------------------------------- +void FComboBox::onMouseDown (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( ! hasFocus() ) + { + auto focused_widget = getFocusWidget(); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + } + + int mouse_x = ev->getX(); + int mouse_y = ev->getY(); + + if ( mouse_x >= int(getWidth()) - nf + && mouse_x <= int(getWidth()) && mouse_y == 1 ) + { + if ( list_window.isHidden() ) + showDropDown(); + else + list_window.hide(); + } + + updateTerminal(); +} + +//---------------------------------------------------------------------- +void FComboBox::onMouseUp (FMouseEvent*) +{ } + +//---------------------------------------------------------------------- +void FComboBox::onMouseMove (FMouseEvent* ev) +{ + if ( ev->getButton() != fc::LeftButton ) + return; + + if ( isMouseOverListWindow(ev->getTermPos()) ) + { + passEventToListWindow(ev); // Event handover to window list + return; + } +} + +//---------------------------------------------------------------------- +void FComboBox::onWheel (FWheelEvent* ev) +{ + switch ( ev->getWheel() ) + { + case fc::WheelUp: + onePosUp(); + break; + + case fc::WheelDown: + onePosDown(); + break; + + default: + break; + } +} + +//---------------------------------------------------------------------- +void FComboBox::onFocusOut (FFocusEvent*) +{ + hideDropDown(); +} + + +// private methods of FComboBox +//---------------------------------------------------------------------- +bool FComboBox::isMouseOverListWindow (const FPoint& termpos) +{ + if ( list_window.isShown() ) + { + const auto& list_geometry = list_window.getTermGeometry(); + + if ( list_geometry.contains(termpos) ) + return true; + } + + return false; +} + +//---------------------------------------------------------------------- +void FComboBox::init() +{ + setShadow(); + auto parent_widget = getParentWidget(); + FLabel* label = input_field.getLabelObject(); + label->setParent(getParent()); + label->setForegroundColor (parent_widget->getForegroundColor()); + label->setBackgroundColor (parent_widget->getBackgroundColor()); + input_field.setLabelAssociatedWidget(this); + input_field.unsetShadow(); + adjustSize(); + initCallbacks(); + + if ( isNewFont() ) + nf = 1; +} + +//---------------------------------------------------------------------- +void FComboBox::initCallbacks() +{ + input_field.addCallback + ( + "mouse-press", + F_METHOD_CALLBACK (this, &FComboBox::cb_inputFieldSwitch) + ); + + input_field.addCallback + ( + "mouse-move", + F_METHOD_CALLBACK (this, &FComboBox::cb_inputFieldHandOver) + ); + + list_window.list.addCallback + ( + "row-changed", + F_METHOD_CALLBACK (this, &FComboBox::cb_setInputField) + ); + + list_window.list.addCallback + ( + "row-selected", + F_METHOD_CALLBACK (this, &FComboBox::cb_closeComboBox) + ); + + list_window.list.addCallback + ( + "clicked", + F_METHOD_CALLBACK (this, &FComboBox::cb_closeComboBox) + ); +} + +//---------------------------------------------------------------------- +void FComboBox::draw() +{ + const auto& wc = getFWidgetColors(); + + FColorPair button_color = [&] () -> FColorPair + { + if ( list_window.isEmpty() ) + return FColorPair ( wc.scrollbar_button_inactive_fg + , wc.scrollbar_button_inactive_bg ); + else + return FColorPair ( wc.scrollbar_button_fg + , wc.scrollbar_button_bg ); + }(); + + print() << FPoint(int(getWidth()) - nf, 1) + << button_color; + + if ( isNewFont() ) + print() << NF_button_arrow_down; + else + print() << fc::BlackDownPointingTriangle; // ▼ + + if ( getFlags().shadow ) + drawShadow(this); +} + +//---------------------------------------------------------------------- +void FComboBox::onePosUp() +{ + std::size_t i = list_window.list.currentItem(); + + if ( i > 1 ) + i--; + else + return; + + list_window.list.setCurrentItem(i); + input_field = list_window.list.getItem(i).getText(); + input_field.redraw(); + processChanged(); +} + +//---------------------------------------------------------------------- +void FComboBox::onePosDown() +{ + std::size_t i = list_window.list.currentItem(); + + if ( i < list_window.list.getCount() ) + i++; + else + return; + + list_window.list.setCurrentItem(i); + input_field = list_window.list.getItem(i).getText(); + input_field.redraw(); + processChanged(); +} + +//---------------------------------------------------------------------- +void FComboBox::passEventToListWindow (FMouseEvent*& ev) +{ + // Mouse event handover to list window + + const auto& t = ev->getTermPos(); + const auto& p = list_window.list.termToWidgetPos(t); + int b = ev->getButton(); + + try + { + const auto& _ev = \ + std::make_shared(fc::MouseMove_Event, p, t, b); + setClickedWidget(&list_window.list); + list_window.list.setFocus(); + list_window.list.onMouseMove(_ev.get()); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << ex.what() << std::endl; + } +} + +//---------------------------------------------------------------------- +void FComboBox::processClick() +{ + emitCallback("clicked"); +} + +//---------------------------------------------------------------------- +void FComboBox::processChanged() +{ + emitCallback("row-changed"); +} + +//---------------------------------------------------------------------- +void FComboBox::cb_setInputField (FWidget*, FDataPtr) +{ + auto& list = list_window.list; + std::size_t i = list.currentItem(); + input_field = list.getItem(i).getText(); + input_field.redraw(); + processChanged(); +} + +//---------------------------------------------------------------------- +void FComboBox::cb_closeComboBox (FWidget*, FDataPtr) +{ + hideDropDown(); + processClick(); +} + +//---------------------------------------------------------------------- +void FComboBox::cb_inputFieldSwitch (FWidget*, FDataPtr) +{ + auto mouse = getFMouseControl(); + + if ( mouse && ! mouse->isLeftButtonPressed() ) + return; + + if ( list_window.isShown() ) + { + hideDropDown(); + } + else if ( ! is_editable ) + { + if ( ! hasFocus() ) + { + auto focused_widget = getFocusWidget(); + setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + } + + showDropDown(); + } +} + +//---------------------------------------------------------------------- +void FComboBox::cb_inputFieldHandOver (FWidget*, FDataPtr) +{ + auto mouse = getFMouseControl(); + + if ( ! mouse || list_window.isHidden() ) + return; + + const auto& t = mouse->getPos(); + auto p = list_window.list.termToWidgetPos(t); + int b = ( mouse->isLeftButtonPressed() ) ? fc::LeftButton : 0; + + try + { + const auto& _ev = \ + std::make_shared(fc::MouseMove_Event, p, t, b); + setClickedWidget(&list_window.list); + list_window.list.setFocus(); + list_window.list.onMouseMove(_ev.get()); + } + catch (const std::bad_alloc& ex) + { + std::cerr << bad_alloc_str << ex.what() << std::endl; + } +} + +// non-member functions +//---------------------------------------------------------------------- +void closeOpenComboBox() +{ + // Close open comboboxes + auto openmenu = FWidget::getOpenMenu(); + + if ( ! openmenu ) + return; + + if ( openmenu->isInstanceOf("FDropDownListBox") ) + { + auto drop_down = static_cast(openmenu); + drop_down->hide(); + } +} + +//---------------------------------------------------------------------- +bool closeComboBox ( FDropDownListBox* list_window + , const FPoint& mouse_position ) +{ + // Close the drop down list box + + if ( ! list_window ) + return false; + + if ( list_window->containsWidget(mouse_position) ) + return false; + + list_window->hide(); + return true; +} + +} // namespace finalcut diff --git a/src/fdialog.cpp b/src/fdialog.cpp index c5c17cdd..26d2548d 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -23,6 +23,7 @@ #include #include "final/fapplication.h" +#include "final/fcombobox.h" #include "final/fdialog.h" #include "final/fevent.h" #include "final/fmenuitem.h" @@ -1176,7 +1177,7 @@ void FDialog::leaveMenu() getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1193,6 +1194,7 @@ void FDialog::openMenu() } else { + finalcut::closeOpenComboBox(); setOpenMenu(dialog_menu); FPoint pos(getPos()); pos.y_ref()++; @@ -1221,7 +1223,7 @@ void FDialog::selectFirstMenuItem() getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- diff --git a/src/flabel.cpp b/src/flabel.cpp index 6781c06a..01bf3000 100644 --- a/src/flabel.cpp +++ b/src/flabel.cpp @@ -198,7 +198,7 @@ void FLabel::onMouseDown (FMouseEvent* ev) { accel_widget->getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } } @@ -225,7 +225,7 @@ void FLabel::onAccel (FAccelEvent* ev) { accel_widget->getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } } diff --git a/src/flineedit.cpp b/src/flineedit.cpp index ca801734..c59e6b63 100644 --- a/src/flineedit.cpp +++ b/src/flineedit.cpp @@ -166,6 +166,17 @@ bool FLineEdit::setShadow (bool enable) return getFlags().shadow; } +//---------------------------------------------------------------------- +bool FLineEdit::setReadOnly (bool enable) +{ + if ( enable ) + unsetVisibleCursor(); + else + setVisibleCursor(); + + return (read_only = enable); +} + //---------------------------------------------------------------------- void FLineEdit::setText (const FString& txt) { @@ -183,7 +194,9 @@ void FLineEdit::setText (const FString& txt) if ( isShown() ) { - cursorEnd(); + if ( ! isReadOnly() ) + cursorEnd(); + adjustTextOffset(); } } @@ -201,7 +214,9 @@ void FLineEdit::setMaxLength (std::size_t max) if ( isShown() ) { - cursorEnd(); + if ( ! isReadOnly() ) + cursorEnd(); + adjustTextOffset(); } } @@ -209,6 +224,9 @@ void FLineEdit::setMaxLength (std::size_t max) //---------------------------------------------------------------------- void FLineEdit::setCursorPosition (std::size_t pos) { + if ( isReadOnly() ) + return; + if ( pos == 0 ) cursor_pos = 1; else @@ -260,7 +278,9 @@ void FLineEdit::hide() //---------------------------------------------------------------------- void FLineEdit::clear() { - cursor_pos = 0; + if ( ! isReadOnly() ) + cursor_pos = 0; + text_offset = 0; char_width_offset = 0; text.clear(); @@ -270,6 +290,9 @@ void FLineEdit::clear() //---------------------------------------------------------------------- void FLineEdit::onKeyPress (FKeyEvent* ev) { + if ( isReadOnly() ) + return; + FKey key = ev->key(); switch ( key ) @@ -338,7 +361,7 @@ void FLineEdit::onKeyPress (FKeyEvent* ev) //---------------------------------------------------------------------- void FLineEdit::onMouseDown (FMouseEvent* ev) { - if ( ev->getButton() != fc::LeftButton ) + if ( ev->getButton() != fc::LeftButton || isReadOnly() ) return; if ( ! hasFocus() ) @@ -389,7 +412,7 @@ void FLineEdit::onMouseUp (FMouseEvent*) //---------------------------------------------------------------------- void FLineEdit::onMouseMove (FMouseEvent* ev) { - if ( ev->getButton() != fc::LeftButton ) + if ( ev->getButton() != fc::LeftButton || isReadOnly() ) return; std::size_t len = print_text.getLength(); @@ -531,7 +554,7 @@ void FLineEdit::onAccel (FAccelEvent* ev) { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } } @@ -542,23 +565,26 @@ void FLineEdit::onAccel (FAccelEvent* ev) //---------------------------------------------------------------------- void FLineEdit::onHide (FHideEvent*) { - if ( ! insert_mode ) + if ( ! insert_mode && ! isReadOnly() ) setInsertCursor(); } //---------------------------------------------------------------------- void FLineEdit::onFocusIn (FFocusEvent*) { - if ( insert_mode ) - setInsertCursor(); - else - unsetInsertCursor(); + if ( ! isReadOnly() ) + { + if ( insert_mode ) + setInsertCursor(); + else + unsetInsertCursor(); + } if ( getStatusBar() ) { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -571,7 +597,7 @@ void FLineEdit::onFocusOut (FFocusEvent*) getStatusBar()->drawMessage(); } - if ( ! insert_mode ) + if ( ! insert_mode && ! isReadOnly() ) setInsertCursor(); } @@ -623,7 +649,12 @@ void FLineEdit::init() { const auto& wc = getFWidgetColors(); label->setAccelWidget(this); - setVisibleCursor(); + + if ( isReadOnly() ) + unsetVisibleCursor(); + else + setVisibleCursor(); + setShadow(); if ( isEnabled() ) @@ -658,7 +689,7 @@ bool FLineEdit::hasHotkey() //---------------------------------------------------------------------- void FLineEdit::draw() { - if ( cursor_pos == NOT_SET ) + if ( cursor_pos == NOT_SET && isReadOnly() ) cursorEnd(); if ( ! isShown() ) diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 420c60ef..f6a3f00e 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -202,6 +202,9 @@ void FListBox::insert (FListBoxItem listItem) itemlist.push_back (listItem); + if ( current == 0 ) + current = 1; + std::size_t element_count = getCount(); recalculateVerticalBar (element_count); } @@ -300,13 +303,8 @@ void FListBox::onKeyPress (FKeyEvent* ev) processKeyAction(ev); // Process the keystrokes if ( current_before != current ) - { processChanged(); - if ( ! isMultiSelection() ) - processSelect(); - } - if ( ev->isAccepted() ) { bool draw_vbar( yoffset_before != yoffset ); @@ -330,12 +328,14 @@ void FListBox::onMouseDown (FMouseEvent* ev) getWidgetFocus(); int yoffset_before = yoffset; + std::size_t current_before = current; int mouse_x = ev->getX(); int mouse_y = ev->getY(); if ( mouse_x > 1 && mouse_x < int(getWidth()) && mouse_y > 1 && mouse_y < int(getHeight()) ) { + click_on_list = true; std::size_t element_count = getCount(); current = std::size_t(yoffset + mouse_y - 1); @@ -347,6 +347,11 @@ void FListBox::onMouseDown (FMouseEvent* ev) if ( ev->getButton() == fc::RightButton ) multiSelection(current); + if ( current_before != current ) + { + processChanged(); + } + if ( isShown() ) drawList(); @@ -356,13 +361,15 @@ void FListBox::onMouseDown (FMouseEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } //---------------------------------------------------------------------- void FListBox::onMouseUp (FMouseEvent* ev) { + click_on_list = false; + if ( drag_scroll != fc::noScroll ) stopDragScroll(); @@ -374,8 +381,6 @@ void FListBox::onMouseUp (FMouseEvent* ev) if ( mouse_x > 1 && mouse_x < int(getWidth()) && mouse_y > 1 && mouse_y < int(getHeight()) ) { - processChanged(); - if ( ! isMultiSelection() ) processSelect(); } @@ -400,6 +405,7 @@ void FListBox::onMouseMove (FMouseEvent* ev) if ( mouse_x > 1 && mouse_x < int(getWidth()) && mouse_y > 1 && mouse_y < int(getHeight()) ) { + click_on_list = true; std::size_t element_count = getCount(); current = std::size_t(yoffset + mouse_y - 1); @@ -408,11 +414,16 @@ void FListBox::onMouseMove (FMouseEvent* ev) inc_search.clear(); - // Handle multiple selections - if ( ev->getButton() == fc::RightButton - && current_before != current ) + if ( current_before != current ) { - multiSelectionUpTo(current); + // Handle multiple selections + changes + if ( ev->getButton() == fc::RightButton) + { + processChanged(); + multiSelectionUpTo(current); + } + else if ( ev->getButton() == fc::LeftButton) + processChanged(); } if ( isShown() ) @@ -424,13 +435,13 @@ void FListBox::onMouseMove (FMouseEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } // Auto-scrolling when dragging mouse outside the widget - if ( mouse_y < 2 ) + if ( click_on_list && mouse_y < 2 ) dragUp (ev->getButton()); - else if ( mouse_y >= int(getHeight()) ) + else if ( click_on_list && mouse_y >= int(getHeight()) ) dragDown (ev->getButton()); else stopDragScroll(); @@ -485,6 +496,7 @@ void FListBox::onTimer (FTimerEvent*) if ( current_before != current ) { inc_search.clear(); + processChanged(); // Handle multiple selections if ( drag_scroll == fc::scrollUpSelect @@ -501,7 +513,7 @@ void FListBox::onTimer (FTimerEvent*) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -533,9 +545,6 @@ void FListBox::onWheel (FWheelEvent* ev) { inc_search.clear(); processChanged(); - - if ( ! isMultiSelection() ) - processSelect(); } if ( isShown() ) @@ -547,7 +556,7 @@ void FListBox::onWheel (FWheelEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -770,12 +779,12 @@ void FListBox::drawScrollbars() if ( ! hbar->isShown() && isHorizontallyScrollable() ) hbar->show(); else - vbar->redraw(); + hbar->redraw(); if ( ! vbar->isShown() && isVerticallyScrollable() ) vbar->show(); else - hbar->redraw(); + vbar->redraw(); } @@ -1085,7 +1094,7 @@ inline void FListBox::updateDrawing (bool draw_vbar, bool draw_hbar) hbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1769,9 +1778,6 @@ void FListBox::cb_VBarChange (FWidget*, FDataPtr) { inc_search.clear(); processChanged(); - - if ( ! isMultiSelection() ) - processSelect(); } if ( isShown() ) @@ -1785,7 +1791,7 @@ void FListBox::cb_VBarChange (FWidget*, FDataPtr) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -1838,7 +1844,7 @@ void FListBox::cb_HBarChange (FWidget*, FDataPtr) { drawList(); updateTerminal(); - flushOutputBuffer(); + flush(); } if ( scrollType >= FScrollbar::scrollStepBackward ) @@ -1849,7 +1855,7 @@ void FListBox::cb_HBarChange (FWidget*, FDataPtr) hbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } diff --git a/src/flistview.cpp b/src/flistview.cpp index 6f4d4d8a..a781e553 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -968,7 +968,7 @@ void FListView::onMouseDown (FMouseEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } } @@ -1073,7 +1073,7 @@ void FListView::onMouseMove (FMouseEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } // auto-scrolling when dragging mouse outside the widget @@ -1160,7 +1160,7 @@ void FListView::onTimer (FTimerEvent*) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1199,7 +1199,7 @@ void FListView::onWheel (FWheelEvent* ev) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1462,12 +1462,12 @@ void FListView::drawScrollbars() if ( ! hbar->isShown() && isHorizontallyScrollable() ) hbar->show(); else - vbar->redraw(); + hbar->redraw(); if ( ! vbar->isShown() && isVerticallyScrollable() ) vbar->show(); else - hbar->redraw(); + vbar->redraw(); } //---------------------------------------------------------------------- @@ -1928,7 +1928,7 @@ void FListView::updateDrawing (bool draw_vbar, bool draw_hbar) hbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -2636,7 +2636,7 @@ void FListView::cb_VBarChange (FWidget*, FDataPtr) vbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -2688,7 +2688,7 @@ void FListView::cb_HBarChange (FWidget*, FDataPtr) drawHeadlines(); drawList(); updateTerminal(); - flushOutputBuffer(); + flush(); } if ( scrollType >= FScrollbar::scrollStepBackward ) @@ -2699,7 +2699,7 @@ void FListView::cb_HBarChange (FWidget*, FDataPtr) hbar->drawBar(); updateTerminal(); - flushOutputBuffer(); + flush(); } } diff --git a/src/fmenu.cpp b/src/fmenu.cpp index b3fd4c7a..fe652dd2 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -21,6 +21,7 @@ ***********************************************************************/ #include +#include #include #include "final/fapplication.h" @@ -102,7 +103,7 @@ void FMenu::hide() const auto& t_geometry = getTermGeometryWithShadow(); restoreVTerm (t_geometry); updateTerminal(); - flushOutputBuffer(); + flush(); if ( ! isSubMenu() ) { @@ -204,7 +205,7 @@ void FMenu::onMouseDown (FMouseEvent* ev) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } return; @@ -313,7 +314,7 @@ void FMenu::onMouseMove (FMouseEvent* ev) { closeOpenedSubMenu(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -347,7 +348,7 @@ void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr) // private methods of FMenu //---------------------------------------------------------------------- -bool FMenu::isWindowsMenu (const FWidget* w) const +bool FMenu::isDialog (const FWidget* w) const { return w->isDialogWidget(); } @@ -381,6 +382,13 @@ bool FMenu::isSubMenu() const return false; } +//---------------------------------------------------------------------- +bool FMenu::isDialogMenu() const +{ + auto super = getSuperMenu(); + return ( super ) ? super->isDialogWidget() : false; +} + //---------------------------------------------------------------------- bool FMenu::isMouseOverMenu (const FPoint& termpos) { @@ -584,7 +592,7 @@ void FMenu::openSubMenu (FMenu* sub_menu, bool select) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -635,7 +643,7 @@ void FMenu::hideSuperMenus() m->hide(); m->hideSuperMenus(); } - else if ( isWindowsMenu(super) ) + else if ( isDialog(super) ) { auto dgl = static_cast(super); dgl->leaveMenu(); @@ -696,7 +704,7 @@ void FMenu::mouseDownSubmenu (FMenuItem* m_item) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -764,7 +772,7 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } return true; @@ -1038,7 +1046,7 @@ bool FMenu::selectNextItem() redraw(); updateTerminal(); - flushOutputBuffer(); + flush(); break; } @@ -1088,7 +1096,7 @@ bool FMenu::selectPrevItem() redraw(); updateTerminal(); - flushOutputBuffer(); + flush(); break; } } @@ -1151,7 +1159,7 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev) hide(); hideSuperMenus(); updateTerminal(); - flushOutputBuffer(); + flush(); ev->accept(); item->processClicked(); } @@ -1494,7 +1502,7 @@ inline void FMenu::selectPrevMenu (FKeyEvent* ev) getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } else keypressMenuBar(ev); // select previous menu @@ -1559,7 +1567,7 @@ inline void FMenu::closeMenu() if ( getStatusBar() ) getStatusBar()->clearMessage(); - if ( ! (super && isWindowsMenu(super)) ) + if ( ! (super && isDialog(super)) ) switchToPrevWindow(this); } @@ -1567,7 +1575,7 @@ inline void FMenu::closeMenu() getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1576,4 +1584,30 @@ void FMenu::processActivate() emitCallback("activate"); } + +// non-member functions +//---------------------------------------------------------------------- +std::tuple closeOpenMenus ( FMenu* menu + , const FPoint& mouse_position ) +{ + // Close the open menu + + bool is_dialog_menu{false}; + + if ( ! menu ) + return std::make_tuple(false, false); + + if ( menu->containsMenuStructure(mouse_position) ) + return std::make_tuple(true, false); + + if ( menu->isDialogMenu() ) + is_dialog_menu = true; + + menu->unselectItem(); + menu->hide(); + menu->hideSubMenus(); + menu->hideSuperMenus(); + return std::make_tuple (false, is_dialog_menu); +} + } // namespace finalcut diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 46f12767..f6b8ece2 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -971,7 +971,7 @@ void FMenuBar::leaveMenuBar() getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); mouse_down = false; } diff --git a/src/fmenuitem.cpp b/src/fmenuitem.cpp index 8ad5608a..a57261c7 100644 --- a/src/fmenuitem.cpp +++ b/src/fmenuitem.cpp @@ -249,7 +249,7 @@ void FMenuItem::openMenu() dd_menu->raiseWindow(); dd_menu->redraw(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -296,7 +296,7 @@ void FMenuItem::onMouseDoubleClick (FMouseEvent* ev) passMouseEvent (mbar, ev, fc::MouseDoubleClick_Event); } - if ( isWindowsMenu(super_menu) ) + if ( isDialog(super_menu) ) { auto dgl = static_cast(super_menu); passMouseEvent (dgl, ev, fc::MouseDoubleClick_Event); @@ -321,7 +321,7 @@ void FMenuItem::onMouseDown (FMouseEvent* ev) passMouseEvent (mbar, ev, fc::MouseDown_Event); } - if ( isWindowsMenu(super_menu) ) + if ( isDialog(super_menu) ) { auto dgl = static_cast(super_menu); passMouseEvent (dgl, ev, fc::MouseDown_Event); @@ -346,7 +346,7 @@ void FMenuItem::onMouseUp (FMouseEvent* ev) passMouseEvent (mbar, ev, fc::MouseUp_Event); } - if ( isWindowsMenu(super_menu) ) + if ( isDialog(super_menu) ) { auto dgl = static_cast(super_menu); passMouseEvent (dgl, ev, fc::MouseUp_Event); @@ -371,7 +371,7 @@ void FMenuItem::onMouseMove (FMouseEvent* ev) passMouseEvent (mbar, ev, fc::MouseMove_Event); } - if ( isWindowsMenu(super_menu) ) + if ( isDialog(super_menu) ) { auto dgl = static_cast(super_menu); passMouseEvent (dgl, ev, fc::MouseMove_Event); @@ -458,7 +458,7 @@ void FMenuItem::onFocusOut (FFocusEvent*) // protected methods of FMenuItem //---------------------------------------------------------------------- -bool FMenuItem::isWindowsMenu (FWidget* w) const +bool FMenuItem::isDialog (FWidget* w) const { return ( w ) ? w->isDialogWidget() : false; } diff --git a/src/fpoint.cpp b/src/fpoint.cpp index f9af58ae..aed9d5b7 100644 --- a/src/fpoint.cpp +++ b/src/fpoint.cpp @@ -53,16 +53,16 @@ FPoint& FPoint::operator = (FPoint&& p) //---------------------------------------------------------------------- FPoint& FPoint::operator += (const FPoint& p) { - xpos = xpos + p.xpos; - ypos = ypos + p.ypos; + xpos += p.xpos; + ypos += p.ypos; return *this; } //---------------------------------------------------------------------- FPoint& FPoint::operator -= (const FPoint& p) { - xpos = xpos - p.xpos; - ypos = ypos - p.ypos; + xpos -= p.xpos; + ypos -= p.ypos; return *this; } @@ -91,6 +91,20 @@ bool FPoint::isOrigin() const return xpos == 0 && ypos == 0; } +//---------------------------------------------------------------------- +void FPoint::move (int dx, int dy) +{ + xpos += dx; + ypos += dy; +} + +//---------------------------------------------------------------------- +void FPoint::move (const FPoint& d) +{ + xpos += d.getX(); + ypos += d.getY(); +} + //---------------------------------------------------------------------- std::ostream& operator << (std::ostream& outstr, const FPoint& p) { diff --git a/src/fprogressbar.cpp b/src/fprogressbar.cpp index d5c6c59b..749625c5 100644 --- a/src/fprogressbar.cpp +++ b/src/fprogressbar.cpp @@ -133,7 +133,7 @@ void FProgressbar::draw() if ( getFlags().shadow ) drawShadow(this); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -179,7 +179,7 @@ void FProgressbar::drawProgressBar() setReverse(false); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- diff --git a/src/frect.cpp b/src/frect.cpp index 24b1d9b1..87399cf3 100644 --- a/src/frect.cpp +++ b/src/frect.cpp @@ -229,19 +229,19 @@ void FRect::setCoordinates (int x1, int y1, int x2, int y2) //---------------------------------------------------------------------- void FRect::move (int dx, int dy) { - X1 = X1 + dx; - Y1 = Y1 + dy; - X2 = X2 + dx; - Y2 = Y2 + dy; + X1 += dx; + Y1 += dy; + X2 += dx; + Y2 += dy; } //---------------------------------------------------------------------- void FRect::move (const FPoint& d) { - X1 = X1 + d.getX(); - Y1 = Y1 + d.getY(); - X2 = X2 + d.getX(); - Y2 = Y2 + d.getY(); + X1 += d.getX(); + Y1 += d.getY(); + X2 += d.getX(); + Y2 += d.getY(); } //---------------------------------------------------------------------- @@ -332,6 +332,7 @@ FRect& FRect::operator = (FRect&& r) return *this; } +// FRect non-member operators //---------------------------------------------------------------------- FRect operator + (const FRect& r, const FSize& s) { diff --git a/src/fscrollbar.cpp b/src/fscrollbar.cpp index a6692734..6e2bab09 100644 --- a/src/fscrollbar.cpp +++ b/src/fscrollbar.cpp @@ -129,8 +129,7 @@ void FScrollbar::setPageSize (int document_size, int page_size) //---------------------------------------------------------------------- void FScrollbar::setOrientation (fc::orientation o) { - std::size_t nf{0}; - length = ( getHeight() > getWidth() ) ? getHeight() : getWidth(); + length = ( o == fc::vertical ) ? getHeight() : getWidth(); if ( o == fc::vertical && bar_orientation == fc::horizontal ) { @@ -141,12 +140,9 @@ void FScrollbar::setOrientation (fc::orientation o) { setWidth(length); setHeight(1); - - if ( isNewFont() ) - nf = 2; } - slider_length = bar_length = length - nf - 2; + calculateSliderValues(); bar_orientation = o; } @@ -158,10 +154,9 @@ void FScrollbar::setGeometry ( const FPoint& pos, const FSize& size FWidget::setGeometry (pos, size, adjust); - std::size_t nf{0}; std::size_t w = size.getWidth(); std::size_t h = size.getHeight(); - length = ( h > w ) ? h : w; + length = ( bar_orientation == fc::vertical ) ? h : w; if ( bar_orientation == fc::vertical ) { @@ -172,12 +167,9 @@ void FScrollbar::setGeometry ( const FPoint& pos, const FSize& size { setWidth(length); setHeight(1); - - if ( isNewFont() ) - nf = 2; } - slider_length = bar_length = length - nf - 2; + calculateSliderValues(); } //---------------------------------------------------------------------- diff --git a/src/fsize.cpp b/src/fsize.cpp index 94e01e28..e50a7b4e 100644 --- a/src/fsize.cpp +++ b/src/fsize.cpp @@ -122,6 +122,7 @@ void FSize::scaleBy (const FPoint& d) scaleBy (d.getX(), d.getY()); } +// FSize non-member operators //---------------------------------------------------------------------- std::ostream& operator << (std::ostream& outstr, const FSize& s) { diff --git a/src/fspinbox.cpp b/src/fspinbox.cpp index a6555f9b..7b82503e 100644 --- a/src/fspinbox.cpp +++ b/src/fspinbox.cpp @@ -97,6 +97,7 @@ bool FSpinBox::setShadow (bool enable) return getFlags().shadow; } + //---------------------------------------------------------------------- void FSpinBox::setValue (sInt64 n) { diff --git a/src/fswitch.cpp b/src/fswitch.cpp index 67328d79..4a47316c 100644 --- a/src/fswitch.cpp +++ b/src/fswitch.cpp @@ -124,7 +124,7 @@ void FSwitch::draw() drawCheckButton(); FToggleButton::draw(); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- diff --git a/src/ftextview.cpp b/src/ftextview.cpp index fa31ca0b..bf0f2107 100644 --- a/src/ftextview.cpp +++ b/src/ftextview.cpp @@ -609,7 +609,7 @@ void FTextView::draw() setCursorPos (FPoint(int(getWidth()), int(getHeight()))); updateTerminal(); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -634,12 +634,12 @@ void FTextView::drawScrollbars() if ( ! hbar->isShown() && isHorizontallyScrollable() ) hbar->show(); else - vbar->redraw(); + hbar->redraw(); if ( ! vbar->isShown() && isVerticallyScrollable() ) vbar->show(); else - hbar->redraw(); + vbar->redraw(); } //---------------------------------------------------------------------- diff --git a/src/ftogglebutton.cpp b/src/ftogglebutton.cpp index ce6b21a6..0ec66d91 100644 --- a/src/ftogglebutton.cpp +++ b/src/ftogglebutton.cpp @@ -221,7 +221,7 @@ void FToggleButton::onMouseDown (FMouseEvent* ev) { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } } @@ -298,7 +298,7 @@ void FToggleButton::onAccel (FAccelEvent* ev) { getStatusBar()->drawMessage(); updateTerminal(); - flushOutputBuffer(); + flush(); } processClick(); diff --git a/src/ftooltip.cpp b/src/ftooltip.cpp index c8b69e6e..54ccadb7 100644 --- a/src/ftooltip.cpp +++ b/src/ftooltip.cpp @@ -75,21 +75,6 @@ void FToolTip::setText (const FString& txt) calculateDimensions(); } -//---------------------------------------------------------------------- -void FToolTip::draw() -{ - int y{0}; - setColor(); - clearArea(); - drawBorder(); - - for (auto&& line : text_components) - { - print() << FPoint(3, 2 + y) << line; - y++; - } -} - //---------------------------------------------------------------------- void FToolTip::show() { @@ -128,6 +113,21 @@ void FToolTip::init() calculateDimensions(); } +//---------------------------------------------------------------------- +void FToolTip::draw() +{ + int y{0}; + setColor(); + clearArea(); + drawBorder(); + + for (auto&& line : text_components) + { + print() << FPoint(3, 2 + y) << line; + y++; + } +} + //---------------------------------------------------------------------- void FToolTip::calculateDimensions() { diff --git a/src/fvterm.cpp b/src/fvterm.cpp index fc481257..44b0aa3f 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -144,7 +144,7 @@ void FVTerm::setTermXY (int x, int y) if ( move_str ) appendOutputBuffer(move_str); - flushOutputBuffer(); + flush(); term_pos->setPoint(x, y); } @@ -158,7 +158,7 @@ void FVTerm::hideCursor (bool enable) if ( visibility_str ) appendOutputBuffer(visibility_str); - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -590,6 +590,21 @@ void FVTerm::print (const FColorPair& pair) setColor (pair.getForegroundColor(), pair.getBackgroundColor()); } +//---------------------------------------------------------------------- +void FVTerm::flush() +{ + // Flush the output buffer + + while ( ! output_buffer->empty() ) + { + static FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); + FTermPutchar (output_buffer->front()); + output_buffer->pop(); + } + + std::fflush(stdout); +} + // protected methods of FVTerm //---------------------------------------------------------------------- @@ -1278,19 +1293,6 @@ void FVTerm::finishTerminalUpdate() terminal_update_complete = true; } -//---------------------------------------------------------------------- -void FVTerm::flushOutputBuffer() -{ - while ( ! output_buffer->empty() ) - { - static FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); - FTermPutchar (output_buffer->front()); - output_buffer->pop(); - } - - std::fflush(stdout); -} - // private methods of FVTerm //---------------------------------------------------------------------- @@ -1940,7 +1942,7 @@ void FVTerm::finish() if ( FTerm::hasAlternateScreen() ) clearTerm(); - flushOutputBuffer(); + flush(); if ( output_buffer ) delete output_buffer; @@ -2089,7 +2091,7 @@ bool FVTerm::clearTerm (int fillchar) setTermXY (0, 0); } - flushOutputBuffer(); + flush(); return true; } @@ -3047,7 +3049,7 @@ int FVTerm::appendOutputBuffer (int ch) output_buffer->push(ch); if ( output_buffer->size() >= TERMINAL_OUTPUT_BUFFER_SIZE ) - flushOutputBuffer(); + flush(); return ch; } diff --git a/src/fwidget.cpp b/src/fwidget.cpp index d942695f..b3762185 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -973,7 +973,7 @@ void FWidget::redraw() if ( redraw_root_widget == this ) { updateTerminal(); - flushOutputBuffer(); + flush(); redraw_root_widget = nullptr; } } @@ -1053,7 +1053,7 @@ void FWidget::show() { finishTerminalUpdate(); updateTerminal(); - flushOutputBuffer(); + flush(); show_root_widget = nullptr; } @@ -1373,7 +1373,7 @@ void FWidget::hideArea (const FSize& size) print() << FPoint(1, 1 + y) << FString(size.getWidth(), L' '); } - flushOutputBuffer(); + flush(); } //---------------------------------------------------------------------- @@ -1519,10 +1519,12 @@ bool FWidget::event (FEvent* ev) break; case fc::MouseDown_Event: + emitCallback("mouse-press"); onMouseDown (static_cast(ev)); break; case fc::MouseUp_Event: + emitCallback("mouse-release"); onMouseUp (static_cast(ev)); break; @@ -1531,18 +1533,22 @@ bool FWidget::event (FEvent* ev) break; case fc::MouseWheel_Event: + emitWheelCallback(static_cast(ev)); onWheel (static_cast(ev)); break; case fc::MouseMove_Event: + emitCallback("mouse-move"); onMouseMove (static_cast(ev)); break; case fc::FocusIn_Event: + emitCallback("focus-in"); onFocusIn (static_cast(ev)); break; case fc::FocusOut_Event: + emitCallback("focus-out"); onFocusOut (static_cast(ev)); break; @@ -1829,6 +1835,17 @@ void FWidget::KeyDownEvent (FKeyEvent* kev) } } +//---------------------------------------------------------------------- +void FWidget::emitWheelCallback (FWheelEvent* ev) +{ + int wheel = ev->getWheel(); + + if ( wheel == fc::WheelUp ) + emitCallback("mouse-wheel-up"); + else if ( wheel == fc::WheelDown ) + emitCallback("mouse-wheel-down"); +} + //---------------------------------------------------------------------- void FWidget::setWindowFocus (bool enable) { @@ -1894,7 +1911,7 @@ bool FWidget::changeFocus ( FWidget* follower, FWidget* parent redraw(); follower->redraw(); updateTerminal(); - flushOutputBuffer(); + flush(); } } diff --git a/src/fwindow.cpp b/src/fwindow.cpp index 02109dbc..72fcc55b 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -23,7 +23,9 @@ #include #include "final/fapplication.h" +#include "final/fcombobox.h" #include "final/fevent.h" +#include "final/fmenu.h" #include "final/fmenubar.h" #include "final/fstatusbar.h" #include "final/fwindow.h" @@ -871,4 +873,46 @@ void FWindow::processAlwaysOnTop() } } +// non-member functions +//---------------------------------------------------------------------- +void closeDropDown (FWidget* widget, const FPoint& mouse_position) +{ + // Close the pop down windows + + bool is_dialog_menu{false}; + auto openmenu = FWidget::getOpenMenu(); + + if ( ! openmenu ) + return; + + if ( openmenu->isInstanceOf("FMenu") ) + { + bool contains_menu_structure; + auto menu = static_cast(openmenu); + std::tie(contains_menu_structure, is_dialog_menu) = \ + closeOpenMenus (menu, mouse_position); + + if ( contains_menu_structure ) + return; + } + + if ( openmenu->isInstanceOf("FDropDownListBox") ) + { + auto drop_down = static_cast(openmenu); + + if ( ! closeComboBox(drop_down, mouse_position) ) + return; + } + + // No widget was been clicked and the menu is no dialog menu + if ( ! (FWidget::getClickedWidget() || is_dialog_menu) ) + FWindow::switchToPrevWindow(widget); + + if ( FWidget::getStatusBar() ) + FWidget::getStatusBar()->drawMessage(); + + widget->updateTerminal(); + FVTerm::flush(); +} + } // namespace finalcut diff --git a/src/include/final/fapplication.h b/src/include/final/fapplication.h index 780c6f6a..2be55309 100644 --- a/src/include/final/fapplication.h +++ b/src/include/final/fapplication.h @@ -163,7 +163,7 @@ class FApplication : public FWidget bool getMouseEvent(); FWidget*& determineClickedWidget(); void unsetMoveSizeMode(); - void closeOpenMenu(); + void closeDropDown(); void unselectMenubarItems(); void sendMouseEvent(); void sendMouseMoveEvent ( const FPoint& diff --git a/src/include/final/fcombobox.h b/src/include/final/fcombobox.h new file mode 100644 index 00000000..d75d44b0 --- /dev/null +++ b/src/include/final/fcombobox.h @@ -0,0 +1,342 @@ +/*********************************************************************** +* fcombobox.h - Widget FComboBox * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2019 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 * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +/* Inheritance diagram + * ═══════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▏ + * ▕ FTerm ▏ + * ▕▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏ + * ▕ FVTerm ▏ ▕ FObject ▏ + * ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏ + * ▲ ▲ + * │ │ + * └─────┬─────┘ + * │ + * ▕▔▔▔▔▔▔▔▔▔▏ + * ▕ FWidget ▏ + * ▕▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▔▔▔▔▔▏1 1▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FComboBox ▏- - - -▕ FDropDownListBox ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + */ + +#ifndef FCOMBOBOX_H +#define FCOMBOBOX_H + +#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) + #error "Only can be included directly." +#endif + +#include "final/flineedit.h" +#include "final/flistbox.h" +#include "final/fwidget.h" +#include "final/fwindow.h" + + +namespace finalcut +{ + +// class forward declaration +class FLineEdit; +class FListBox; + +//---------------------------------------------------------------------- +// class FDropDownListBox +//---------------------------------------------------------------------- + +class FDropDownListBox : public FWindow +{ + public: + // Using-declaration + using FWidget::setGeometry; + + // Constructor + explicit FDropDownListBox (FWidget* = nullptr); + + // Disable copy constructor + FDropDownListBox (const FDropDownListBox&) = delete; + + // Destructor + virtual ~FDropDownListBox (); + + // Disable assignment operator (=) + FDropDownListBox& operator = (const FDropDownListBox&) = delete; + + // Accessors + const FString getClassName() const override; + + // Mutators + void setGeometry ( const FPoint&, const FSize& + , bool = true ) override; + // Inquiries + bool isEmpty(); + + // Methods + void show() override; + void hide() override; + + // Event handlers + void onKeyPress (FKeyEvent*) override; + + private: + // Methods + void init(); + void draw() override; + void drawShadow(); + bool containsWidget (const FPoint&); + + // Data members + FListBox list{this}; + + // Friend functions + friend bool closeComboBox (FDropDownListBox*, const FPoint&); + + // Friend classes + friend class FComboBox; +}; + +// FDropDownListBox inline functions +//---------------------------------------------------------------------- +inline const FString FDropDownListBox::getClassName() const +{ return "FDropDownListBox"; } + +//---------------------------------------------------------------------- +inline bool FDropDownListBox::isEmpty() +{ return bool( list.getCount() == 0 ); } + + +//---------------------------------------------------------------------- +// class FComboBox +//---------------------------------------------------------------------- + +class FComboBox : public FWidget +{ + public: + // Using-declaration + using FWidget::setGeometry; + + // Constructors + explicit FComboBox (FWidget* = nullptr); + + // Disable copy constructor + FComboBox (const FComboBox&) = delete; + + // Destructor + ~FComboBox(); + + // Disable assignment operator (=) + FComboBox& operator = (const FComboBox&) = delete; + + // Overloaded operators + + // Accessors + const FString getClassName() const override; + std::size_t getCount() const; + FString getText() const; + FDataPtr getItemData(); + FLineEdit::label_o getLabelOrientation(); + + // Mutators + void setGeometry ( const FPoint&, const FSize& + , bool = true ) override; + bool setEnable (bool) override; + bool setEnable() override; + bool unsetEnable() override; + bool setDisable() override; + bool setFocus (bool) override; + bool setFocus() override; + bool unsetFocus() override; + bool setShadow (bool); + bool setShadow(); + bool unsetShadow(); + bool setEditable (bool); + bool setEditable(); + bool unsetEditable(); + void setMaxVisibleItems (std::size_t); + void setLabelText (const FString&); + void setLabelOrientation (const FLineEdit::label_o); + + // Inquiries + bool hasShadow(); + + // Methods + void insert (FListBoxItem); + template + void insert ( const std::initializer_list& list + , FDataPtr = nullptr ); + template + void insert (const ItemT&, FDataPtr = nullptr); + void remove (std::size_t); + void reserve (std::size_t); + void clear(); + virtual void showDropDown(); + virtual void hideDropDown(); + + // Event handlers + void onKeyPress (FKeyEvent*) override; + void onMouseDown (FMouseEvent*) override; + void onMouseUp (FMouseEvent*) override; + void onMouseMove (FMouseEvent*) override; + void onWheel (FWheelEvent*) override; + void onFocusOut (FFocusEvent*) override; + + private: + // Inquiries + bool isMouseOverListWindow (const FPoint&); + + // Methods + void init(); + void initCallbacks(); + void draw() override; + void onePosUp(); + void onePosDown(); + void passEventToListWindow (FMouseEvent*&); + void processClick(); + void processChanged(); + + // Callback methods + void cb_setInputField (FWidget*, FDataPtr); + void cb_closeComboBox (FWidget*, FDataPtr); + void cb_inputFieldSwitch (FWidget*, FDataPtr); + void cb_inputFieldHandOver (FWidget*, FDataPtr); + + // Data members + FLineEdit input_field{this}; + FDropDownListBox list_window{this}; + std::size_t max_items{8}; + int nf{0}; + bool is_editable{true}; +}; + +// non-member function forward declarations +//---------------------------------------------------------------------- +void closeOpenComboBox(); +bool closeComboBox (FDropDownListBox*, const FPoint&); + +// FComboBox inline functions +//---------------------------------------------------------------------- +inline const FString FComboBox::getClassName() const +{ return "FComboBox"; } + +//---------------------------------------------------------------------- +inline std::size_t FComboBox::getCount() const +{ return list_window.list.getCount(); } + +//---------------------------------------------------------------------- +inline FString FComboBox::getText() const +{ return input_field.getText(); } + +//---------------------------------------------------------------------- +inline FDataPtr FComboBox::getItemData() +{ + std::size_t i = list_window.list.currentItem(); + return list_window.list.getItem(i).getData(); +} + +//---------------------------------------------------------------------- +inline FLineEdit::label_o FComboBox::getLabelOrientation() +{ return input_field.getLabelOrientation(); } + +//---------------------------------------------------------------------- +inline bool FComboBox::setEnable() +{ return setEnable(true); } + +//---------------------------------------------------------------------- +inline bool FComboBox::unsetEnable() +{ return setEnable(false); } + +//---------------------------------------------------------------------- +inline bool FComboBox::setDisable() +{ return setEnable(false); } + +//---------------------------------------------------------------------- +inline bool FComboBox::setFocus() +{ return setFocus(true); } + +//---------------------------------------------------------------------- +inline bool FComboBox::unsetFocus() +{ return setFocus(false); } + +//---------------------------------------------------------------------- +inline bool FComboBox::setShadow() +{ return setShadow(true); } + +//---------------------------------------------------------------------- +inline bool FComboBox::unsetShadow() +{ return setShadow(false); } + +//---------------------------------------------------------------------- +inline bool FComboBox::setEditable() +{ return setEditable(true); } + +//---------------------------------------------------------------------- +inline bool FComboBox::unsetEditable() +{ return setEditable(false); } + +//---------------------------------------------------------------------- +inline bool FComboBox::hasShadow() +{ return getFlags().shadow; } + +//---------------------------------------------------------------------- +template +void FComboBox::insert ( const std::initializer_list& list + , FDataPtr d ) +{ + for (auto& item : list) + { + FListBoxItem listItem (FString() << item, d); + insert (listItem); + } +} + +//---------------------------------------------------------------------- +template +void FComboBox::insert ( const ItemT& item + , FDataPtr d ) +{ + FListBoxItem listItem (FString() << item, d); + insert (listItem); +} + +//---------------------------------------------------------------------- +inline void FComboBox::reserve (std::size_t new_cap) +{ list_window.list.reserve(new_cap); } + +//---------------------------------------------------------------------- +inline void FComboBox::setLabelText (const FString& s) +{ input_field.setLabelText(s); } + +//---------------------------------------------------------------------- +inline void FComboBox::setLabelOrientation (const FLineEdit::label_o o) +{ input_field.setLabelOrientation(o); } + +} // namespace finalcut + +#endif // FCOMBOBOX_H + + diff --git a/src/include/final/fconfig.h b/src/include/final/fconfig.h index 71879cdb..4f481ea5 100644 --- a/src/include/final/fconfig.h +++ b/src/include/final/fconfig.h @@ -50,9 +50,7 @@ #endif /* Define to 1 if GPM mouse is enabled */ -#ifndef F_HAVE_LIBGPM -#define F_HAVE_LIBGPM 1 -#endif +/* #undef HAVE_LIBGPM */ /* Define to 1 if you have the header file. */ #ifndef F_HAVE_LINUX_FB_H diff --git a/src/include/final/ffiledialog.h b/src/include/final/ffiledialog.h index bc7bc3c7..75d3092f 100644 --- a/src/include/final/ffiledialog.h +++ b/src/include/final/ffiledialog.h @@ -140,11 +140,6 @@ class FFileDialog : public FDialog static const FString fileSaveChooser ( FWidget* , const FString& = FString() , const FString& = FString() ); - // Friend function - friend const FString fileChooser ( FWidget* - , const FString& - , const FString& - , FFileDialog::DialogType); protected: // Method @@ -212,6 +207,10 @@ class FFileDialog : public FDialog , const FFileDialog::dir_entry& ); friend bool sortDirFirst ( const FFileDialog::dir_entry& , const FFileDialog::dir_entry& ); + friend const FString fileChooser ( FWidget* + , const FString& + , const FString& + , FFileDialog::DialogType); }; // FMessageBox inline functions diff --git a/src/include/final/final.h b/src/include/final/final.h index 9f26cf3e..06369f94 100644 --- a/src/include/final/final.h +++ b/src/include/final/final.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/src/include/final/flineedit.h b/src/include/final/flineedit.h index 6afa4427..6f57a2df 100644 --- a/src/include/final/flineedit.h +++ b/src/include/final/flineedit.h @@ -127,19 +127,23 @@ class FLineEdit : public FWidget void setLabelAssociatedWidget (FWidget*); void setGeometry ( const FPoint&, const FSize& , bool = true ) override; - bool setEnable(bool) override; + bool setEnable (bool) override; bool setEnable() override; bool unsetEnable() override; bool setDisable() override; - bool setFocus(bool) override; + bool setFocus (bool) override; bool setFocus() override; bool unsetFocus() override; - bool setShadow(bool); + bool setShadow (bool); bool setShadow(); bool unsetShadow(); + bool setReadOnly (bool); + bool setReadOnly(); + bool unsetReadOnly(); // Inquiry - bool hasShadow(); + bool hasShadow() const; + bool isReadOnly() const; // Methods void hide() override; @@ -215,14 +219,12 @@ class FLineEdit : public FWidget int scroll_repeat{100}; bool scroll_timer{false}; bool insert_mode{true}; + bool read_only{false}; std::size_t cursor_pos{NOT_SET}; std::size_t text_offset{0}; std::size_t char_width_offset{0}; std::size_t x_pos{0}; std::size_t max_length{std::numeric_limits::max()}; - - // Friend class - friend class FSpinBox; }; @@ -306,9 +308,21 @@ inline bool FLineEdit::unsetShadow() { return setShadow(false); } //---------------------------------------------------------------------- -inline bool FLineEdit::hasShadow() +inline bool FLineEdit::setReadOnly() +{ return setReadOnly(true); } + +//---------------------------------------------------------------------- +inline bool FLineEdit::unsetReadOnly() +{ return setReadOnly(true); } + +//---------------------------------------------------------------------- +inline bool FLineEdit::hasShadow() const { return getFlags().shadow; } +//---------------------------------------------------------------------- +inline bool FLineEdit::isReadOnly() const +{ return read_only; } + } // namespace finalcut #endif // FLINEEDIT_H diff --git a/src/include/final/flistbox.h b/src/include/final/flistbox.h index ec686df1..45af5f2e 100644 --- a/src/include/final/flistbox.h +++ b/src/include/final/flistbox.h @@ -159,7 +159,7 @@ class FListBox : public FWidget FListBox (const FListBox&) = delete; // Destructor - virtual ~FListBox(); + virtual ~FListBox(); // Disable assignment operator (=) FListBox& operator = (const FListBox&) = delete; @@ -167,8 +167,10 @@ class FListBox : public FWidget // Accessors const FString getClassName() const override; std::size_t getCount() const; - FListBoxItem getItem (std::size_t); - FListBoxItem getItem (listBoxItems::iterator) const; + FListBoxItem& getItem (std::size_t); + const FListBoxItem& getItem (std::size_t) const; + FListBoxItem& getItem (listBoxItems::iterator); + const FListBoxItem& getItem (listBoxItems::const_iterator) const; std::size_t currentItem() const; FString& getText(); @@ -308,7 +310,7 @@ class FListBox : public FWidget void processChanged(); void lazyConvert (listBoxItems::iterator, int); listBoxItems::iterator index2iterator (std::size_t); - + listBoxItems::const_iterator index2iterator (std::size_t index) const; // Callback methods void cb_VBarChange (FWidget*, FDataPtr); void cb_HBarChange (FWidget*, FDataPtr); @@ -340,6 +342,7 @@ class FListBox : public FWidget bool multi_select{false}; bool mouse_select{false}; bool scroll_timer{false}; + bool click_on_list{false}; }; @@ -381,14 +384,25 @@ inline std::size_t FListBox::getCount() const { return itemlist.size(); } //---------------------------------------------------------------------- -inline FListBoxItem FListBox::getItem (std::size_t index) +inline FListBoxItem& FListBox::getItem (std::size_t index) { listBoxItems::iterator iter = index2iterator(index - 1); return *iter; } //---------------------------------------------------------------------- -inline FListBoxItem FListBox::getItem (listBoxItems::iterator iter) const +inline const FListBoxItem& FListBox::getItem (std::size_t index) const +{ + listBoxItems::const_iterator iter = index2iterator(index - 1); + return *iter; +} + +//---------------------------------------------------------------------- +inline FListBoxItem& FListBox::getItem (listBoxItems::iterator iter) +{ return *iter; } + +//---------------------------------------------------------------------- +inline const FListBoxItem& FListBox::getItem (listBoxItems::const_iterator iter) const { return *iter; } //---------------------------------------------------------------------- @@ -539,6 +553,15 @@ inline FListBox::listBoxItems::iterator \ return iter; } +//---------------------------------------------------------------------- +inline FListBox::listBoxItems::const_iterator \ + FListBox::index2iterator (std::size_t index) const +{ + listBoxItems::const_iterator iter = itemlist.begin(); + std::advance (iter, index); + return iter; +} + } // namespace finalcut #endif // FLISTBOX_H diff --git a/src/include/final/fmenu.h b/src/include/final/fmenu.h index cd0c1973..10c62c8d 100644 --- a/src/include/final/fmenu.h +++ b/src/include/final/fmenu.h @@ -159,11 +159,12 @@ class FMenu : public FWindow, public FMenuList void setSuperMenu (FWidget*); // Inquiries - bool isWindowsMenu (const FWidget*) const; + bool isDialog (const FWidget*) const; bool isMenuBar (const FWidget*) const; bool isMenu (const FWidget*) const; bool isRadioMenuItem (const FWidget*) const; bool isSubMenu() const; + bool isDialogMenu() const; bool isMouseOverMenu (const FPoint&); bool isMouseOverSubMenu (const FPoint&); bool isMouseOverSuperMenu (const FPoint&); @@ -215,14 +216,6 @@ class FMenu : public FWindow, public FMenuList void closeMenu(); void processActivate(); - // Friend classes - friend class FApplication; - friend class FCheckMenuItem; - friend class FDialog; - friend class FMenuBar; - friend class FMenuItem; - friend class FRadioMenuItem; - // Data members FMenuItem menuitem{}; FWidget* super_menu{nullptr}; @@ -232,8 +225,22 @@ class FMenu : public FWindow, public FMenuList std::size_t hotkeypos{NOT_SET}; bool mouse_down{false}; bool has_checkable_items{false}; + + // Friend functions + friend std::tuple closeOpenMenus (FMenu*, const FPoint&); + + // Friend classes + friend class FCheckMenuItem; + friend class FDialog; + friend class FMenuBar; + friend class FMenuItem; + friend class FRadioMenuItem; }; +// non-member function forward declarations +//---------------------------------------------------------------------- +std::tuple closeOpenMenus (FMenu*, const FPoint&); + // FMenu inline functions //---------------------------------------------------------------------- diff --git a/src/include/final/fmenubar.h b/src/include/final/fmenubar.h index 4cdaf534..8262d41f 100644 --- a/src/include/final/fmenubar.h +++ b/src/include/final/fmenubar.h @@ -147,15 +147,15 @@ class FMenuBar : public FWindow, public FMenuList void passEventToMenu (const FMouseEvent*&); void leaveMenuBar(); - // Friend classes - friend class FMenu; - friend class FMenuItem; - // Data members std::size_t screenWidth{80}; bool mouse_down{false}; bool drop_down{false}; bool focus_changed{false}; + + // Friend classes + friend class FMenu; + friend class FMenuItem; }; diff --git a/src/include/final/fmenuitem.h b/src/include/final/fmenuitem.h index f28dc72d..b313d8c6 100644 --- a/src/include/final/fmenuitem.h +++ b/src/include/final/fmenuitem.h @@ -150,7 +150,7 @@ class FMenuItem : public FWidget void setSuperMenu (FWidget*); // Inquiries - bool isWindowsMenu (FWidget*) const; + bool isDialog (FWidget*) const; bool isMenuBar (FWidget*) const; bool isMenu (FWidget*) const; diff --git a/src/include/final/foptiattr.h b/src/include/final/foptiattr.h index bb5f1fc8..3df719c1 100644 --- a/src/include/final/foptiattr.h +++ b/src/include/final/foptiattr.h @@ -125,10 +125,6 @@ class FOptiAttr final // Disable assignment operator (=) FOptiAttr& operator = (const FOptiAttr&) = delete; - // Friend operator functions - friend bool operator == (const FChar&, const FChar&); - friend bool operator != (const FChar&, const FChar&); - // Accessors const FString getClassName() const; @@ -336,24 +332,6 @@ class FOptiAttr final // FOptiAttr inline functions -//---------------------------------------------------------------------- -inline bool operator == ( const FChar& lhs, - const FChar& rhs ) -{ - return lhs.ch == rhs.ch - && lhs.fg_color == rhs.fg_color - && lhs.bg_color == rhs.bg_color - && lhs.attr.byte[0] == rhs.attr.byte[0] - && lhs.attr.byte[1] == rhs.attr.byte[1] - && lhs.attr.bit.fullwidth_padding \ - == rhs.attr.bit.fullwidth_padding; -} - -//---------------------------------------------------------------------- -inline bool operator != ( const FChar& lhs, - const FChar& rhs ) -{ return ! ( lhs == rhs ); } - //---------------------------------------------------------------------- inline const FString FOptiAttr::getClassName() const { return "FOptiAttr"; } @@ -374,6 +352,26 @@ inline void FOptiAttr::setDefaultColorSupport() inline void FOptiAttr::unsetDefaultColorSupport() { ansi_default_color = false; } + +// FChar operator functions +//---------------------------------------------------------------------- +inline bool operator == ( const FChar& lhs, + const FChar& rhs ) +{ + return lhs.ch == rhs.ch + && lhs.fg_color == rhs.fg_color + && lhs.bg_color == rhs.bg_color + && lhs.attr.byte[0] == rhs.attr.byte[0] + && lhs.attr.byte[1] == rhs.attr.byte[1] + && lhs.attr.bit.fullwidth_padding \ + == rhs.attr.bit.fullwidth_padding; +} + +//---------------------------------------------------------------------- +inline bool operator != ( const FChar& lhs, + const FChar& rhs ) +{ return ! ( lhs == rhs ); } + } // namespace finalcut #endif // FOPTIATTR_H diff --git a/src/include/final/foptimove.h b/src/include/final/foptimove.h index 62941e1c..7cd63c1f 100644 --- a/src/include/final/foptimove.h +++ b/src/include/final/foptimove.h @@ -203,9 +203,6 @@ class FOptiMove final bool isMethod5Faster (int&, int, int, int); void moveByMethod (int, int, int, int, int); - // Friend function - friend void printDurations (const FOptiMove&); - // Data members capability F_cursor_home{}; capability F_carriage_return{}; @@ -236,6 +233,9 @@ class FOptiMove final char move_buf[BUF_SIZE]{'\0'}; bool automatic_left_margin{false}; bool eat_nl_glitch{false}; + + // Friend function + friend void printDurations (const FOptiMove&); }; diff --git a/src/include/final/fpoint.h b/src/include/final/fpoint.h index 93f105b2..3b570875 100644 --- a/src/include/final/fpoint.h +++ b/src/include/final/fpoint.h @@ -64,14 +64,6 @@ class FPoint FPoint& operator += (const FPoint&); FPoint& operator -= (const FPoint&); - friend bool operator == (const FPoint&, const FPoint&); - friend bool operator != (const FPoint&, const FPoint&); - friend FPoint operator + (const FPoint&, const FPoint&); - friend FPoint operator - (const FPoint&, const FPoint&); - friend FPoint operator - (const FPoint&); - friend std::ostream& operator << (std::ostream&, const FPoint&); - friend std::istream& operator >> (std::istream&, FPoint&); - // Accessors virtual const FString getClassName(); int getX() const; @@ -88,10 +80,23 @@ class FPoint int& x_ref(); int& y_ref(); + // Methods + void move (int, int); + void move (const FPoint&); + private: // Data members int xpos{0}; int ypos{0}; + + // Friend operator functions + friend bool operator == (const FPoint&, const FPoint&); + friend bool operator != (const FPoint&, const FPoint&); + friend FPoint operator + (const FPoint&, const FPoint&); + friend FPoint operator - (const FPoint&, const FPoint&); + friend FPoint operator - (const FPoint&); + friend std::ostream& operator << (std::ostream&, const FPoint&); + friend std::istream& operator >> (std::istream&, FPoint&); }; @@ -114,26 +119,6 @@ inline FPoint::FPoint (int x, int y) , ypos(y) { } -//---------------------------------------------------------------------- -inline bool operator == (const FPoint& p1, const FPoint& p2) -{ return p1.xpos == p2.xpos && p1.ypos == p2.ypos; } - -//---------------------------------------------------------------------- -inline bool operator != (const FPoint& p1, const FPoint& p2) -{ return p1.xpos != p2.xpos || p1.ypos != p2.ypos; } - -//---------------------------------------------------------------------- -inline FPoint operator + (const FPoint& p1, const FPoint& p2) -{ return FPoint(p1.xpos + p2.xpos, p1.ypos + p2.ypos); } - -//---------------------------------------------------------------------- -inline FPoint operator - (const FPoint& p1, const FPoint& p2) -{ return FPoint(p1.xpos - p2.xpos, p1.ypos - p2.ypos); } - -//---------------------------------------------------------------------- -inline FPoint operator - (const FPoint& p) -{ return FPoint(-p.xpos, -p.ypos); } - //---------------------------------------------------------------------- inline const FString FPoint::getClassName() { return "FPoint"; } @@ -158,6 +143,28 @@ inline int& FPoint::x_ref() inline int& FPoint::y_ref() { return ypos; } + +// FPoint non-member operators +//---------------------------------------------------------------------- +inline bool operator == (const FPoint& p1, const FPoint& p2) +{ return p1.xpos == p2.xpos && p1.ypos == p2.ypos; } + +//---------------------------------------------------------------------- +inline bool operator != (const FPoint& p1, const FPoint& p2) +{ return p1.xpos != p2.xpos || p1.ypos != p2.ypos; } + +//---------------------------------------------------------------------- +inline FPoint operator + (const FPoint& p1, const FPoint& p2) +{ return FPoint(p1.xpos + p2.xpos, p1.ypos + p2.ypos); } + +//---------------------------------------------------------------------- +inline FPoint operator - (const FPoint& p1, const FPoint& p2) +{ return FPoint(p1.xpos - p2.xpos, p1.ypos - p2.ypos); } + +//---------------------------------------------------------------------- +inline FPoint operator - (const FPoint& p) +{ return FPoint(-p.xpos, -p.ypos); } + } // namespace finalcut #endif // FPOINT_H diff --git a/src/include/final/frect.h b/src/include/final/frect.h index 93e63b06..a3bd352f 100644 --- a/src/include/final/frect.h +++ b/src/include/final/frect.h @@ -72,13 +72,6 @@ class FRect FRect& operator = (const FRect&); FRect& operator = (FRect&&); - friend FRect operator + (const FRect&, const FSize&); - friend FRect operator - (const FRect&, const FSize&); - friend bool operator == (const FRect&, const FRect&); - friend bool operator != (const FRect&, const FRect&); - friend std::ostream& operator << (std::ostream&, const FRect&); - friend std::istream& operator >> (std::istream&, FRect&); - // Accessors virtual const FString getClassName(); int getX1() const; @@ -142,6 +135,14 @@ class FRect int Y1{0}; int X2{-1}; int Y2{-1}; + + // Friend operator functions + friend FRect operator + (const FRect&, const FSize&); + friend FRect operator - (const FRect&, const FSize&); + friend bool operator == (const FRect&, const FRect&); + friend bool operator != (const FRect&, const FRect&); + friend std::ostream& operator << (std::ostream&, const FRect&); + friend std::istream& operator >> (std::istream&, FRect&); }; // FRect inline functions diff --git a/src/include/final/fsize.h b/src/include/final/fsize.h index 0870421c..e6fb40dc 100644 --- a/src/include/final/fsize.h +++ b/src/include/final/fsize.h @@ -69,18 +69,6 @@ class FSize FSize& operator += (const FSize&); FSize& operator -= (const FSize&); - friend bool operator < (const FSize&, const FSize&); - friend bool operator <= (const FSize&, const FSize&); - friend bool operator == (const FSize&, const FSize&); - friend bool operator != (const FSize&, const FSize&); - friend bool operator >= (const FSize&, const FSize&); - friend bool operator > (const FSize&, const FSize&); - friend FSize operator + (const FSize&, const FSize&); - friend FSize operator - (const FSize&, const FSize&); - - friend std::ostream& operator << (std::ostream&, const FSize&); - friend std::istream& operator >> (std::istream&, FSize&); - // Accessors virtual const FString getClassName(); std::size_t getWidth() const; @@ -106,6 +94,19 @@ class FSize // Data members std::size_t width{0}; std::size_t height{0}; + + // Friend operator functions + friend bool operator < (const FSize&, const FSize&); + friend bool operator <= (const FSize&, const FSize&); + friend bool operator == (const FSize&, const FSize&); + friend bool operator != (const FSize&, const FSize&); + friend bool operator >= (const FSize&, const FSize&); + friend bool operator > (const FSize&, const FSize&); + friend FSize operator + (const FSize&, const FSize&); + friend FSize operator - (const FSize&, const FSize&); + + friend std::ostream& operator << (std::ostream&, const FSize&); + friend std::istream& operator >> (std::istream&, FSize&); }; // FSize inline functions @@ -127,6 +128,32 @@ inline FSize::FSize (std::size_t w, std::size_t h) , height(h) { } +//---------------------------------------------------------------------- +inline const FString FSize::getClassName() +{ return "FSize"; } + +//---------------------------------------------------------------------- +inline std::size_t FSize::getWidth() const +{ return width; } + +//---------------------------------------------------------------------- +inline std::size_t FSize::getHeight() const +{ return height; } + +//---------------------------------------------------------------------- +inline std::size_t FSize::getArea() const +{ return width * height; } + +//---------------------------------------------------------------------- +inline std::size_t& FSize::width_ref() +{ return width; } + +//---------------------------------------------------------------------- +inline std::size_t& FSize::height_ref() +{ return height; } + + +// FSize non-member operators //---------------------------------------------------------------------- inline bool operator < (const FSize& s1, const FSize& s2) { return s1.width < s2.width && s1.height < s2.height; } @@ -168,30 +195,6 @@ inline FSize operator - (const FSize& s1, const FSize& s2) return FSize(w, h); } -//---------------------------------------------------------------------- -inline const FString FSize::getClassName() -{ return "FSize"; } - -//---------------------------------------------------------------------- -inline std::size_t FSize::getWidth() const -{ return width; } - -//---------------------------------------------------------------------- -inline std::size_t FSize::getHeight() const -{ return height; } - -//---------------------------------------------------------------------- -inline std::size_t FSize::getArea() const -{ return width * height; } - -//---------------------------------------------------------------------- -inline std::size_t& FSize::width_ref() -{ return width; } - -//---------------------------------------------------------------------- -inline std::size_t& FSize::height_ref() -{ return height; } - } // namespace finalcut #endif // FSIZE_H diff --git a/src/include/final/fspinbox.h b/src/include/final/fspinbox.h index 694b7fdf..3371f07d 100644 --- a/src/include/final/fspinbox.h +++ b/src/include/final/fspinbox.h @@ -83,6 +83,7 @@ class FSpinBox : public FWidget FSpinBox& operator = (const FSpinBox&) = delete; // Accessors + const FString getClassName() const override; sInt64 getValue(); FString getPrefix() const; FString getSuffix() const; @@ -159,6 +160,10 @@ class FSpinBox : public FWidget // FSpinBox inline functions +//---------------------------------------------------------------------- +inline const FString FSpinBox::getClassName() const +{ return "FSpinBox"; } + //---------------------------------------------------------------------- inline sInt64 FSpinBox::getValue() { return value; } diff --git a/src/include/final/fstatusbar.h b/src/include/final/fstatusbar.h index a55150dd..3331d30d 100644 --- a/src/include/final/fstatusbar.h +++ b/src/include/final/fstatusbar.h @@ -119,15 +119,15 @@ class FStatusKey : public FWidget FStatusBar* getConnectedStatusbar() const; void setConnectedStatusbar (FStatusBar*); - // Friend class - friend class FStatusBar; - // Data members FString text{}; FStatusBar* bar{nullptr}; FKey key{0}; bool active{false}; bool mouse_focus{false}; + + // Friend class + friend class FStatusBar; }; diff --git a/src/include/final/fstring.h b/src/include/final/fstring.h index d3ecae45..0f86595e 100644 --- a/src/include/final/fstring.h +++ b/src/include/final/fstring.h @@ -161,22 +161,6 @@ class FString operator const char* () const { return c_str(); } - // Non-member operators - friend const FString operator + (const FString&, const FString&); - friend const FString operator + (const FString&, const wchar_t); - friend const FString operator + (const std::wstring&, const FString&); - friend const FString operator + (const wchar_t[], const FString&); - friend const FString operator + (const std::string&, const FString&); - friend const FString operator + (const char[], const FString&); - friend const FString operator + (const wchar_t, const FString&); - friend const FString operator + (const char, const FString&); - friend const FString operator + (const FString&, const char); - - friend std::ostream& operator << (std::ostream&, const FString&); - friend std::istream& operator >> (std::istream&, FString& s); - friend std::wostream& operator << (std::wostream&, const FString&); - friend std::wistream& operator >> (std::wistream&, FString&); - // Accessor virtual const FString getClassName(); @@ -279,6 +263,22 @@ class FString mutable char* c_string{nullptr}; static wchar_t null_char; static const wchar_t const_null_char; + + // Friend Non-member operator functions + friend const FString operator + (const FString&, const FString&); + friend const FString operator + (const FString&, const wchar_t); + friend const FString operator + (const std::wstring&, const FString&); + friend const FString operator + (const wchar_t[], const FString&); + friend const FString operator + (const std::string&, const FString&); + friend const FString operator + (const char[], const FString&); + friend const FString operator + (const wchar_t, const FString&); + friend const FString operator + (const char, const FString&); + friend const FString operator + (const FString&, const char); + + friend std::ostream& operator << (std::ostream&, const FString&); + friend std::istream& operator >> (std::istream&, FString& s); + friend std::wostream& operator << (std::wostream&, const FString&); + friend std::wistream& operator >> (std::wistream&, FString&); }; diff --git a/src/include/final/ftermbuffer.h b/src/include/final/ftermbuffer.h index ab9980d3..139e5d02 100644 --- a/src/include/final/ftermbuffer.h +++ b/src/include/final/ftermbuffer.h @@ -74,10 +74,6 @@ class FTermBuffer FTermBuffer& operator << (const std::wstring&); FTermBuffer& operator << (const FColorPair&); - // Non-member operators - friend FCharVector& operator << ( FCharVector& - , const FTermBuffer& ); - // Accessors virtual const FString getClassName() const; std::size_t getLength() const; @@ -104,6 +100,10 @@ class FTermBuffer private: FCharVector data{}; + + // Non-member operators + friend FCharVector& operator << ( FCharVector& + , const FTermBuffer& ); }; diff --git a/src/include/final/ftogglebutton.h b/src/include/final/ftogglebutton.h index 90c02348..0787bfa0 100644 --- a/src/include/final/ftogglebutton.h +++ b/src/include/final/ftogglebutton.h @@ -153,9 +153,6 @@ class FToggleButton : public FWidget void init(); void drawText (FString&&, std::size_t); - // Friend classes - friend class FButtonGroup; - // Data members FButtonGroup* button_group{nullptr}; FString text{}; @@ -163,6 +160,9 @@ class FToggleButton : public FWidget std::size_t button_width{0}; // plus margin spaces bool focus_inside_group{true}; bool checked{false}; + + // Friend classes + friend class FButtonGroup; }; // FRadioButton inline functions diff --git a/src/include/final/ftooltip.h b/src/include/final/ftooltip.h index 7c664009..4496b76e 100644 --- a/src/include/final/ftooltip.h +++ b/src/include/final/ftooltip.h @@ -92,7 +92,6 @@ class FToolTip : public FWindow void setText (const FString&); // Methods - void draw() override; void show() override; void hide() override; @@ -102,6 +101,7 @@ class FToolTip : public FWindow private: // Methods void init(); + void draw() override; void calculateDimensions(); void adjustSize() override; diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index 96ac1936..487f2ea9 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -307,6 +307,7 @@ class FVTerm virtual void print (const FPoint&); virtual void print (const FColorPair&); virtual FVTerm& print(); + static void flush(); static void beep(); static void redefineDefaultColors (bool); @@ -361,7 +362,6 @@ class FVTerm void processTerminalUpdate(); static void startTerminalUpdate(); static void finishTerminalUpdate(); - static void flushOutputBuffer(); static void initScreenSettings(); static void changeTermSizeFinished(); static void exitWithMessage (const FString&) diff --git a/src/include/final/fwidget.h b/src/include/final/fwidget.h index b657c088..18795098 100644 --- a/src/include/final/fwidget.h +++ b/src/include/final/fwidget.h @@ -307,6 +307,7 @@ class FWidget : public FVTerm, public FObject bool isMenuWidget() const; bool isVisible() const; bool isShown() const; + bool isHidden() const; bool isEnabled() const; bool hasVisibleCursor() const; bool hasFocus() const; @@ -410,6 +411,7 @@ class FWidget : public FVTerm, public FObject void insufficientSpaceAdjust(); void KeyPressEvent (FKeyEvent*); void KeyDownEvent (FKeyEvent*); + void emitWheelCallback (FWheelEvent*); void setWindowFocus (bool); FCallbackPtr getCallbackPtr (FCallback); bool changeFocus (FWidget*, FWidget*, fc::FocusTypes); @@ -919,6 +921,10 @@ inline bool FWidget::isVisible() const inline bool FWidget::isShown() const { return flags.shown; } +//---------------------------------------------------------------------- +inline bool FWidget::isHidden() const +{ return flags.hidden; } + //---------------------------------------------------------------------- inline bool FWidget::isWindowWidget() const { return flags.window_widget; } diff --git a/src/include/final/fwindow.h b/src/include/final/fwindow.h index 62993f41..868afd04 100644 --- a/src/include/final/fwindow.h +++ b/src/include/final/fwindow.h @@ -179,6 +179,10 @@ class FWindow : public FWidget bool zoomed{false}; }; +// non-member function forward declarations +//---------------------------------------------------------------------- +void closeDropDown (FWidget*, const FPoint&); + // FWindow inline functions //---------------------------------------------------------------------- diff --git a/test/fpoint-test.cpp b/test/fpoint-test.cpp index 2939d85c..d0cfe1fc 100644 --- a/test/fpoint-test.cpp +++ b/test/fpoint-test.cpp @@ -56,6 +56,7 @@ class FPointTest : public CPPUNIT_NS::TestFixture void additionTest(); void subtractionTest(); void referenceTest(); + void moveTest(); void streamInsertionTest(); void streamExtractionTest(); @@ -76,6 +77,7 @@ class FPointTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST (additionTest); CPPUNIT_TEST (subtractionTest); CPPUNIT_TEST (referenceTest); + CPPUNIT_TEST (moveTest); CPPUNIT_TEST (streamInsertionTest); CPPUNIT_TEST (streamExtractionTest); @@ -311,6 +313,24 @@ void FPointTest::referenceTest() CPPUNIT_ASSERT ( p1.getY() == 4 ); } +//---------------------------------------------------------------------- +void FPointTest::moveTest() +{ + finalcut::FPoint p1 (4, 3); + CPPUNIT_ASSERT ( p1.getX() == 4 ); + CPPUNIT_ASSERT ( p1.getY() == 3 ); + + const finalcut::FPoint p2 (2, 3); + p1.move(p2); + CPPUNIT_ASSERT ( p1.getX() == 6 ); + CPPUNIT_ASSERT ( p1.getY() == 6 ); + + p1.move (-2, -7); + CPPUNIT_ASSERT ( p1.getX() == 4 ); + CPPUNIT_ASSERT ( p1.getY() == -1 ); + +} + //---------------------------------------------------------------------- void FPointTest::streamInsertionTest() {