New widget class FComboBox to provide a dropdown list with an input field

This commit is contained in:
Markus Gans 2019-12-16 11:14:24 +01:00
parent aacf27ff74
commit 74d8585561
62 changed files with 1741 additions and 373 deletions

View File

@ -50,7 +50,11 @@ matrix:
- TEST="Coverity Scan" - TEST="Coverity Scan"
addons: addons:
apt: apt:
sources:
- ubuntu-toolchain-r-test
packages: packages:
- ca-certificates
- gcc
- g++ - g++
- gpm - gpm
- libgpm-dev - libgpm-dev

View File

@ -1,3 +1,7 @@
2019-12-16 Markus Gans <guru.mail@muenster.de>
* New widget class FComboBox to provide a dropdown list
with an input field
2019-11-17 Markus Gans <guru.mail@muenster.de> 2019-11-17 Markus Gans <guru.mail@muenster.de>
* Revision of FString number input stream * Revision of FString number input stream

View File

@ -205,6 +205,9 @@ Class digramm
│ ┌───────────┐ │ ┌───────────┐
├────┤ FTextView │ ├────┤ FTextView │
│ └───────────┘ │ └───────────┘
│ ┌───────────┐1 1┌──────────────────┐
├────┤ FComboBox ├------┤ FDropDownListBox │
│ └───────────┘ └──────────────────┘
┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐ ┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐
│ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │ │ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │
└─────────────┘ │ └──────────┘ └──────────────┘ └─────────────┘ │ └──────────┘ └──────────────┘

View File

@ -71,6 +71,9 @@
│ ┌───────────┐ │ ┌───────────┐
├────┤ FTextView │ ├────┤ FTextView │
│ └───────────┘ │ └───────────┘
│ ┌───────────┐1 1┌──────────────────┐
├────┤ FComboBox ├------┤ FDropDownListBox │
│ └───────────┘ └──────────────────┘
┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐ ┌─────────────┐1 │ ┌──────────┐1 *┌──────────────┐
│ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │ │ FTermBuffer ├----------------------├────┤ FListBox ├-------┤ FListBoxItem │
└─────────────┘ │ └──────────┘ └──────────────┘ └─────────────┘ │ └──────────┘ └──────────────┘

View File

@ -410,6 +410,9 @@ use `delCallbacks()` to remove all existing callbacks from an object.
<dt>FScrollbar</dt> <dt>FScrollbar</dt>
<dd>"change-value"</dd> <dd>"change-value"</dd>
<dt>FSpinBox</dt>
<dd>"changed"</dd>
<dt>FStatusBar</dt> <dt>FStatusBar</dt>
<dd>"activate"</dd> <dd>"activate"</dd>
@ -420,7 +423,7 @@ use `delCallbacks()` to remove all existing callbacks from an object.
<dd>"clicked"<br />"toggled"</dd> <dd>"clicked"<br />"toggled"</dd>
<dt>FWidget</dt> <dt>FWidget</dt>
<dd>"destroy"</dd> <dd>"destroy"<br />"focus-in"<br />"focus-out"<br />"mouse-press"<br />"mouse-release"<br />"mouse-move"<br />"mouse-wheel-down"<br />"mouse-wheel-up"</dd>
</dl> </dl>
&nbsp; &nbsp;

View File

@ -20,7 +20,8 @@
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***********************************************************************/ ***********************************************************************/
#include <map> #include <tuple>
#include <utility>
#include <vector> #include <vector>
#include <final/final.h> #include <final/final.h>
@ -36,6 +37,10 @@ using finalcut::FSize;
class Background : public finalcut::FDialog class Background : public finalcut::FDialog
{ {
public: public:
// Typedef
typedef std::tuple<uChar,uChar,uChar> RGB;
// Constructors
explicit Background (finalcut::FWidget* = nullptr); explicit Background (finalcut::FWidget* = nullptr);
// Disable copy constructor // Disable copy constructor
@ -50,12 +55,35 @@ class Background : public finalcut::FDialog
private: private:
// Callback method // Callback method
void cb_changed (finalcut::FWidget*, FDataPtr); void cb_changed (finalcut::FWidget*, FDataPtr);
void cb_choice (finalcut::FWidget*, FDataPtr);
// Data members // Data members
finalcut::FComboBox color_choice{this};
finalcut::FSpinBox red{this}; finalcut::FSpinBox red{this};
finalcut::FSpinBox green{this}; finalcut::FSpinBox green{this};
finalcut::FSpinBox blue{this}; finalcut::FSpinBox blue{this};
finalcut::FButton quit{"&Quit", this}; finalcut::FButton quit{"&Quit", this};
std::vector<std::pair<finalcut::FString, RGB>> 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 // Dialog settings
setText ("Background color palette"); 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<FDataPtr>(&c.second);
finalcut::FListBoxItem item (c.first, data_ptr);
color_choice.insert(item);
}
// Spin boxes // 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.setLabelOrientation (finalcut::FLineEdit::label_above);
red.setLabelText ("Red"); red.setLabelText ("Red");
red.setRange (0, 255); red.setRange (0, 255);
red.setValue (0x80); 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.setLabelOrientation (finalcut::FLineEdit::label_above);
green.setLabelText ("Green"); green.setLabelText ("Green");
green.setRange (0, 255); green.setRange (0, 255);
green.setValue (0xa4); 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.setLabelOrientation (finalcut::FLineEdit::label_above);
blue.setLabelText ("Blue"); blue.setLabelText ("Blue");
blue.setRange (0, 255); blue.setRange (0, 255);
blue.setValue (0xec); blue.setValue (0xec);
// Set the initial palette values // Set the initial palette values
const auto& wc = getFWidgetColors(); finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
finalcut::FTerm::setPalette ( wc.term_bg
, int(red.getValue()) , int(red.getValue())
, int(green.getValue()) , int(green.getValue())
, int(blue.getValue()) ); , int(blue.getValue()) );
// Quit button // Quit button
quit.setGeometry(FPoint(19, 5), FSize(10, 1)); quit.setGeometry(FPoint(19, 8), FSize(10, 1));
// Add some function callbacks // Add some function callbacks
quit.addCallback quit.addCallback
@ -119,6 +159,18 @@ Background::Background (finalcut::FWidget* parent)
"changed", "changed",
F_METHOD_CALLBACK (this, &Background::cb_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) void Background::cb_changed (finalcut::FWidget*, FDataPtr)
{ {
const auto& wc = getFWidgetColors(); finalcut::FTerm::setPalette ( finalcut::fc::LightMagenta
finalcut::FTerm::setPalette ( wc.term_bg , 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<RGB*>(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(red.getValue())
, int(green.getValue()) , int(green.getValue())
, int(blue.getValue()) ); , int(blue.getValue()) );
@ -145,6 +214,7 @@ void Background::cb_changed (finalcut::FWidget*, FDataPtr)
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
finalcut::FApplication app(argc, argv); finalcut::FApplication app(argc, argv);
app.setBackgroundColor(finalcut::fc::LightMagenta);
Background dialog(&app); Background dialog(&app);
app.setMainWidget(&dialog); app.setMainWidget(&dialog);
dialog.show(); dialog.show();

View File

@ -65,7 +65,7 @@ FString& doubleToString (std::list<double>::const_iterator iter)
} }
FString& mapToString ( std::map<FString FString& mapToString ( std::map<FString
, FString>::const_iterator iter ) , FString>::const_iterator iter )
{ {
auto temp = temp_str.lock(); auto temp = temp_str.lock();
return *temp = iter->first + ": " + iter->second; return *temp = iter->first + ": " + iter->second;

View File

@ -86,7 +86,7 @@ void term_boundaries (int& x, int& y)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void move (int xold, int yold, int xnew, int ynew) 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{}; finalcut::FString buffer{}, sequence{}, from{}, to{}, byte{};
const std::string ctrl_character[] = 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(xold, yold);
term_boundaries(xnew, ynew); term_boundaries(xnew, ynew);
// get the move string // Get the move string
buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew); buffer = finalcut::FTerm::moveCursorString (xold, yold, xnew, ynew);
for (auto&& ch : buffer) for (auto&& ch : buffer)

View File

@ -267,7 +267,7 @@ void MainWindow::onTimer (finalcut::FTimerEvent*)
line1 = line1.right(length - 1) + first_Char[0]; line1 = line1.right(length - 1) + first_Char[0];
line2 = line2.right(length - 1) + first_Char[1]; line2 = line2.right(length - 1) + first_Char[1];
redraw(); redraw();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -136,7 +136,7 @@ void ProgressDialog::onTimer (finalcut::FTimerEvent*)
{ {
auto p = progressBar.getPercentage(); auto p = progressBar.getPercentage();
progressBar.setPercentage(++p); progressBar.setPercentage(++p);
flushOutputBuffer(); flush();
if ( p != 100 ) if ( p != 100 )
return; return;
@ -154,7 +154,7 @@ void ProgressDialog::onTimer (finalcut::FTimerEvent*)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -45,6 +45,7 @@ libfinal_la_SOURCES = \
fkey_map.cpp \ fkey_map.cpp \
fcharmap.cpp \ fcharmap.cpp \
fspinbox.cpp \ fspinbox.cpp \
fcombobox.cpp \
fstartoptions.cpp \ fstartoptions.cpp \
fstatusbar.cpp \ fstatusbar.cpp \
ftermcap.cpp \ ftermcap.cpp \
@ -119,6 +120,7 @@ finalcutinclude_HEADERS = \
include/final/fscrollbar.h \ include/final/fscrollbar.h \
include/final/fscrollview.h \ include/final/fscrollview.h \
include/final/fspinbox.h \ include/final/fspinbox.h \
include/final/fcombobox.h \
include/final/fstartoptions.h \ include/final/fstartoptions.h \
include/final/fstatusbar.h \ include/final/fstatusbar.h \
include/final/fstring.h \ include/final/fstring.h \

View File

@ -44,6 +44,7 @@ INCLUDE_HEADERS = \
fscrollbar.h \ fscrollbar.h \
fscrollview.h \ fscrollview.h \
fspinbox.h \ fspinbox.h \
fcombobox.h \
fstatusbar.h \ fstatusbar.h \
fstring.h \ fstring.h \
fmouse.h \ fmouse.h \
@ -106,6 +107,7 @@ OBJS = \
fwindow.o \ fwindow.o \
fscrollview.o \ fscrollview.o \
fspinbox.o \ fspinbox.o \
fcombobox.o \
fmessagebox.o \ fmessagebox.o \
ftooltip.o \ ftooltip.o \
ffiledialog.o \ ffiledialog.o \

View File

@ -44,6 +44,7 @@ INCLUDE_HEADERS = \
fscrollbar.h \ fscrollbar.h \
fscrollview.h \ fscrollview.h \
fspinbox.h \ fspinbox.h \
fcombobox.h \
fstatusbar.h \ fstatusbar.h \
fstring.h \ fstring.h \
fmouse.h \ fmouse.h \
@ -106,6 +107,7 @@ OBJS = \
fwindow.o \ fwindow.o \
fscrollview.o \ fscrollview.o \
fspinbox.o \ fspinbox.o \
fcombobox.o \
fmessagebox.o \ fmessagebox.o \
ftooltip.o \ ftooltip.o \
ffiledialog.o \ ffiledialog.o \

View File

@ -669,7 +669,7 @@ void FApplication::processKeyboardEvent()
return; return;
findKeyboardWidget(); findKeyboardWidget();
flushOutputBuffer(); flush();
keyboard->clearKeyBufferOnTimeout(); keyboard->clearKeyBufferOnTimeout();
if ( isKeyPressed() ) if ( isKeyPressed() )
@ -815,46 +815,15 @@ void FApplication::unsetMoveSizeMode()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FApplication::closeOpenMenu() void FApplication::closeDropDown()
{ {
// Close the open menu // Close the open menu
auto openmenu = FWidget::getOpenMenu(); if ( mouse && mouse->isMoved() )
auto menu = static_cast<FMenu*>(openmenu);
if ( ! openmenu || ( mouse && mouse->isMoved()) )
return; return;
if ( mouse ) const auto& mouse_position = mouse->getPos();
{ finalcut::closeDropDown (this, mouse_position);
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();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -889,7 +858,7 @@ void FApplication::unselectMenubarItems()
FWidget::getStatusBar()->drawMessage(); FWidget::getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -1124,7 +1093,7 @@ void FApplication::processMouseEvent()
determineClickedWidget(); determineClickedWidget();
unsetMoveSizeMode(); unsetMoveSizeMode();
closeOpenMenu(); closeDropDown();
unselectMenubarItems(); unselectMenubarItems();
sendMouseEvent(); sendMouseEvent();
@ -1135,14 +1104,14 @@ void FApplication::processMouseEvent()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FApplication::processResizeEvent() void FApplication::processResizeEvent()
{ {
if ( hasChangedTermSize() ) if ( ! hasChangedTermSize() )
{ return;
FResizeEvent r_ev(fc::Resize_Event);
sendEvent(app_object, &r_ev);
if ( r_ev.isAccepted() ) FResizeEvent r_ev(fc::Resize_Event);
changeTermSizeFinished(); sendEvent(app_object, &r_ev);
}
if ( r_ev.isAccepted() )
changeTermSizeFinished();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -364,7 +364,7 @@ void FButtonGroup::onFocusIn (FFocusEvent* in_ev)
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -539,7 +539,7 @@ void FButtonGroup::directFocus()
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }

733
src/fcombobox.cpp Normal file
View File

@ -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 *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#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<FComboBox*>(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<FMouseEvent>(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<FMouseEvent>(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<FDropDownListBox*>(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

View File

@ -23,6 +23,7 @@
#include <memory> #include <memory>
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fcombobox.h"
#include "final/fdialog.h" #include "final/fdialog.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/fmenuitem.h" #include "final/fmenuitem.h"
@ -1176,7 +1177,7 @@ void FDialog::leaveMenu()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1193,6 +1194,7 @@ void FDialog::openMenu()
} }
else else
{ {
finalcut::closeOpenComboBox();
setOpenMenu(dialog_menu); setOpenMenu(dialog_menu);
FPoint pos(getPos()); FPoint pos(getPos());
pos.y_ref()++; pos.y_ref()++;
@ -1221,7 +1223,7 @@ void FDialog::selectFirstMenuItem()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -198,7 +198,7 @@ void FLabel::onMouseDown (FMouseEvent* ev)
{ {
accel_widget->getStatusBar()->drawMessage(); accel_widget->getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
} }
@ -225,7 +225,7 @@ void FLabel::onAccel (FAccelEvent* ev)
{ {
accel_widget->getStatusBar()->drawMessage(); accel_widget->getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
} }

View File

@ -166,6 +166,17 @@ bool FLineEdit::setShadow (bool enable)
return getFlags().shadow; return getFlags().shadow;
} }
//----------------------------------------------------------------------
bool FLineEdit::setReadOnly (bool enable)
{
if ( enable )
unsetVisibleCursor();
else
setVisibleCursor();
return (read_only = enable);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::setText (const FString& txt) void FLineEdit::setText (const FString& txt)
{ {
@ -183,7 +194,9 @@ void FLineEdit::setText (const FString& txt)
if ( isShown() ) if ( isShown() )
{ {
cursorEnd(); if ( ! isReadOnly() )
cursorEnd();
adjustTextOffset(); adjustTextOffset();
} }
} }
@ -201,7 +214,9 @@ void FLineEdit::setMaxLength (std::size_t max)
if ( isShown() ) if ( isShown() )
{ {
cursorEnd(); if ( ! isReadOnly() )
cursorEnd();
adjustTextOffset(); adjustTextOffset();
} }
} }
@ -209,6 +224,9 @@ void FLineEdit::setMaxLength (std::size_t max)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::setCursorPosition (std::size_t pos) void FLineEdit::setCursorPosition (std::size_t pos)
{ {
if ( isReadOnly() )
return;
if ( pos == 0 ) if ( pos == 0 )
cursor_pos = 1; cursor_pos = 1;
else else
@ -260,7 +278,9 @@ void FLineEdit::hide()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::clear() void FLineEdit::clear()
{ {
cursor_pos = 0; if ( ! isReadOnly() )
cursor_pos = 0;
text_offset = 0; text_offset = 0;
char_width_offset = 0; char_width_offset = 0;
text.clear(); text.clear();
@ -270,6 +290,9 @@ void FLineEdit::clear()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onKeyPress (FKeyEvent* ev) void FLineEdit::onKeyPress (FKeyEvent* ev)
{ {
if ( isReadOnly() )
return;
FKey key = ev->key(); FKey key = ev->key();
switch ( key ) switch ( key )
@ -338,7 +361,7 @@ void FLineEdit::onKeyPress (FKeyEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onMouseDown (FMouseEvent* ev) void FLineEdit::onMouseDown (FMouseEvent* ev)
{ {
if ( ev->getButton() != fc::LeftButton ) if ( ev->getButton() != fc::LeftButton || isReadOnly() )
return; return;
if ( ! hasFocus() ) if ( ! hasFocus() )
@ -389,7 +412,7 @@ void FLineEdit::onMouseUp (FMouseEvent*)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onMouseMove (FMouseEvent* ev) void FLineEdit::onMouseMove (FMouseEvent* ev)
{ {
if ( ev->getButton() != fc::LeftButton ) if ( ev->getButton() != fc::LeftButton || isReadOnly() )
return; return;
std::size_t len = print_text.getLength(); std::size_t len = print_text.getLength();
@ -531,7 +554,7 @@ void FLineEdit::onAccel (FAccelEvent* ev)
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
} }
@ -542,23 +565,26 @@ void FLineEdit::onAccel (FAccelEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onHide (FHideEvent*) void FLineEdit::onHide (FHideEvent*)
{ {
if ( ! insert_mode ) if ( ! insert_mode && ! isReadOnly() )
setInsertCursor(); setInsertCursor();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::onFocusIn (FFocusEvent*) void FLineEdit::onFocusIn (FFocusEvent*)
{ {
if ( insert_mode ) if ( ! isReadOnly() )
setInsertCursor(); {
else if ( insert_mode )
unsetInsertCursor(); setInsertCursor();
else
unsetInsertCursor();
}
if ( getStatusBar() ) if ( getStatusBar() )
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -571,7 +597,7 @@ void FLineEdit::onFocusOut (FFocusEvent*)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
} }
if ( ! insert_mode ) if ( ! insert_mode && ! isReadOnly() )
setInsertCursor(); setInsertCursor();
} }
@ -623,7 +649,12 @@ void FLineEdit::init()
{ {
const auto& wc = getFWidgetColors(); const auto& wc = getFWidgetColors();
label->setAccelWidget(this); label->setAccelWidget(this);
setVisibleCursor();
if ( isReadOnly() )
unsetVisibleCursor();
else
setVisibleCursor();
setShadow(); setShadow();
if ( isEnabled() ) if ( isEnabled() )
@ -658,7 +689,7 @@ bool FLineEdit::hasHotkey()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FLineEdit::draw() void FLineEdit::draw()
{ {
if ( cursor_pos == NOT_SET ) if ( cursor_pos == NOT_SET && isReadOnly() )
cursorEnd(); cursorEnd();
if ( ! isShown() ) if ( ! isShown() )

View File

@ -202,6 +202,9 @@ void FListBox::insert (FListBoxItem listItem)
itemlist.push_back (listItem); itemlist.push_back (listItem);
if ( current == 0 )
current = 1;
std::size_t element_count = getCount(); std::size_t element_count = getCount();
recalculateVerticalBar (element_count); recalculateVerticalBar (element_count);
} }
@ -300,13 +303,8 @@ void FListBox::onKeyPress (FKeyEvent* ev)
processKeyAction(ev); // Process the keystrokes processKeyAction(ev); // Process the keystrokes
if ( current_before != current ) if ( current_before != current )
{
processChanged(); processChanged();
if ( ! isMultiSelection() )
processSelect();
}
if ( ev->isAccepted() ) if ( ev->isAccepted() )
{ {
bool draw_vbar( yoffset_before != yoffset ); bool draw_vbar( yoffset_before != yoffset );
@ -330,12 +328,14 @@ void FListBox::onMouseDown (FMouseEvent* ev)
getWidgetFocus(); getWidgetFocus();
int yoffset_before = yoffset; int yoffset_before = yoffset;
std::size_t current_before = current;
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
if ( mouse_x > 1 && mouse_x < int(getWidth()) if ( mouse_x > 1 && mouse_x < int(getWidth())
&& mouse_y > 1 && mouse_y < int(getHeight()) ) && mouse_y > 1 && mouse_y < int(getHeight()) )
{ {
click_on_list = true;
std::size_t element_count = getCount(); std::size_t element_count = getCount();
current = std::size_t(yoffset + mouse_y - 1); current = std::size_t(yoffset + mouse_y - 1);
@ -347,6 +347,11 @@ void FListBox::onMouseDown (FMouseEvent* ev)
if ( ev->getButton() == fc::RightButton ) if ( ev->getButton() == fc::RightButton )
multiSelection(current); multiSelection(current);
if ( current_before != current )
{
processChanged();
}
if ( isShown() ) if ( isShown() )
drawList(); drawList();
@ -356,13 +361,15 @@ void FListBox::onMouseDown (FMouseEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FListBox::onMouseUp (FMouseEvent* ev) void FListBox::onMouseUp (FMouseEvent* ev)
{ {
click_on_list = false;
if ( drag_scroll != fc::noScroll ) if ( drag_scroll != fc::noScroll )
stopDragScroll(); stopDragScroll();
@ -374,8 +381,6 @@ void FListBox::onMouseUp (FMouseEvent* ev)
if ( mouse_x > 1 && mouse_x < int(getWidth()) if ( mouse_x > 1 && mouse_x < int(getWidth())
&& mouse_y > 1 && mouse_y < int(getHeight()) ) && mouse_y > 1 && mouse_y < int(getHeight()) )
{ {
processChanged();
if ( ! isMultiSelection() ) if ( ! isMultiSelection() )
processSelect(); processSelect();
} }
@ -400,6 +405,7 @@ void FListBox::onMouseMove (FMouseEvent* ev)
if ( mouse_x > 1 && mouse_x < int(getWidth()) if ( mouse_x > 1 && mouse_x < int(getWidth())
&& mouse_y > 1 && mouse_y < int(getHeight()) ) && mouse_y > 1 && mouse_y < int(getHeight()) )
{ {
click_on_list = true;
std::size_t element_count = getCount(); std::size_t element_count = getCount();
current = std::size_t(yoffset + mouse_y - 1); current = std::size_t(yoffset + mouse_y - 1);
@ -408,11 +414,16 @@ void FListBox::onMouseMove (FMouseEvent* ev)
inc_search.clear(); inc_search.clear();
// Handle multiple selections if ( current_before != current )
if ( ev->getButton() == fc::RightButton
&& 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() ) if ( isShown() )
@ -424,13 +435,13 @@ void FListBox::onMouseMove (FMouseEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
// Auto-scrolling when dragging mouse outside the widget // Auto-scrolling when dragging mouse outside the widget
if ( mouse_y < 2 ) if ( click_on_list && mouse_y < 2 )
dragUp (ev->getButton()); dragUp (ev->getButton());
else if ( mouse_y >= int(getHeight()) ) else if ( click_on_list && mouse_y >= int(getHeight()) )
dragDown (ev->getButton()); dragDown (ev->getButton());
else else
stopDragScroll(); stopDragScroll();
@ -485,6 +496,7 @@ void FListBox::onTimer (FTimerEvent*)
if ( current_before != current ) if ( current_before != current )
{ {
inc_search.clear(); inc_search.clear();
processChanged();
// Handle multiple selections // Handle multiple selections
if ( drag_scroll == fc::scrollUpSelect if ( drag_scroll == fc::scrollUpSelect
@ -501,7 +513,7 @@ void FListBox::onTimer (FTimerEvent*)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -533,9 +545,6 @@ void FListBox::onWheel (FWheelEvent* ev)
{ {
inc_search.clear(); inc_search.clear();
processChanged(); processChanged();
if ( ! isMultiSelection() )
processSelect();
} }
if ( isShown() ) if ( isShown() )
@ -547,7 +556,7 @@ void FListBox::onWheel (FWheelEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -770,12 +779,12 @@ void FListBox::drawScrollbars()
if ( ! hbar->isShown() && isHorizontallyScrollable() ) if ( ! hbar->isShown() && isHorizontallyScrollable() )
hbar->show(); hbar->show();
else else
vbar->redraw(); hbar->redraw();
if ( ! vbar->isShown() && isVerticallyScrollable() ) if ( ! vbar->isShown() && isVerticallyScrollable() )
vbar->show(); vbar->show();
else else
hbar->redraw(); vbar->redraw();
} }
@ -1085,7 +1094,7 @@ inline void FListBox::updateDrawing (bool draw_vbar, bool draw_hbar)
hbar->drawBar(); hbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1769,9 +1778,6 @@ void FListBox::cb_VBarChange (FWidget*, FDataPtr)
{ {
inc_search.clear(); inc_search.clear();
processChanged(); processChanged();
if ( ! isMultiSelection() )
processSelect();
} }
if ( isShown() ) if ( isShown() )
@ -1785,7 +1791,7 @@ void FListBox::cb_VBarChange (FWidget*, FDataPtr)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -1838,7 +1844,7 @@ void FListBox::cb_HBarChange (FWidget*, FDataPtr)
{ {
drawList(); drawList();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
if ( scrollType >= FScrollbar::scrollStepBackward ) if ( scrollType >= FScrollbar::scrollStepBackward )
@ -1849,7 +1855,7 @@ void FListBox::cb_HBarChange (FWidget*, FDataPtr)
hbar->drawBar(); hbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }

View File

@ -968,7 +968,7 @@ void FListView::onMouseDown (FMouseEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
} }
@ -1073,7 +1073,7 @@ void FListView::onMouseMove (FMouseEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
// auto-scrolling when dragging mouse outside the widget // auto-scrolling when dragging mouse outside the widget
@ -1160,7 +1160,7 @@ void FListView::onTimer (FTimerEvent*)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1199,7 +1199,7 @@ void FListView::onWheel (FWheelEvent* ev)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1462,12 +1462,12 @@ void FListView::drawScrollbars()
if ( ! hbar->isShown() && isHorizontallyScrollable() ) if ( ! hbar->isShown() && isHorizontallyScrollable() )
hbar->show(); hbar->show();
else else
vbar->redraw(); hbar->redraw();
if ( ! vbar->isShown() && isVerticallyScrollable() ) if ( ! vbar->isShown() && isVerticallyScrollable() )
vbar->show(); vbar->show();
else else
hbar->redraw(); vbar->redraw();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1928,7 +1928,7 @@ void FListView::updateDrawing (bool draw_vbar, bool draw_hbar)
hbar->drawBar(); hbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -2636,7 +2636,7 @@ void FListView::cb_VBarChange (FWidget*, FDataPtr)
vbar->drawBar(); vbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -2688,7 +2688,7 @@ void FListView::cb_HBarChange (FWidget*, FDataPtr)
drawHeadlines(); drawHeadlines();
drawList(); drawList();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
if ( scrollType >= FScrollbar::scrollStepBackward ) if ( scrollType >= FScrollbar::scrollStepBackward )
@ -2699,7 +2699,7 @@ void FListView::cb_HBarChange (FWidget*, FDataPtr)
hbar->drawBar(); hbar->drawBar();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }

View File

@ -21,6 +21,7 @@
***********************************************************************/ ***********************************************************************/
#include <memory> #include <memory>
#include <tuple>
#include <vector> #include <vector>
#include "final/fapplication.h" #include "final/fapplication.h"
@ -102,7 +103,7 @@ void FMenu::hide()
const auto& t_geometry = getTermGeometryWithShadow(); const auto& t_geometry = getTermGeometryWithShadow();
restoreVTerm (t_geometry); restoreVTerm (t_geometry);
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
if ( ! isSubMenu() ) if ( ! isSubMenu() )
{ {
@ -204,7 +205,7 @@ void FMenu::onMouseDown (FMouseEvent* ev)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
return; return;
@ -313,7 +314,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
{ {
closeOpenedSubMenu(); closeOpenedSubMenu();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -347,7 +348,7 @@ void FMenu::cb_menuitem_toggled (FWidget* widget, FDataPtr)
// private methods of FMenu // private methods of FMenu
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenu::isWindowsMenu (const FWidget* w) const bool FMenu::isDialog (const FWidget* w) const
{ {
return w->isDialogWidget(); return w->isDialogWidget();
} }
@ -381,6 +382,13 @@ bool FMenu::isSubMenu() const
return false; return false;
} }
//----------------------------------------------------------------------
bool FMenu::isDialogMenu() const
{
auto super = getSuperMenu();
return ( super ) ? super->isDialogWidget() : false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenu::isMouseOverMenu (const FPoint& termpos) bool FMenu::isMouseOverMenu (const FPoint& termpos)
{ {
@ -584,7 +592,7 @@ void FMenu::openSubMenu (FMenu* sub_menu, bool select)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -635,7 +643,7 @@ void FMenu::hideSuperMenus()
m->hide(); m->hide();
m->hideSuperMenus(); m->hideSuperMenus();
} }
else if ( isWindowsMenu(super) ) else if ( isDialog(super) )
{ {
auto dgl = static_cast<FDialog*>(super); auto dgl = static_cast<FDialog*>(super);
dgl->leaveMenu(); dgl->leaveMenu();
@ -696,7 +704,7 @@ void FMenu::mouseDownSubmenu (FMenuItem* m_item)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -764,7 +772,7 @@ bool FMenu::mouseUpOverList (FPoint mouse_pos)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
return true; return true;
@ -1038,7 +1046,7 @@ bool FMenu::selectNextItem()
redraw(); redraw();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
break; break;
} }
@ -1088,7 +1096,7 @@ bool FMenu::selectPrevItem()
redraw(); redraw();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
break; break;
} }
} }
@ -1151,7 +1159,7 @@ bool FMenu::hotkeyMenu (FKeyEvent* ev)
hide(); hide();
hideSuperMenus(); hideSuperMenus();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
ev->accept(); ev->accept();
item->processClicked(); item->processClicked();
} }
@ -1494,7 +1502,7 @@ inline void FMenu::selectPrevMenu (FKeyEvent* ev)
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
else else
keypressMenuBar(ev); // select previous menu keypressMenuBar(ev); // select previous menu
@ -1559,7 +1567,7 @@ inline void FMenu::closeMenu()
if ( getStatusBar() ) if ( getStatusBar() )
getStatusBar()->clearMessage(); getStatusBar()->clearMessage();
if ( ! (super && isWindowsMenu(super)) ) if ( ! (super && isDialog(super)) )
switchToPrevWindow(this); switchToPrevWindow(this);
} }
@ -1567,7 +1575,7 @@ inline void FMenu::closeMenu()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1576,4 +1584,30 @@ void FMenu::processActivate()
emitCallback("activate"); emitCallback("activate");
} }
// non-member functions
//----------------------------------------------------------------------
std::tuple<bool, bool> 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 } // namespace finalcut

View File

@ -971,7 +971,7 @@ void FMenuBar::leaveMenuBar()
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
mouse_down = false; mouse_down = false;
} }

View File

@ -249,7 +249,7 @@ void FMenuItem::openMenu()
dd_menu->raiseWindow(); dd_menu->raiseWindow();
dd_menu->redraw(); dd_menu->redraw();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -296,7 +296,7 @@ void FMenuItem::onMouseDoubleClick (FMouseEvent* ev)
passMouseEvent (mbar, ev, fc::MouseDoubleClick_Event); passMouseEvent (mbar, ev, fc::MouseDoubleClick_Event);
} }
if ( isWindowsMenu(super_menu) ) if ( isDialog(super_menu) )
{ {
auto dgl = static_cast<FDialog*>(super_menu); auto dgl = static_cast<FDialog*>(super_menu);
passMouseEvent (dgl, ev, fc::MouseDoubleClick_Event); passMouseEvent (dgl, ev, fc::MouseDoubleClick_Event);
@ -321,7 +321,7 @@ void FMenuItem::onMouseDown (FMouseEvent* ev)
passMouseEvent (mbar, ev, fc::MouseDown_Event); passMouseEvent (mbar, ev, fc::MouseDown_Event);
} }
if ( isWindowsMenu(super_menu) ) if ( isDialog(super_menu) )
{ {
auto dgl = static_cast<FDialog*>(super_menu); auto dgl = static_cast<FDialog*>(super_menu);
passMouseEvent (dgl, ev, fc::MouseDown_Event); passMouseEvent (dgl, ev, fc::MouseDown_Event);
@ -346,7 +346,7 @@ void FMenuItem::onMouseUp (FMouseEvent* ev)
passMouseEvent (mbar, ev, fc::MouseUp_Event); passMouseEvent (mbar, ev, fc::MouseUp_Event);
} }
if ( isWindowsMenu(super_menu) ) if ( isDialog(super_menu) )
{ {
auto dgl = static_cast<FDialog*>(super_menu); auto dgl = static_cast<FDialog*>(super_menu);
passMouseEvent (dgl, ev, fc::MouseUp_Event); passMouseEvent (dgl, ev, fc::MouseUp_Event);
@ -371,7 +371,7 @@ void FMenuItem::onMouseMove (FMouseEvent* ev)
passMouseEvent (mbar, ev, fc::MouseMove_Event); passMouseEvent (mbar, ev, fc::MouseMove_Event);
} }
if ( isWindowsMenu(super_menu) ) if ( isDialog(super_menu) )
{ {
auto dgl = static_cast<FDialog*>(super_menu); auto dgl = static_cast<FDialog*>(super_menu);
passMouseEvent (dgl, ev, fc::MouseMove_Event); passMouseEvent (dgl, ev, fc::MouseMove_Event);
@ -458,7 +458,7 @@ void FMenuItem::onFocusOut (FFocusEvent*)
// protected methods of FMenuItem // protected methods of FMenuItem
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenuItem::isWindowsMenu (FWidget* w) const bool FMenuItem::isDialog (FWidget* w) const
{ {
return ( w ) ? w->isDialogWidget() : false; return ( w ) ? w->isDialogWidget() : false;
} }

View File

@ -53,16 +53,16 @@ FPoint& FPoint::operator = (FPoint&& p)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FPoint& FPoint::operator += (const FPoint& p) FPoint& FPoint::operator += (const FPoint& p)
{ {
xpos = xpos + p.xpos; xpos += p.xpos;
ypos = ypos + p.ypos; ypos += p.ypos;
return *this; return *this;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FPoint& FPoint::operator -= (const FPoint& p) FPoint& FPoint::operator -= (const FPoint& p)
{ {
xpos = xpos - p.xpos; xpos -= p.xpos;
ypos = ypos - p.ypos; ypos -= p.ypos;
return *this; return *this;
} }
@ -91,6 +91,20 @@ bool FPoint::isOrigin() const
return xpos == 0 && ypos == 0; 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) std::ostream& operator << (std::ostream& outstr, const FPoint& p)
{ {

View File

@ -133,7 +133,7 @@ void FProgressbar::draw()
if ( getFlags().shadow ) if ( getFlags().shadow )
drawShadow(this); drawShadow(this);
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -179,7 +179,7 @@ void FProgressbar::drawProgressBar()
setReverse(false); setReverse(false);
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -229,19 +229,19 @@ void FRect::setCoordinates (int x1, int y1, int x2, int y2)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FRect::move (int dx, int dy) void FRect::move (int dx, int dy)
{ {
X1 = X1 + dx; X1 += dx;
Y1 = Y1 + dy; Y1 += dy;
X2 = X2 + dx; X2 += dx;
Y2 = Y2 + dy; Y2 += dy;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FRect::move (const FPoint& d) void FRect::move (const FPoint& d)
{ {
X1 = X1 + d.getX(); X1 += d.getX();
Y1 = Y1 + d.getY(); Y1 += d.getY();
X2 = X2 + d.getX(); X2 += d.getX();
Y2 = Y2 + d.getY(); Y2 += d.getY();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -332,6 +332,7 @@ FRect& FRect::operator = (FRect&& r)
return *this; return *this;
} }
// FRect non-member operators
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FRect operator + (const FRect& r, const FSize& s) FRect operator + (const FRect& r, const FSize& s)
{ {

View File

@ -129,8 +129,7 @@ void FScrollbar::setPageSize (int document_size, int page_size)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FScrollbar::setOrientation (fc::orientation o) void FScrollbar::setOrientation (fc::orientation o)
{ {
std::size_t nf{0}; length = ( o == fc::vertical ) ? getHeight() : getWidth();
length = ( getHeight() > getWidth() ) ? getHeight() : getWidth();
if ( o == fc::vertical && bar_orientation == fc::horizontal ) if ( o == fc::vertical && bar_orientation == fc::horizontal )
{ {
@ -141,12 +140,9 @@ void FScrollbar::setOrientation (fc::orientation o)
{ {
setWidth(length); setWidth(length);
setHeight(1); setHeight(1);
if ( isNewFont() )
nf = 2;
} }
slider_length = bar_length = length - nf - 2; calculateSliderValues();
bar_orientation = o; bar_orientation = o;
} }
@ -158,10 +154,9 @@ void FScrollbar::setGeometry ( const FPoint& pos, const FSize& size
FWidget::setGeometry (pos, size, adjust); FWidget::setGeometry (pos, size, adjust);
std::size_t nf{0};
std::size_t w = size.getWidth(); std::size_t w = size.getWidth();
std::size_t h = size.getHeight(); std::size_t h = size.getHeight();
length = ( h > w ) ? h : w; length = ( bar_orientation == fc::vertical ) ? h : w;
if ( bar_orientation == fc::vertical ) if ( bar_orientation == fc::vertical )
{ {
@ -172,12 +167,9 @@ void FScrollbar::setGeometry ( const FPoint& pos, const FSize& size
{ {
setWidth(length); setWidth(length);
setHeight(1); setHeight(1);
if ( isNewFont() )
nf = 2;
} }
slider_length = bar_length = length - nf - 2; calculateSliderValues();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -122,6 +122,7 @@ void FSize::scaleBy (const FPoint& d)
scaleBy (d.getX(), d.getY()); scaleBy (d.getX(), d.getY());
} }
// FSize non-member operators
//---------------------------------------------------------------------- //----------------------------------------------------------------------
std::ostream& operator << (std::ostream& outstr, const FSize& s) std::ostream& operator << (std::ostream& outstr, const FSize& s)
{ {

View File

@ -97,6 +97,7 @@ bool FSpinBox::setShadow (bool enable)
return getFlags().shadow; return getFlags().shadow;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FSpinBox::setValue (sInt64 n) void FSpinBox::setValue (sInt64 n)
{ {

View File

@ -124,7 +124,7 @@ void FSwitch::draw()
drawCheckButton(); drawCheckButton();
FToggleButton::draw(); FToggleButton::draw();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -609,7 +609,7 @@ void FTextView::draw()
setCursorPos (FPoint(int(getWidth()), int(getHeight()))); setCursorPos (FPoint(int(getWidth()), int(getHeight())));
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -634,12 +634,12 @@ void FTextView::drawScrollbars()
if ( ! hbar->isShown() && isHorizontallyScrollable() ) if ( ! hbar->isShown() && isHorizontallyScrollable() )
hbar->show(); hbar->show();
else else
vbar->redraw(); hbar->redraw();
if ( ! vbar->isShown() && isVerticallyScrollable() ) if ( ! vbar->isShown() && isVerticallyScrollable() )
vbar->show(); vbar->show();
else else
hbar->redraw(); vbar->redraw();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -221,7 +221,7 @@ void FToggleButton::onMouseDown (FMouseEvent* ev)
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }
@ -298,7 +298,7 @@ void FToggleButton::onAccel (FAccelEvent* ev)
{ {
getStatusBar()->drawMessage(); getStatusBar()->drawMessage();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
processClick(); processClick();

View File

@ -75,21 +75,6 @@ void FToolTip::setText (const FString& txt)
calculateDimensions(); 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() void FToolTip::show()
{ {
@ -128,6 +113,21 @@ void FToolTip::init()
calculateDimensions(); 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() void FToolTip::calculateDimensions()
{ {

View File

@ -144,7 +144,7 @@ void FVTerm::setTermXY (int x, int y)
if ( move_str ) if ( move_str )
appendOutputBuffer(move_str); appendOutputBuffer(move_str);
flushOutputBuffer(); flush();
term_pos->setPoint(x, y); term_pos->setPoint(x, y);
} }
@ -158,7 +158,7 @@ void FVTerm::hideCursor (bool enable)
if ( visibility_str ) if ( visibility_str )
appendOutputBuffer(visibility_str); appendOutputBuffer(visibility_str);
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -590,6 +590,21 @@ void FVTerm::print (const FColorPair& pair)
setColor (pair.getForegroundColor(), pair.getBackgroundColor()); 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 // protected methods of FVTerm
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1278,19 +1293,6 @@ void FVTerm::finishTerminalUpdate()
terminal_update_complete = true; 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 // private methods of FVTerm
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1940,7 +1942,7 @@ void FVTerm::finish()
if ( FTerm::hasAlternateScreen() ) if ( FTerm::hasAlternateScreen() )
clearTerm(); clearTerm();
flushOutputBuffer(); flush();
if ( output_buffer ) if ( output_buffer )
delete output_buffer; delete output_buffer;
@ -2089,7 +2091,7 @@ bool FVTerm::clearTerm (int fillchar)
setTermXY (0, 0); setTermXY (0, 0);
} }
flushOutputBuffer(); flush();
return true; return true;
} }
@ -3047,7 +3049,7 @@ int FVTerm::appendOutputBuffer (int ch)
output_buffer->push(ch); output_buffer->push(ch);
if ( output_buffer->size() >= TERMINAL_OUTPUT_BUFFER_SIZE ) if ( output_buffer->size() >= TERMINAL_OUTPUT_BUFFER_SIZE )
flushOutputBuffer(); flush();
return ch; return ch;
} }

View File

@ -973,7 +973,7 @@ void FWidget::redraw()
if ( redraw_root_widget == this ) if ( redraw_root_widget == this )
{ {
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
redraw_root_widget = nullptr; redraw_root_widget = nullptr;
} }
} }
@ -1053,7 +1053,7 @@ void FWidget::show()
{ {
finishTerminalUpdate(); finishTerminalUpdate();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
show_root_widget = nullptr; show_root_widget = nullptr;
} }
@ -1373,7 +1373,7 @@ void FWidget::hideArea (const FSize& size)
print() << FPoint(1, 1 + y) << FString(size.getWidth(), L' '); print() << FPoint(1, 1 + y) << FString(size.getWidth(), L' ');
} }
flushOutputBuffer(); flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1519,10 +1519,12 @@ bool FWidget::event (FEvent* ev)
break; break;
case fc::MouseDown_Event: case fc::MouseDown_Event:
emitCallback("mouse-press");
onMouseDown (static_cast<FMouseEvent*>(ev)); onMouseDown (static_cast<FMouseEvent*>(ev));
break; break;
case fc::MouseUp_Event: case fc::MouseUp_Event:
emitCallback("mouse-release");
onMouseUp (static_cast<FMouseEvent*>(ev)); onMouseUp (static_cast<FMouseEvent*>(ev));
break; break;
@ -1531,18 +1533,22 @@ bool FWidget::event (FEvent* ev)
break; break;
case fc::MouseWheel_Event: case fc::MouseWheel_Event:
emitWheelCallback(static_cast<FWheelEvent*>(ev));
onWheel (static_cast<FWheelEvent*>(ev)); onWheel (static_cast<FWheelEvent*>(ev));
break; break;
case fc::MouseMove_Event: case fc::MouseMove_Event:
emitCallback("mouse-move");
onMouseMove (static_cast<FMouseEvent*>(ev)); onMouseMove (static_cast<FMouseEvent*>(ev));
break; break;
case fc::FocusIn_Event: case fc::FocusIn_Event:
emitCallback("focus-in");
onFocusIn (static_cast<FFocusEvent*>(ev)); onFocusIn (static_cast<FFocusEvent*>(ev));
break; break;
case fc::FocusOut_Event: case fc::FocusOut_Event:
emitCallback("focus-out");
onFocusOut (static_cast<FFocusEvent*>(ev)); onFocusOut (static_cast<FFocusEvent*>(ev));
break; 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) void FWidget::setWindowFocus (bool enable)
{ {
@ -1894,7 +1911,7 @@ bool FWidget::changeFocus ( FWidget* follower, FWidget* parent
redraw(); redraw();
follower->redraw(); follower->redraw();
updateTerminal(); updateTerminal();
flushOutputBuffer(); flush();
} }
} }

View File

@ -23,7 +23,9 @@
#include <utility> #include <utility>
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fcombobox.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/fmenu.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fstatusbar.h" #include "final/fstatusbar.h"
#include "final/fwindow.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<FMenu*>(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<FDropDownListBox*>(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 } // namespace finalcut

View File

@ -163,7 +163,7 @@ class FApplication : public FWidget
bool getMouseEvent(); bool getMouseEvent();
FWidget*& determineClickedWidget(); FWidget*& determineClickedWidget();
void unsetMoveSizeMode(); void unsetMoveSizeMode();
void closeOpenMenu(); void closeDropDown();
void unselectMenubarItems(); void unselectMenubarItems();
void sendMouseEvent(); void sendMouseEvent();
void sendMouseMoveEvent ( const FPoint& void sendMouseMoveEvent ( const FPoint&

View File

@ -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 *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
/* 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 <final/final.h> 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 <typename T>
void insert ( const std::initializer_list<T>& list
, FDataPtr = nullptr );
template <typename ItemT>
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 <typename T>
void FComboBox::insert ( const std::initializer_list<T>& list
, FDataPtr d )
{
for (auto& item : list)
{
FListBoxItem listItem (FString() << item, d);
insert (listItem);
}
}
//----------------------------------------------------------------------
template <typename ItemT>
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

View File

@ -50,9 +50,7 @@
#endif #endif
/* Define to 1 if GPM mouse is enabled */ /* Define to 1 if GPM mouse is enabled */
#ifndef F_HAVE_LIBGPM /* #undef HAVE_LIBGPM */
#define F_HAVE_LIBGPM 1
#endif
/* Define to 1 if you have the <linux/fb.h> header file. */ /* Define to 1 if you have the <linux/fb.h> header file. */
#ifndef F_HAVE_LINUX_FB_H #ifndef F_HAVE_LINUX_FB_H

View File

@ -140,11 +140,6 @@ class FFileDialog : public FDialog
static const FString fileSaveChooser ( FWidget* static const FString fileSaveChooser ( FWidget*
, const FString& = FString() , const FString& = FString()
, const FString& = FString() ); , const FString& = FString() );
// Friend function
friend const FString fileChooser ( FWidget*
, const FString&
, const FString&
, FFileDialog::DialogType);
protected: protected:
// Method // Method
@ -212,6 +207,10 @@ class FFileDialog : public FDialog
, const FFileDialog::dir_entry& ); , const FFileDialog::dir_entry& );
friend bool sortDirFirst ( const FFileDialog::dir_entry& friend bool sortDirFirst ( const FFileDialog::dir_entry&
, const FFileDialog::dir_entry& ); , const FFileDialog::dir_entry& );
friend const FString fileChooser ( FWidget*
, const FString&
, const FString&
, FFileDialog::DialogType);
}; };
// FMessageBox inline functions // FMessageBox inline functions

View File

@ -35,6 +35,7 @@
#include <final/fobject.h> #include <final/fobject.h>
#include <final/fcolorpalette.h> #include <final/fcolorpalette.h>
#include <final/fcolorpair.h> #include <final/fcolorpair.h>
#include <final/fcombobox.h>
#include <final/fcharmap.h> #include <final/fcharmap.h>
#include <final/fcheckbox.h> #include <final/fcheckbox.h>
#include <final/fcheckmenuitem.h> #include <final/fcheckmenuitem.h>

View File

@ -127,19 +127,23 @@ class FLineEdit : public FWidget
void setLabelAssociatedWidget (FWidget*); void setLabelAssociatedWidget (FWidget*);
void setGeometry ( const FPoint&, const FSize& void setGeometry ( const FPoint&, const FSize&
, bool = true ) override; , bool = true ) override;
bool setEnable(bool) override; bool setEnable (bool) override;
bool setEnable() override; bool setEnable() override;
bool unsetEnable() override; bool unsetEnable() override;
bool setDisable() override; bool setDisable() override;
bool setFocus(bool) override; bool setFocus (bool) override;
bool setFocus() override; bool setFocus() override;
bool unsetFocus() override; bool unsetFocus() override;
bool setShadow(bool); bool setShadow (bool);
bool setShadow(); bool setShadow();
bool unsetShadow(); bool unsetShadow();
bool setReadOnly (bool);
bool setReadOnly();
bool unsetReadOnly();
// Inquiry // Inquiry
bool hasShadow(); bool hasShadow() const;
bool isReadOnly() const;
// Methods // Methods
void hide() override; void hide() override;
@ -215,14 +219,12 @@ class FLineEdit : public FWidget
int scroll_repeat{100}; int scroll_repeat{100};
bool scroll_timer{false}; bool scroll_timer{false};
bool insert_mode{true}; bool insert_mode{true};
bool read_only{false};
std::size_t cursor_pos{NOT_SET}; std::size_t cursor_pos{NOT_SET};
std::size_t text_offset{0}; std::size_t text_offset{0};
std::size_t char_width_offset{0}; std::size_t char_width_offset{0};
std::size_t x_pos{0}; std::size_t x_pos{0};
std::size_t max_length{std::numeric_limits<std::size_t>::max()}; std::size_t max_length{std::numeric_limits<std::size_t>::max()};
// Friend class
friend class FSpinBox;
}; };
@ -306,9 +308,21 @@ inline bool FLineEdit::unsetShadow()
{ return setShadow(false); } { 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; } { return getFlags().shadow; }
//----------------------------------------------------------------------
inline bool FLineEdit::isReadOnly() const
{ return read_only; }
} // namespace finalcut } // namespace finalcut
#endif // FLINEEDIT_H #endif // FLINEEDIT_H

View File

@ -159,7 +159,7 @@ class FListBox : public FWidget
FListBox (const FListBox&) = delete; FListBox (const FListBox&) = delete;
// Destructor // Destructor
virtual ~FListBox(); virtual ~FListBox();
// Disable assignment operator (=) // Disable assignment operator (=)
FListBox& operator = (const FListBox&) = delete; FListBox& operator = (const FListBox&) = delete;
@ -167,8 +167,10 @@ class FListBox : public FWidget
// Accessors // Accessors
const FString getClassName() const override; const FString getClassName() const override;
std::size_t getCount() const; std::size_t getCount() const;
FListBoxItem getItem (std::size_t); FListBoxItem& getItem (std::size_t);
FListBoxItem getItem (listBoxItems::iterator) const; const FListBoxItem& getItem (std::size_t) const;
FListBoxItem& getItem (listBoxItems::iterator);
const FListBoxItem& getItem (listBoxItems::const_iterator) const;
std::size_t currentItem() const; std::size_t currentItem() const;
FString& getText(); FString& getText();
@ -308,7 +310,7 @@ class FListBox : public FWidget
void processChanged(); void processChanged();
void lazyConvert (listBoxItems::iterator, int); void lazyConvert (listBoxItems::iterator, int);
listBoxItems::iterator index2iterator (std::size_t); listBoxItems::iterator index2iterator (std::size_t);
listBoxItems::const_iterator index2iterator (std::size_t index) const;
// Callback methods // Callback methods
void cb_VBarChange (FWidget*, FDataPtr); void cb_VBarChange (FWidget*, FDataPtr);
void cb_HBarChange (FWidget*, FDataPtr); void cb_HBarChange (FWidget*, FDataPtr);
@ -340,6 +342,7 @@ class FListBox : public FWidget
bool multi_select{false}; bool multi_select{false};
bool mouse_select{false}; bool mouse_select{false};
bool scroll_timer{false}; bool scroll_timer{false};
bool click_on_list{false};
}; };
@ -381,14 +384,25 @@ inline std::size_t FListBox::getCount() const
{ return itemlist.size(); } { 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); listBoxItems::iterator iter = index2iterator(index - 1);
return *iter; 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; } { return *iter; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -539,6 +553,15 @@ inline FListBox::listBoxItems::iterator \
return iter; 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 } // namespace finalcut
#endif // FLISTBOX_H #endif // FLISTBOX_H

View File

@ -159,11 +159,12 @@ class FMenu : public FWindow, public FMenuList
void setSuperMenu (FWidget*); void setSuperMenu (FWidget*);
// Inquiries // Inquiries
bool isWindowsMenu (const FWidget*) const; bool isDialog (const FWidget*) const;
bool isMenuBar (const FWidget*) const; bool isMenuBar (const FWidget*) const;
bool isMenu (const FWidget*) const; bool isMenu (const FWidget*) const;
bool isRadioMenuItem (const FWidget*) const; bool isRadioMenuItem (const FWidget*) const;
bool isSubMenu() const; bool isSubMenu() const;
bool isDialogMenu() const;
bool isMouseOverMenu (const FPoint&); bool isMouseOverMenu (const FPoint&);
bool isMouseOverSubMenu (const FPoint&); bool isMouseOverSubMenu (const FPoint&);
bool isMouseOverSuperMenu (const FPoint&); bool isMouseOverSuperMenu (const FPoint&);
@ -215,14 +216,6 @@ class FMenu : public FWindow, public FMenuList
void closeMenu(); void closeMenu();
void processActivate(); void processActivate();
// Friend classes
friend class FApplication;
friend class FCheckMenuItem;
friend class FDialog;
friend class FMenuBar;
friend class FMenuItem;
friend class FRadioMenuItem;
// Data members // Data members
FMenuItem menuitem{}; FMenuItem menuitem{};
FWidget* super_menu{nullptr}; FWidget* super_menu{nullptr};
@ -232,8 +225,22 @@ class FMenu : public FWindow, public FMenuList
std::size_t hotkeypos{NOT_SET}; std::size_t hotkeypos{NOT_SET};
bool mouse_down{false}; bool mouse_down{false};
bool has_checkable_items{false}; bool has_checkable_items{false};
// Friend functions
friend std::tuple<bool, bool> 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<bool, bool> closeOpenMenus (FMenu*, const FPoint&);
// FMenu inline functions // FMenu inline functions
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -147,15 +147,15 @@ class FMenuBar : public FWindow, public FMenuList
void passEventToMenu (const FMouseEvent*&); void passEventToMenu (const FMouseEvent*&);
void leaveMenuBar(); void leaveMenuBar();
// Friend classes
friend class FMenu;
friend class FMenuItem;
// Data members // Data members
std::size_t screenWidth{80}; std::size_t screenWidth{80};
bool mouse_down{false}; bool mouse_down{false};
bool drop_down{false}; bool drop_down{false};
bool focus_changed{false}; bool focus_changed{false};
// Friend classes
friend class FMenu;
friend class FMenuItem;
}; };

View File

@ -150,7 +150,7 @@ class FMenuItem : public FWidget
void setSuperMenu (FWidget*); void setSuperMenu (FWidget*);
// Inquiries // Inquiries
bool isWindowsMenu (FWidget*) const; bool isDialog (FWidget*) const;
bool isMenuBar (FWidget*) const; bool isMenuBar (FWidget*) const;
bool isMenu (FWidget*) const; bool isMenu (FWidget*) const;

View File

@ -125,10 +125,6 @@ class FOptiAttr final
// Disable assignment operator (=) // Disable assignment operator (=)
FOptiAttr& operator = (const FOptiAttr&) = delete; FOptiAttr& operator = (const FOptiAttr&) = delete;
// Friend operator functions
friend bool operator == (const FChar&, const FChar&);
friend bool operator != (const FChar&, const FChar&);
// Accessors // Accessors
const FString getClassName() const; const FString getClassName() const;
@ -336,24 +332,6 @@ class FOptiAttr final
// FOptiAttr inline functions // 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 inline const FString FOptiAttr::getClassName() const
{ return "FOptiAttr"; } { return "FOptiAttr"; }
@ -374,6 +352,26 @@ inline void FOptiAttr::setDefaultColorSupport()
inline void FOptiAttr::unsetDefaultColorSupport() inline void FOptiAttr::unsetDefaultColorSupport()
{ ansi_default_color = false; } { 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 } // namespace finalcut
#endif // FOPTIATTR_H #endif // FOPTIATTR_H

View File

@ -203,9 +203,6 @@ class FOptiMove final
bool isMethod5Faster (int&, int, int, int); bool isMethod5Faster (int&, int, int, int);
void moveByMethod (int, int, int, int, int); void moveByMethod (int, int, int, int, int);
// Friend function
friend void printDurations (const FOptiMove&);
// Data members // Data members
capability F_cursor_home{}; capability F_cursor_home{};
capability F_carriage_return{}; capability F_carriage_return{};
@ -236,6 +233,9 @@ class FOptiMove final
char move_buf[BUF_SIZE]{'\0'}; char move_buf[BUF_SIZE]{'\0'};
bool automatic_left_margin{false}; bool automatic_left_margin{false};
bool eat_nl_glitch{false}; bool eat_nl_glitch{false};
// Friend function
friend void printDurations (const FOptiMove&);
}; };

View File

@ -64,14 +64,6 @@ class FPoint
FPoint& operator += (const FPoint&); FPoint& operator += (const 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 // Accessors
virtual const FString getClassName(); virtual const FString getClassName();
int getX() const; int getX() const;
@ -88,10 +80,23 @@ class FPoint
int& x_ref(); int& x_ref();
int& y_ref(); int& y_ref();
// Methods
void move (int, int);
void move (const FPoint&);
private: private:
// Data members // Data members
int xpos{0}; int xpos{0};
int ypos{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) , 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() inline const FString FPoint::getClassName()
{ return "FPoint"; } { return "FPoint"; }
@ -158,6 +143,28 @@ inline int& FPoint::x_ref()
inline int& FPoint::y_ref() inline int& FPoint::y_ref()
{ return ypos; } { 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 } // namespace finalcut
#endif // FPOINT_H #endif // FPOINT_H

View File

@ -72,13 +72,6 @@ class FRect
FRect& operator = (const FRect&); FRect& operator = (const FRect&);
FRect& operator = (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 // Accessors
virtual const FString getClassName(); virtual const FString getClassName();
int getX1() const; int getX1() const;
@ -142,6 +135,14 @@ class FRect
int Y1{0}; int Y1{0};
int X2{-1}; int X2{-1};
int Y2{-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 // FRect inline functions

View File

@ -69,18 +69,6 @@ class FSize
FSize& operator += (const FSize&); FSize& operator += (const 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 // Accessors
virtual const FString getClassName(); virtual const FString getClassName();
std::size_t getWidth() const; std::size_t getWidth() const;
@ -106,6 +94,19 @@ class FSize
// Data members // Data members
std::size_t width{0}; std::size_t width{0};
std::size_t height{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 // FSize inline functions
@ -127,6 +128,32 @@ inline FSize::FSize (std::size_t w, std::size_t h)
, height(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) inline bool operator < (const FSize& s1, const FSize& s2)
{ return s1.width < s2.width && s1.height < s2.height; } { 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); 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 } // namespace finalcut
#endif // FSIZE_H #endif // FSIZE_H

View File

@ -83,6 +83,7 @@ class FSpinBox : public FWidget
FSpinBox& operator = (const FSpinBox&) = delete; FSpinBox& operator = (const FSpinBox&) = delete;
// Accessors // Accessors
const FString getClassName() const override;
sInt64 getValue(); sInt64 getValue();
FString getPrefix() const; FString getPrefix() const;
FString getSuffix() const; FString getSuffix() const;
@ -159,6 +160,10 @@ class FSpinBox : public FWidget
// FSpinBox inline functions // FSpinBox inline functions
//----------------------------------------------------------------------
inline const FString FSpinBox::getClassName() const
{ return "FSpinBox"; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline sInt64 FSpinBox::getValue() inline sInt64 FSpinBox::getValue()
{ return value; } { return value; }

View File

@ -119,15 +119,15 @@ class FStatusKey : public FWidget
FStatusBar* getConnectedStatusbar() const; FStatusBar* getConnectedStatusbar() const;
void setConnectedStatusbar (FStatusBar*); void setConnectedStatusbar (FStatusBar*);
// Friend class
friend class FStatusBar;
// Data members // Data members
FString text{}; FString text{};
FStatusBar* bar{nullptr}; FStatusBar* bar{nullptr};
FKey key{0}; FKey key{0};
bool active{false}; bool active{false};
bool mouse_focus{false}; bool mouse_focus{false};
// Friend class
friend class FStatusBar;
}; };

View File

@ -161,22 +161,6 @@ class FString
operator const char* () const { return c_str(); } 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 // Accessor
virtual const FString getClassName(); virtual const FString getClassName();
@ -279,6 +263,22 @@ class FString
mutable char* c_string{nullptr}; mutable char* c_string{nullptr};
static wchar_t null_char; static wchar_t null_char;
static const wchar_t const_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&);
}; };

View File

@ -74,10 +74,6 @@ class FTermBuffer
FTermBuffer& operator << (const std::wstring&); FTermBuffer& operator << (const std::wstring&);
FTermBuffer& operator << (const FColorPair&); FTermBuffer& operator << (const FColorPair&);
// Non-member operators
friend FCharVector& operator << ( FCharVector&
, const FTermBuffer& );
// Accessors // Accessors
virtual const FString getClassName() const; virtual const FString getClassName() const;
std::size_t getLength() const; std::size_t getLength() const;
@ -104,6 +100,10 @@ class FTermBuffer
private: private:
FCharVector data{}; FCharVector data{};
// Non-member operators
friend FCharVector& operator << ( FCharVector&
, const FTermBuffer& );
}; };

View File

@ -153,9 +153,6 @@ class FToggleButton : public FWidget
void init(); void init();
void drawText (FString&&, std::size_t); void drawText (FString&&, std::size_t);
// Friend classes
friend class FButtonGroup;
// Data members // Data members
FButtonGroup* button_group{nullptr}; FButtonGroup* button_group{nullptr};
FString text{}; FString text{};
@ -163,6 +160,9 @@ class FToggleButton : public FWidget
std::size_t button_width{0}; // plus margin spaces std::size_t button_width{0}; // plus margin spaces
bool focus_inside_group{true}; bool focus_inside_group{true};
bool checked{false}; bool checked{false};
// Friend classes
friend class FButtonGroup;
}; };
// FRadioButton inline functions // FRadioButton inline functions

View File

@ -92,7 +92,6 @@ class FToolTip : public FWindow
void setText (const FString&); void setText (const FString&);
// Methods // Methods
void draw() override;
void show() override; void show() override;
void hide() override; void hide() override;
@ -102,6 +101,7 @@ class FToolTip : public FWindow
private: private:
// Methods // Methods
void init(); void init();
void draw() override;
void calculateDimensions(); void calculateDimensions();
void adjustSize() override; void adjustSize() override;

View File

@ -307,6 +307,7 @@ class FVTerm
virtual void print (const FPoint&); virtual void print (const FPoint&);
virtual void print (const FColorPair&); virtual void print (const FColorPair&);
virtual FVTerm& print(); virtual FVTerm& print();
static void flush();
static void beep(); static void beep();
static void redefineDefaultColors (bool); static void redefineDefaultColors (bool);
@ -361,7 +362,6 @@ class FVTerm
void processTerminalUpdate(); void processTerminalUpdate();
static void startTerminalUpdate(); static void startTerminalUpdate();
static void finishTerminalUpdate(); static void finishTerminalUpdate();
static void flushOutputBuffer();
static void initScreenSettings(); static void initScreenSettings();
static void changeTermSizeFinished(); static void changeTermSizeFinished();
static void exitWithMessage (const FString&) static void exitWithMessage (const FString&)

View File

@ -307,6 +307,7 @@ class FWidget : public FVTerm, public FObject
bool isMenuWidget() const; bool isMenuWidget() const;
bool isVisible() const; bool isVisible() const;
bool isShown() const; bool isShown() const;
bool isHidden() const;
bool isEnabled() const; bool isEnabled() const;
bool hasVisibleCursor() const; bool hasVisibleCursor() const;
bool hasFocus() const; bool hasFocus() const;
@ -410,6 +411,7 @@ class FWidget : public FVTerm, public FObject
void insufficientSpaceAdjust(); void insufficientSpaceAdjust();
void KeyPressEvent (FKeyEvent*); void KeyPressEvent (FKeyEvent*);
void KeyDownEvent (FKeyEvent*); void KeyDownEvent (FKeyEvent*);
void emitWheelCallback (FWheelEvent*);
void setWindowFocus (bool); void setWindowFocus (bool);
FCallbackPtr getCallbackPtr (FCallback); FCallbackPtr getCallbackPtr (FCallback);
bool changeFocus (FWidget*, FWidget*, fc::FocusTypes); bool changeFocus (FWidget*, FWidget*, fc::FocusTypes);
@ -919,6 +921,10 @@ inline bool FWidget::isVisible() const
inline bool FWidget::isShown() const inline bool FWidget::isShown() const
{ return flags.shown; } { return flags.shown; }
//----------------------------------------------------------------------
inline bool FWidget::isHidden() const
{ return flags.hidden; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FWidget::isWindowWidget() const inline bool FWidget::isWindowWidget() const
{ return flags.window_widget; } { return flags.window_widget; }

View File

@ -179,6 +179,10 @@ class FWindow : public FWidget
bool zoomed{false}; bool zoomed{false};
}; };
// non-member function forward declarations
//----------------------------------------------------------------------
void closeDropDown (FWidget*, const FPoint&);
// FWindow inline functions // FWindow inline functions
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -56,6 +56,7 @@ class FPointTest : public CPPUNIT_NS::TestFixture
void additionTest(); void additionTest();
void subtractionTest(); void subtractionTest();
void referenceTest(); void referenceTest();
void moveTest();
void streamInsertionTest(); void streamInsertionTest();
void streamExtractionTest(); void streamExtractionTest();
@ -76,6 +77,7 @@ class FPointTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST (additionTest); CPPUNIT_TEST (additionTest);
CPPUNIT_TEST (subtractionTest); CPPUNIT_TEST (subtractionTest);
CPPUNIT_TEST (referenceTest); CPPUNIT_TEST (referenceTest);
CPPUNIT_TEST (moveTest);
CPPUNIT_TEST (streamInsertionTest); CPPUNIT_TEST (streamInsertionTest);
CPPUNIT_TEST (streamExtractionTest); CPPUNIT_TEST (streamExtractionTest);
@ -311,6 +313,24 @@ void FPointTest::referenceTest()
CPPUNIT_ASSERT ( p1.getY() == 4 ); 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() void FPointTest::streamInsertionTest()
{ {