2019-12-16 11:14:24 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* fcombobox.cpp - Widget FComboBox *
|
|
|
|
* *
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
* *
|
2020-02-02 22:34:27 +01:00
|
|
|
* Copyright 2019-2020 Markus Gans *
|
2019-12-16 11:14:24 +01:00
|
|
|
* *
|
|
|
|
* 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
|
|
|
|
{
|
2020-04-13 12:40:11 +02:00
|
|
|
if ( FApplication::isQuit() )
|
2019-12-16 11:14:24 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
FWindow* parent_win{nullptr};
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
if ( const auto& parent = getParentWidget() )
|
2019-12-16 11:14:24 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
2019-12-23 03:53:32 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FComboBox::setSize (const FSize& size, bool adjust)
|
|
|
|
{
|
|
|
|
FWidget::setSize (size, adjust);
|
|
|
|
FSize input_field_size(size);
|
|
|
|
input_field_size.scaleBy(-(1 + nf), 0);
|
|
|
|
input_field.setSize (input_field_size, adjust);
|
|
|
|
}
|
|
|
|
|
2019-12-16 11:14:24 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-01-09 19:21:16 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FComboBox::setCurrentItem (std::size_t index)
|
|
|
|
{
|
|
|
|
if ( index > getCount() )
|
|
|
|
index = getCount();
|
|
|
|
else if ( index < 1 )
|
|
|
|
index = 1;
|
|
|
|
|
|
|
|
if ( index == list_window.list.currentItem() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
list_window.list.setCurrentItem(index);
|
|
|
|
input_field = list_window.list.getItem(index).getText();
|
|
|
|
input_field.redraw();
|
|
|
|
processChanged();
|
|
|
|
}
|
|
|
|
|
2019-12-16 11:14:24 +01:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
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() )
|
|
|
|
{
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t index = list_window.list.currentItem();
|
2020-01-09 19:21:16 +01:00
|
|
|
input_field = list_window.list.getItem(index).getText();
|
2019-12-16 11:14:24 +01:00
|
|
|
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);
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t w = getWidth();
|
|
|
|
const std::size_t h = ( getCount() <= max_items ) ? getCount() : max_items;
|
2019-12-16 11:14:24 +01:00
|
|
|
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:
|
2019-12-20 19:36:18 +01:00
|
|
|
case fc::Fkey_escape:
|
|
|
|
case fc::Fkey_escape_mintty:
|
2019-12-16 11:14:24 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2020-02-02 22:34:27 +01:00
|
|
|
const int mouse_x = ev->getX();
|
|
|
|
const int mouse_y = ev->getY();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
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::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() )
|
|
|
|
{
|
2020-02-02 22:34:27 +01:00
|
|
|
auto list_geometry = list_window.getTermGeometry();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
if ( list_geometry.contains(termpos) )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FComboBox::init()
|
|
|
|
{
|
|
|
|
setShadow();
|
2020-02-02 22:34:27 +01:00
|
|
|
const auto& parent_widget = getParentWidget();
|
2019-12-16 11:14:24 +01:00
|
|
|
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)
|
|
|
|
);
|
|
|
|
|
2019-12-23 14:20:31 +01:00
|
|
|
for (const auto& signal : {"row-selected", "clicked"})
|
|
|
|
{
|
|
|
|
list_window.list.addCallback
|
|
|
|
(
|
|
|
|
signal,
|
|
|
|
F_METHOD_CALLBACK (this, &FComboBox::cb_closeComboBox)
|
|
|
|
);
|
|
|
|
}
|
2019-12-16 11:14:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FComboBox::draw()
|
|
|
|
{
|
|
|
|
const auto& wc = getFWidgetColors();
|
|
|
|
|
2020-04-14 23:46:42 +02:00
|
|
|
const FColorPair button_color = [this, &wc] ()
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
2020-01-09 19:21:16 +01:00
|
|
|
std::size_t index = list_window.list.currentItem();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
2020-01-09 19:21:16 +01:00
|
|
|
if ( index > 1 )
|
|
|
|
index--;
|
2019-12-16 11:14:24 +01:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2020-01-09 19:21:16 +01:00
|
|
|
list_window.list.setCurrentItem(index);
|
|
|
|
input_field = list_window.list.getItem(index).getText();
|
2019-12-16 11:14:24 +01:00
|
|
|
input_field.redraw();
|
|
|
|
processChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
void FComboBox::onePosDown()
|
|
|
|
{
|
2020-01-09 19:21:16 +01:00
|
|
|
std::size_t index = list_window.list.currentItem();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
2020-01-09 19:21:16 +01:00
|
|
|
if ( index < getCount() )
|
|
|
|
index++;
|
2019-12-16 11:14:24 +01:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2020-01-09 19:21:16 +01:00
|
|
|
list_window.list.setCurrentItem(index);
|
|
|
|
input_field = list_window.list.getItem(index).getText();
|
2019-12-16 11:14:24 +01:00
|
|
|
input_field.redraw();
|
|
|
|
processChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-02-19 21:59:13 +01:00
|
|
|
void FComboBox::passEventToListWindow (FMouseEvent* const& ev)
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
|
|
|
// Mouse event handover to list window
|
|
|
|
|
|
|
|
const auto& t = ev->getTermPos();
|
|
|
|
const auto& p = list_window.list.termToWidgetPos(t);
|
2020-02-02 22:34:27 +01:00
|
|
|
const int b = ev->getButton();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void FComboBox::cb_setInputField (const FWidget*, const FDataPtr)
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
|
|
|
auto& list = list_window.list;
|
2020-02-02 22:34:27 +01:00
|
|
|
const std::size_t index = list.currentItem();
|
2020-01-09 19:21:16 +01:00
|
|
|
input_field = list.getItem(index).getText();
|
2019-12-16 11:14:24 +01:00
|
|
|
input_field.redraw();
|
|
|
|
processChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void FComboBox::cb_closeComboBox (const FWidget*, const FDataPtr)
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
|
|
|
hideDropDown();
|
|
|
|
processClick();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void FComboBox::cb_inputFieldSwitch (const FWidget*, const FDataPtr)
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
2020-02-02 22:34:27 +01:00
|
|
|
const auto& mouse = getFMouseControl();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2020-04-13 12:40:11 +02:00
|
|
|
void FComboBox::cb_inputFieldHandOver (const FWidget*, const FDataPtr)
|
2019-12-16 11:14:24 +01:00
|
|
|
{
|
2020-02-02 22:34:27 +01:00
|
|
|
const auto& mouse = getFMouseControl();
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
if ( ! mouse || list_window.isHidden() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
const auto& t = mouse->getPos();
|
2020-02-02 22:34:27 +01:00
|
|
|
const auto& p = list_window.list.termToWidgetPos(t);
|
|
|
|
const int b = ( mouse->isLeftButtonPressed() ) ? fc::LeftButton : 0;
|
2019-12-16 11:14:24 +01:00
|
|
|
|
|
|
|
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
|