finalcut/src/flistbox.cpp

1807 lines
38 KiB
C++
Raw Normal View History

// File: flistbox.cpp
// Provides: class FListBoxItem
// class FListBox
2015-05-23 13:35:12 +02:00
#include "fapp.h"
#include "flistbox.h"
#include "fscrollbar.h"
#include "fstatusbar.h"
//----------------------------------------------------------------------
// class FListBoxItem
//----------------------------------------------------------------------
// constructor and destructor
//----------------------------------------------------------------------
FListBoxItem::FListBoxItem()
2015-09-22 04:18:20 +02:00
: text()
, brackets(fc::NoBrackets)
, selected(false)
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FListBoxItem::FListBoxItem (FString& txt)
2015-09-22 04:18:20 +02:00
: text(txt)
, brackets(fc::NoBrackets)
, selected(false)
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FListBoxItem::FListBoxItem (const std::string& txt)
2015-09-22 04:18:20 +02:00
: text(txt)
, brackets(fc::NoBrackets)
, selected(false)
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FListBoxItem::FListBoxItem (const char* txt)
2015-09-22 04:18:20 +02:00
: text(txt)
, brackets(fc::NoBrackets)
, selected(false)
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
FListBoxItem::~FListBoxItem()
2015-09-22 04:18:20 +02:00
{ }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
// class FListBox
//----------------------------------------------------------------------
// constructor and destructor
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
FListBox::FListBox(FWidget* parent)
: FWidget(parent)
, data()
, vbar(0)
, hbar(0)
2015-09-22 04:18:20 +02:00
, text()
, inc_search()
, multi_select(false)
, mouse_select(false)
, drag_scroll(FListBox::noScroll)
, scroll_timer(false)
, scroll_repeat(100)
, scroll_distance(1)
2015-09-22 04:18:20 +02:00
, current(0)
, last_current(-1)
, secect_from_item(-1)
, xoffset(0)
, yoffset(0)
, last_yoffset(-1)
, nf_offset(0)
, max_line_width(0)
2015-05-23 13:35:12 +02:00
{
2015-09-22 04:18:20 +02:00
init();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FListBox::~FListBox() // destructor
{
2015-12-19 20:49:01 +01:00
delOwnTimer();
delete vbar;
delete hbar;
2015-05-23 13:35:12 +02:00
}
// private methods of FListBox
//----------------------------------------------------------------------
void FListBox::init()
{
if ( hasFocus() )
2016-01-24 14:53:09 +01:00
flags = fc::focus;
2015-05-23 13:35:12 +02:00
if ( isEnabled() )
2016-01-24 14:53:09 +01:00
flags |= fc::active;
2015-09-22 04:18:20 +02:00
nf_offset = isNewFont() ? 1 : 0;
2015-05-23 13:35:12 +02:00
setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg);
2015-05-23 13:35:12 +02:00
vbar = new FScrollbar(fc::vertical, this);
vbar->setMinimum(0);
vbar->setValue(0);
vbar->hide();
2015-05-23 13:35:12 +02:00
hbar = new FScrollbar(fc::horizontal, this);
hbar->setMinimum(0);
hbar->setValue(0);
hbar->hide();
2015-05-23 13:35:12 +02:00
setGeometry (1, 1, 5, 4, false); // initialize geometry values
vbar->addCallback
2015-05-23 13:35:12 +02:00
(
"change-value",
_METHOD_CALLBACK (this, &FListBox::cb_VBarChange)
2015-05-23 13:35:12 +02:00
);
hbar->addCallback
2015-05-23 13:35:12 +02:00
(
"change-value",
_METHOD_CALLBACK (this, &FListBox::cb_HBarChange)
2015-05-23 13:35:12 +02:00
);
}
//----------------------------------------------------------------------
void FListBox::draw()
{
bool isFocus;
if ( current < 1 )
current = 1;
updateVTerm(false);
setColor();
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(true);
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
drawBorder (1, 1, getWidth() - 1, getHeight());
else
drawBorder();
if ( isNewFont() && ! vbar->isVisible() )
2015-05-23 13:35:12 +02:00
{
setColor();
for (int y=2; y < getHeight(); y++)
2015-05-23 13:35:12 +02:00
{
printPos (getWidth(),y);
print (' '); // clear right side of the scrollbar
2015-05-23 13:35:12 +02:00
}
}
2015-05-23 13:35:12 +02:00
drawLabel();
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(false);
updateVTerm(true);
2015-05-23 13:35:12 +02:00
if ( vbar->isVisible() )
vbar->redraw();
if ( hbar->isVisible() )
hbar->redraw();
2015-05-23 13:35:12 +02:00
drawList();
2016-01-24 14:53:09 +01:00
isFocus = ((flags & fc::focus) != 0);
2015-05-23 13:35:12 +02:00
if ( isFocus && statusBar() )
{
FString msg = getStatusbarMessage();
FString curMsg = statusBar()->getMessage();
2015-05-23 13:35:12 +02:00
if ( curMsg != msg )
{
statusBar()->setMessage(msg);
statusBar()->drawMessage();
}
}
}
//----------------------------------------------------------------------
void FListBox::drawLabel()
{
FString txt;
uInt length;
if ( text.isNull() || text.isEmpty() )
return;
2015-09-22 04:18:20 +02:00
txt = " " + text + " ";
2015-05-23 13:35:12 +02:00
length = txt.getLength();
printPos (2, 1);
2015-05-23 13:35:12 +02:00
if ( isEnabled() )
setColor(wc.label_emphasis_fg, wc.label_bg);
else
setColor(wc.label_inactive_fg, wc.label_inactive_bg);
if ( length <= uInt(getWidth()-2) )
2015-05-23 13:35:12 +02:00
print (txt);
else
{
print (text.left(uInt(getWidth()-4)));
2015-05-23 13:35:12 +02:00
setColor (wc.label_ellipsis_fg, wc.label_bg);
print("..");
}
}
//----------------------------------------------------------------------
void FListBox::drawList()
{
FString element;
uInt start, end, inc_len;
bool isFocus;
if ( data.empty() || getHeight() <= 2 || getWidth() <= 4 )
2015-05-23 13:35:12 +02:00
return;
2016-01-24 14:53:09 +01:00
isFocus = ((flags & fc::focus) != 0);
2015-05-23 13:35:12 +02:00
start = 0;
end = uInt(getHeight()-2);
2015-05-23 13:35:12 +02:00
inc_len = inc_search.getLength();
if ( end > count() )
end = count();
if ( last_yoffset >= 0
&& last_yoffset == yoffset
&& last_current != current )
{
// speed up: redraw only the changed rows
2015-09-24 00:41:43 +02:00
uInt last_pos = uInt(current - yoffset) - 1;
uInt current_pos = uInt(last_current - yoffset) - 1;
2015-05-23 13:35:12 +02:00
start = std::min(last_pos, current_pos);
end = std::max(last_pos, current_pos)+1;
}
updateVTerm(false);
2015-05-23 13:35:12 +02:00
for (uInt y=start; y < end; y++)
{
printPos (2, 2 + int(y));
2015-05-23 13:35:12 +02:00
bool serach_mark = false;
2015-09-24 00:41:43 +02:00
bool lineHasBrackets = hasBrackets(int(y) + yoffset + 1);
bool isLineSelected = isSelected(int(y) + yoffset + 1);
bool isCurrentLine = bool(uInt(y) + uInt(yoffset) + 1 == uInt(current));
2015-05-23 13:35:12 +02:00
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
else
setColor (wc.selected_list_fg, wc.selected_list_bg);
}
else
{
if ( isMonochron() )
unsetBold();
else
setColor (wc.list_fg, wc.list_bg);
}
2015-07-09 23:29:51 +02:00
if ( isCurrentLine )
2015-05-23 13:35:12 +02:00
{
2015-10-23 23:57:00 +02:00
if ( isFocus && getMaxColor() < 16 )
setBold();
2015-05-23 13:35:12 +02:00
if ( isLineSelected )
{
if ( isMonochron() )
setBold();
2015-10-23 23:57:00 +02:00
else if ( isFocus )
setColor ( wc.selected_current_element_focus_fg
, wc.selected_current_element_focus_bg );
2015-05-23 13:35:12 +02:00
else
2015-09-22 04:18:20 +02:00
setColor ( wc.selected_current_element_fg
, wc.selected_current_element_bg );
setCursorPos (3, 2 + int(y)); // first character
2015-05-23 13:35:12 +02:00
}
else
{
if ( isMonochron() )
unsetBold();
2015-10-23 23:57:00 +02:00
if ( isFocus )
2015-05-23 13:35:12 +02:00
{
2015-09-22 04:18:20 +02:00
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
int b = ( lineHasBrackets ) ? 1: 0;
if ( inc_len > 0 ) // incremental search
2015-05-23 13:35:12 +02:00
{
serach_mark = true;
setCursorPos (2 + b + int(inc_len), 2 + int(y)); // last found character
2015-05-23 13:35:12 +02:00
}
else // only highlighted
setCursorPos (3 + b, 2 + int(y)); // first character
2015-05-23 13:35:12 +02:00
}
else
2015-09-22 04:18:20 +02:00
setColor ( wc.current_element_fg
, wc.current_element_bg );
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
if ( isMonochron() )
2015-10-11 21:56:16 +02:00
setReverse(false);
2015-05-23 13:35:12 +02:00
}
2015-10-23 23:57:00 +02:00
else
{
if ( isMonochron() )
setReverse(true);
2015-10-24 13:38:58 +02:00
else if ( isFocus && getMaxColor() < 16 )
unsetBold();
2015-10-23 23:57:00 +02:00
}
2015-05-23 13:35:12 +02:00
// print the entry
2015-07-09 23:29:51 +02:00
if ( isMonochron() && isCurrentLine )
print ('>');
else
print (' ');
2015-05-23 13:35:12 +02:00
if ( lineHasBrackets )
{
const wchar_t* element_str;
int full_length;
uInt len;
uInt i = 0;
uInt b = 0;
if ( xoffset == 0 )
{
b=1;
2015-05-23 13:35:12 +02:00
switch ( data[y+uInt(yoffset)].brackets )
{
case fc::NoBrackets:
break;
2015-05-23 13:35:12 +02:00
case fc::SquareBrackets:
print ('[');
break;
2015-05-23 13:35:12 +02:00
case fc::Parenthesis:
print ('(');
break;
2015-05-23 13:35:12 +02:00
case fc::CurlyBrackets:
print ('{');
break;
2015-05-23 13:35:12 +02:00
case fc::AngleBrackets:
print ('<');
break;
}
2015-05-23 13:35:12 +02:00
element = data[y+uInt(yoffset)].getText()
2015-09-22 04:18:20 +02:00
.mid ( uInt(1+xoffset)
, uInt(getWidth()-nf_offset-5) );
2015-05-23 13:35:12 +02:00
}
else
element = data[y+uInt(yoffset)].getText()
2015-09-22 04:18:20 +02:00
.mid ( uInt(xoffset)
, uInt(getWidth()-nf_offset-4) );
2015-05-23 13:35:12 +02:00
element_str = element.wc_str();
len = element.getLength();
for (; i < len; i++)
{
if ( serach_mark && i == 0 )
2015-09-22 04:18:20 +02:00
setColor ( wc.current_inc_search_element_fg
, wc.current_element_focus_bg );
2015-05-23 13:35:12 +02:00
if ( serach_mark && i == inc_len )
2015-09-22 04:18:20 +02:00
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
2015-05-23 13:35:12 +02:00
print (element_str[i]);
}
2015-05-23 13:35:12 +02:00
full_length = int(data[y+uInt(yoffset)].getText().getLength());
if ( b+i < uInt(getWidth()-nf_offset-4) && xoffset <= full_length+1 )
2015-05-23 13:35:12 +02:00
{
if ( serach_mark && i == inc_len )
2015-09-22 04:18:20 +02:00
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
2015-05-23 13:35:12 +02:00
switch ( data[y+uInt(yoffset)].brackets )
{
case fc::NoBrackets:
break;
2015-05-23 13:35:12 +02:00
case fc::SquareBrackets:
print (']');
break;
2015-05-23 13:35:12 +02:00
case fc::Parenthesis:
print (')');
break;
2015-05-23 13:35:12 +02:00
case fc::CurlyBrackets:
print ('}');
break;
2015-05-23 13:35:12 +02:00
case fc::AngleBrackets:
print ('>');
break;
}
2015-05-23 13:35:12 +02:00
i++;
}
2015-07-09 23:29:51 +02:00
if ( isMonochron() && isCurrentLine )
{
print ('<');
i++;
}
for (; b+i < uInt(getWidth()-nf_offset-3); i++)
2015-05-23 13:35:12 +02:00
print (' ');
}
else // line has no brackets
{
const wchar_t* element_str;
uInt i, len;
element = data[y+uInt(yoffset)].getText()
2015-10-10 04:01:22 +02:00
.mid ( uInt(1+xoffset)
, uInt(getWidth()-nf_offset-4) );
2015-05-23 13:35:12 +02:00
element_str = element.wc_str();
len = element.getLength();
if ( serach_mark )
2015-09-22 04:18:20 +02:00
setColor ( wc.current_inc_search_element_fg
, wc.current_element_focus_bg );
2015-05-23 13:35:12 +02:00
for (i=0; i < len; i++)
{
if ( serach_mark && i == inc_len )
2015-09-22 04:18:20 +02:00
setColor ( wc.current_element_focus_fg
, wc.current_element_focus_bg );
2015-05-23 13:35:12 +02:00
print (element_str[i]);
}
2015-07-09 23:29:51 +02:00
if ( isMonochron() && isCurrentLine )
{
print ('<');
i++;
}
for (; i < uInt(getWidth()-nf_offset-3); i++)
2015-05-23 13:35:12 +02:00
print (' ');
}
}
if ( isMonochron() ) // unset for the last element
setReverse(false);
unsetBold();
updateVTerm(true);
2015-05-23 13:35:12 +02:00
last_yoffset = yoffset;
last_current = current;
}
//----------------------------------------------------------------------
void FListBox::processClick()
{
emitCallback("clicked");
}
//----------------------------------------------------------------------
void FListBox::processSelect()
{
emitCallback("row-selected");
}
//----------------------------------------------------------------------
void FListBox::processChanged()
{
emitCallback("row-changed");
}
// protected methods of FListBox
//----------------------------------------------------------------------
void FListBox::adjustYOffset()
{
int element_count = int(count());
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
2015-05-23 13:35:12 +02:00
if ( current < yoffset )
current = yoffset;
if ( current >= yoffset + getHeight() - 1 )
yoffset = current - getHeight() + 2;
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FListBox::adjustSize()
{
int element_count;
adjustYOffset();
FWidget::adjustSize();
element_count = int(count());
vbar->setMaximum(element_count - getHeight() + 2);
vbar->setPageSize(element_count, getHeight() - 2);
vbar->setX(getWidth());
vbar->setHeight (getHeight()-2, false);
vbar->resize();
hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4);
hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4);
hbar->setY(getHeight());
hbar->setWidth (getWidth()-2, false);
hbar->resize();
2015-05-23 13:35:12 +02:00
if ( element_count < getHeight() - 1 )
vbar->hide();
2015-05-23 13:35:12 +02:00
else
vbar->setVisible();
2015-05-23 13:35:12 +02:00
if ( max_line_width < getWidth() - nf_offset - 3 )
hbar->hide();
2015-05-23 13:35:12 +02:00
else
hbar->setVisible();
2015-05-23 13:35:12 +02:00
}
// public methods of FListBox
//----------------------------------------------------------------------
void FListBox::setCurrentItem(int index)
{
int element_count;
2015-05-23 13:35:12 +02:00
if ( index == current )
return;
element_count = int(count());
2015-05-23 13:35:12 +02:00
if ( index > element_count )
current = element_count;
else if ( index < 1 )
current = 1;
else
current = index;
2015-05-23 13:35:12 +02:00
xoffset = 0;
yoffset = 0;
adjustSize();
vbar->setValue(yoffset);
2015-05-23 13:35:12 +02:00
if ( isVisible() )
redraw();
}
//----------------------------------------------------------------------
void FListBox::hide()
{
int n, size;
short fg, bg;
2015-05-23 13:35:12 +02:00
char* blank;
FWidget* parent_widget = getParentWidget();
2015-05-23 13:35:12 +02:00
FWidget::hide();
if ( parent_widget )
{
fg = parent_widget->getForegroundColor();
bg = parent_widget->getBackgroundColor();
}
else
{
fg = wc.dialog_fg;
bg = wc.dialog_bg;
}
2015-05-23 13:35:12 +02:00
setColor (fg, bg);
n = isNewFont() ? 1 : 0;
size = getWidth() + n;
if ( size < 0 )
return;
2015-05-23 13:35:12 +02:00
blank = new char[size+1];
memset(blank, ' ', uLong(size));
blank[size] = '\0';
for (int y=0; y < getHeight(); y++)
2015-05-23 13:35:12 +02:00
{
printPos (1, 1 + y);
2015-05-23 13:35:12 +02:00
print (blank);
}
2015-05-23 13:35:12 +02:00
delete[] blank;
}
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
void FListBox::showInsideBrackets ( int index
, fc::brackets_type b )
2015-05-23 13:35:12 +02:00
{
data[uInt(index-1)].brackets = b;
if ( b != fc::NoBrackets )
{
int len = int(data[uInt(index-1)].getText().getLength() + 2);
if ( len > max_line_width )
2015-05-23 13:35:12 +02:00
{
max_line_width = len;
if ( len >= getWidth() - nf_offset - 3 )
2015-05-23 13:35:12 +02:00
{
hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4);
hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4);
hbar->setValue (xoffset);
if ( ! hbar->isVisible() )
hbar->setVisible();
2015-05-23 13:35:12 +02:00
}
}
}
}
//----------------------------------------------------------------------
void FListBox::setGeometry (int x, int y, int w, int h, bool adjust)
{
FWidget::setGeometry(x, y, w, h, adjust);
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
{
vbar->setGeometry (getWidth(), 2, 2, getHeight()-2);
hbar->setGeometry (1, getHeight(), getWidth()-2, 1);
2015-05-23 13:35:12 +02:00
}
else
{
vbar->setGeometry (getWidth(), 2, 1, getHeight()-2);
hbar->setGeometry (2, getHeight(), getWidth()-2, 1);
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
bool FListBox::setEnable (bool on)
{
FWidget::setEnable(on);
if ( on )
2016-01-24 14:53:09 +01:00
flags |= fc::active;
2015-05-23 13:35:12 +02:00
else
2016-01-24 14:53:09 +01:00
flags &= ~fc::active;
2015-05-23 13:35:12 +02:00
return on;
}
//----------------------------------------------------------------------
bool FListBox::setFocus (bool on)
{
FWidget::setFocus(on);
if ( on )
{
2016-01-24 14:53:09 +01:00
flags |= fc::focus;
2015-05-23 13:35:12 +02:00
if ( statusBar() )
{
FString msg = getStatusbarMessage();
FString curMsg = statusBar()->getMessage();
2015-05-23 13:35:12 +02:00
if ( curMsg != msg )
statusBar()->setMessage(msg);
}
}
else
{
2016-01-24 14:53:09 +01:00
flags &= ~fc::focus;
2015-05-23 13:35:12 +02:00
if ( statusBar() )
statusBar()->clearMessage();
}
2015-05-23 13:35:12 +02:00
return on;
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onKeyPress (FKeyEvent* ev)
2015-05-23 13:35:12 +02:00
{
int element_count = int(count());
int current_before = current;
int xoffset_before = xoffset;
int yoffset_before = yoffset;
2015-09-20 05:44:50 +02:00
int key = ev->key();
2015-05-23 13:35:12 +02:00
switch ( key )
{
case fc::Fkey_return:
case fc::Fkey_enter:
processClick();
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_up:
current--;
2015-05-23 13:35:12 +02:00
if ( current < 1 )
current=1;
2015-05-23 13:35:12 +02:00
if ( current <= yoffset )
yoffset--;
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_down:
current++;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
2015-05-23 13:35:12 +02:00
yoffset++;
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_left:
xoffset--;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset = 0;
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_right:
xoffset++;
if ( xoffset > max_line_width - getWidth() + nf_offset + 4 )
xoffset = max_line_width - getWidth() + nf_offset + 4;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset = 0;
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_ppage:
current -= getHeight()-3;
2015-05-23 13:35:12 +02:00
if ( current < 1 )
current=1;
2015-05-23 13:35:12 +02:00
if ( current <= yoffset )
{
yoffset -= getHeight()-3;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset=0;
}
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_npage:
current += getHeight()-3;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
2015-05-23 13:35:12 +02:00
{
yoffset += getHeight()-3;
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_home:
current = 1;
yoffset = 0;
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_end:
current = element_count;
if ( current >= getHeight() - 1 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_ic: // insert key
if ( isMultiSelection() )
{
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
2015-05-23 13:35:12 +02:00
processSelect();
current++;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( current-yoffset >= getHeight() - 1 )
2015-05-23 13:35:12 +02:00
yoffset++;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
inc_search.clear();
break;
case fc::Fkey_space:
{
uInt inc_len = inc_search.getLength();
2015-05-23 13:35:12 +02:00
if ( inc_len > 0 )
{
inc_search += L' ';
bool inc_found = false;
uInt end = count();
2015-05-23 13:35:12 +02:00
for (uInt i=0; i < end; i++)
{
if ( ! inc_found
&& inc_search.toLower()
== data[i].getText().left(inc_len+1).toLower() )
{
setCurrentItem(int(i+1));
inc_found = true;
break;
}
}
2015-05-23 13:35:12 +02:00
if ( ! inc_found )
{
inc_search.remove(inc_len, 1);
2015-09-20 05:44:50 +02:00
ev->ignore();
2015-05-23 13:35:12 +02:00
}
else
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
else if ( isMultiSelection() )
{
if ( isSelected(current) )
unselectItem(current);
else
selectItem(current);
2015-05-23 13:35:12 +02:00
processSelect();
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
}
break;
case fc::Fkey_erase:
case fc::Fkey_backspace:
{
uInt inc_len = inc_search.getLength();
2015-05-23 13:35:12 +02:00
if ( inc_len > 0 )
{
inc_search.remove(inc_len-1, 1);
if ( inc_len > 1 )
{
uInt end = count();
2015-05-23 13:35:12 +02:00
for (uInt i=0; i < end; i++)
{
if ( inc_search.toLower()
== data[i].getText().left(inc_len-1).toLower() )
{
setCurrentItem(int(i+1));
break;
}
}
}
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
else
2015-09-20 05:44:50 +02:00
ev->ignore();
2015-05-23 13:35:12 +02:00
}
break;
case fc::Fkey_escape:
case fc::Fkey_escape_mintty:
if ( inc_search.getLength() > 0 )
{
inc_search.clear();
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
break;
default:
if ( key > 0x20 && key <= 0x10fff )
{
// incremental search
if ( inc_search.getLength() == 0 )
inc_search = wchar_t(key);
else
inc_search += wchar_t(key);
2015-05-23 13:35:12 +02:00
uInt inc_len = inc_search.getLength();
bool inc_found = false;
uInt end = count();
2015-05-23 13:35:12 +02:00
for (uInt i=0; i < end; i++)
{
if ( ! inc_found
&& inc_search.toLower()
== data[i].getText().left(inc_len).toLower() )
{
setCurrentItem(int(i+1));
inc_found = true;
break;
}
}
2015-05-23 13:35:12 +02:00
if ( ! inc_found )
{
inc_search.remove(inc_len-1, 1);
2015-05-23 13:35:12 +02:00
if ( inc_len == 1 )
2015-09-20 05:44:50 +02:00
ev->ignore();
2015-05-23 13:35:12 +02:00
else
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
else
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
}
else
2015-09-20 05:44:50 +02:00
ev->ignore();
2015-05-23 13:35:12 +02:00
}
if ( current_before != current )
{
processChanged();
2015-05-23 13:35:12 +02:00
if ( ! isMultiSelection() )
processSelect();
}
2015-09-20 05:44:50 +02:00
if ( ev->isAccepted() )
2015-05-23 13:35:12 +02:00
{
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() && xoffset_before != xoffset )
hbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onMouseDown (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int yoffset_before, mouse_x, mouse_y;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton
&& ev->getButton() != fc::RightButton )
2015-05-23 13:35:12 +02:00
{
return;
}
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton && ! isMultiSelection() )
2015-05-23 13:35:12 +02:00
return;
if ( ! hasFocus() )
{
FWidget* focused_widget = getFocusWidget();
2016-01-17 02:57:08 +01:00
FFocusEvent out (fc::FocusOut_Event);
2015-05-23 13:35:12 +02:00
FApplication::queueEvent(focused_widget, &out);
2015-09-22 04:18:20 +02:00
setFocus();
2015-05-23 13:35:12 +02:00
if ( focused_widget )
focused_widget->redraw();
2015-05-23 13:35:12 +02:00
if ( statusBar() )
statusBar()->drawMessage();
}
yoffset_before = yoffset;
2015-09-20 05:44:50 +02:00
mouse_x = ev->getX();
mouse_y = ev->getY();
if ( mouse_x > 1 && mouse_x < getWidth()
&& mouse_y > 1 && mouse_y < getHeight() )
2015-05-23 13:35:12 +02:00
{
current = yoffset + mouse_y - 1;
2015-05-23 13:35:12 +02:00
if ( current > int(count()) )
current = int(count());
inc_search.clear();
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton )
2015-05-23 13:35:12 +02:00
{
if ( isMultiSelection() )
{
if ( isSelected(current) )
{
mouse_select = false;
2015-05-23 13:35:12 +02:00
unselectItem(current);
}
else
{
mouse_select = true;
2015-05-23 13:35:12 +02:00
selectItem(current);
}
2015-05-23 13:35:12 +02:00
processSelect();
secect_from_item = current;
}
}
2015-05-23 13:35:12 +02:00
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onMouseUp (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
if ( drag_scroll != FListBox::noScroll )
2015-05-23 13:35:12 +02:00
{
2015-12-19 20:49:01 +01:00
delOwnTimer();
drag_scroll = FListBox::noScroll;
scroll_distance = 1;
scroll_timer = false;
2015-05-23 13:35:12 +02:00
}
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::LeftButton )
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
int mouse_x = ev->getX();
int mouse_y = ev->getY();
if ( mouse_x > 1 && mouse_x < getWidth()
&& mouse_y > 1 && mouse_y < getHeight() )
2015-05-23 13:35:12 +02:00
{
processChanged();
2015-05-23 13:35:12 +02:00
if ( ! isMultiSelection() )
processSelect();
}
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onMouseMove (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int current_before, yoffset_before, mouse_x, mouse_y;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton
&& ev->getButton() != fc::RightButton )
2015-05-23 13:35:12 +02:00
{
return;
}
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton && ! isMultiSelection() )
2015-05-23 13:35:12 +02:00
return;
current_before = current;
yoffset_before = yoffset;
2015-09-20 05:44:50 +02:00
mouse_x = ev->getX();
mouse_y = ev->getY();
2015-05-23 13:35:12 +02:00
if ( mouse_x > 1 && mouse_x < getWidth()
&& mouse_y > 1 && mouse_y < getHeight() )
2015-05-23 13:35:12 +02:00
{
current = yoffset + mouse_y - 1;
2015-05-23 13:35:12 +02:00
if ( current > int(count()) )
current = int(count());
2015-05-23 13:35:12 +02:00
inc_search.clear();
// handle multiple selections
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton
2015-05-23 13:35:12 +02:00
&& isMultiSelection()
&& current_before != current )
{
int from, to;
if ( secect_from_item > current )
{
from = current;
to = secect_from_item - 1;
}
else
{
from = secect_from_item + 1;
to = current;
}
for (int i=from; i <= to; i++)
{
if ( mouse_select )
2015-05-23 13:35:12 +02:00
{
selectItem(i);
processSelect();
}
else
{
unselectItem(i);
processSelect();
}
}
2015-05-23 13:35:12 +02:00
secect_from_item = current;
}
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
// auto-scrolling when dragging mouse outside the widget
if ( mouse_y < 2 )
{
// drag up
if ( drag_scroll != FListBox::noScroll
&& scroll_distance < getHeight()-2 )
scroll_distance++;
if ( ! scroll_timer && current > 1 )
2015-05-23 13:35:12 +02:00
{
scroll_timer = true;
addTimer(scroll_repeat);
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton )
drag_scroll = FListBox::scrollUpSelect;
2015-05-23 13:35:12 +02:00
else
drag_scroll = FListBox::scrollUp;
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
if ( current == 1 )
{
2015-12-19 20:49:01 +01:00
delOwnTimer();
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
}
}
else if ( mouse_y >= getHeight() )
2015-05-23 13:35:12 +02:00
{
// drag down
if ( drag_scroll != FListBox::noScroll
&& scroll_distance < getHeight()-2 )
scroll_distance++;
if ( ! scroll_timer && current < int(count()) )
2015-05-23 13:35:12 +02:00
{
scroll_timer = true;
addTimer(scroll_repeat);
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::RightButton )
drag_scroll = FListBox::scrollDownSelect;
2015-05-23 13:35:12 +02:00
else
drag_scroll = FListBox::scrollDown;
2015-05-23 13:35:12 +02:00
}
2015-05-23 13:35:12 +02:00
if ( current == int(count()) )
{
2015-12-19 20:49:01 +01:00
delOwnTimer();
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
}
}
else
{
// no dragging
2015-12-19 20:49:01 +01:00
delOwnTimer();
scroll_timer = false;
scroll_distance = 1;
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onMouseDoubleClick (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int mouse_x, mouse_y;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton )
2015-05-23 13:35:12 +02:00
return;
2015-09-20 05:44:50 +02:00
mouse_x = ev->getX();
mouse_y = ev->getY();
2015-05-23 13:35:12 +02:00
if ( mouse_x > 1 && mouse_x < getWidth()
&& mouse_y > 1 && mouse_y < getHeight() )
2015-05-23 13:35:12 +02:00
{
if ( yoffset + mouse_y - 1 > int(count()) )
return;
2015-05-23 13:35:12 +02:00
processClick();
}
}
//----------------------------------------------------------------------
void FListBox::onTimer (FTimerEvent*)
{
int element_count = int(count());
int current_before = current;
int yoffset_before = yoffset;
switch ( int(drag_scroll) )
2015-05-23 13:35:12 +02:00
{
case FListBox::noScroll:
return;
case FListBox::scrollUp:
case FListBox::scrollUpSelect:
if ( current_before == 1)
{
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
return;
}
current -= scroll_distance;
2015-05-23 13:35:12 +02:00
if ( current < 1 )
current=1;
2015-05-23 13:35:12 +02:00
if ( current <= yoffset )
yoffset -= scroll_distance;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset=0;
break;
case FListBox::scrollDown:
case FListBox::scrollDownSelect:
if ( current_before == element_count )
{
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
return;
}
current += scroll_distance;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
yoffset += scroll_distance;
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-09-20 05:44:50 +02:00
break;
2015-09-20 05:44:50 +02:00
default:
break;
2015-05-23 13:35:12 +02:00
}
// handle multiple selections
if ( drag_scroll == FListBox::scrollUpSelect
|| drag_scroll == FListBox::scrollDownSelect )
2015-05-23 13:35:12 +02:00
{
if ( isMultiSelection() && current_before != current )
{
int from, to;
if ( secect_from_item > current )
{
from = current;
to = secect_from_item - 1;
}
else
{
from = secect_from_item + 1;
to = current;
}
2015-05-23 13:35:12 +02:00
for (int i=from; i <= to; i++)
{
if ( mouse_select )
2015-05-23 13:35:12 +02:00
{
selectItem(i);
processSelect();
}
else
{
unselectItem(i);
processSelect();
}
}
2015-05-23 13:35:12 +02:00
secect_from_item = current;
}
}
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FListBox::onWheel (FWheelEvent* ev)
2015-05-23 13:35:12 +02:00
{
int element_count, current_before, yoffset_before, yoffset_end, wheel;
element_count = int(count());
current_before = current;
yoffset_before = yoffset;
yoffset_end = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
if ( yoffset_end < 0 )
yoffset_end = 0;
2015-09-20 05:44:50 +02:00
wheel = ev->getWheel();
2015-05-23 13:35:12 +02:00
if ( drag_scroll != FListBox::noScroll )
2015-05-23 13:35:12 +02:00
{
2015-12-19 20:49:01 +01:00
delOwnTimer();
scroll_timer = false;
scroll_distance = 1;
drag_scroll = FListBox::noScroll;
2015-05-23 13:35:12 +02:00
}
switch ( wheel )
{
2016-01-17 02:57:08 +01:00
case fc::WheelUp:
2015-05-23 13:35:12 +02:00
if ( yoffset == 0 )
break;
2015-05-23 13:35:12 +02:00
yoffset -= 4;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
{
current -= 4+yoffset;
yoffset=0;
}
else
current -= 4;
2015-05-23 13:35:12 +02:00
if ( current < 1 )
current=1;
2015-05-23 13:35:12 +02:00
inc_search.clear();
break;
2016-01-17 02:57:08 +01:00
case fc::WheelDown:
2015-05-23 13:35:12 +02:00
if ( yoffset == yoffset_end )
break;
2015-05-23 13:35:12 +02:00
yoffset += 4;
2015-05-23 13:35:12 +02:00
if ( yoffset > yoffset_end )
{
2015-09-24 00:41:43 +02:00
current += 4 - (yoffset - yoffset_end);
2015-05-23 13:35:12 +02:00
yoffset = yoffset_end;
}
else
current += 4;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
2015-05-23 13:35:12 +02:00
inc_search.clear();
break;
2015-09-20 05:44:50 +02:00
default:
break;
2015-05-23 13:35:12 +02:00
}
if ( current_before != current )
{
processChanged();
2015-05-23 13:35:12 +02:00
if ( ! isMultiSelection() )
processSelect();
}
if ( isVisible() )
drawList();
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
void FListBox::onFocusIn (FFocusEvent*)
{
if ( statusBar() )
statusBar()->drawMessage();
2015-05-23 13:35:12 +02:00
inc_search.clear();
}
//----------------------------------------------------------------------
void FListBox::onFocusOut (FFocusEvent*)
{
if ( statusBar() )
{
statusBar()->clearMessage();
statusBar()->drawMessage();
}
2015-12-19 20:49:01 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
inc_search.clear();
}
//----------------------------------------------------------------------
void FListBox::cb_VBarChange (FWidget*, void*)
{
int distance = 1;
int element_count = int(count());
int yoffset_before = yoffset;
int scrollType = vbar->getScrollType();
2015-05-23 13:35:12 +02:00
switch ( scrollType )
{
case FScrollbar::scrollPageBackward:
distance = getHeight()-2;
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepBackward:
current -= distance;
2015-05-23 13:35:12 +02:00
if ( current < 1 )
current=1;
2015-05-23 13:35:12 +02:00
if ( current <= yoffset )
yoffset -= distance;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
2015-05-23 13:35:12 +02:00
break;
case FScrollbar::scrollPageForward:
distance = getHeight()-2;
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepForward:
current += distance;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( current - yoffset >= getHeight() - 1 )
2015-05-23 13:35:12 +02:00
yoffset += distance;
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
break;
case FScrollbar::scrollJump:
{
int val = vbar->getValue();
2015-05-23 13:35:12 +02:00
if ( yoffset == val )
break;
2015-05-23 13:35:12 +02:00
int c = current - yoffset;
yoffset = val;
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
2015-05-23 13:35:12 +02:00
current = yoffset + c;
2015-05-23 13:35:12 +02:00
if ( current < yoffset )
current = yoffset;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
2015-05-23 13:35:12 +02:00
break;
}
case FScrollbar::scrollWheelUp:
{
2016-01-17 02:57:08 +01:00
FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelUp);
2015-05-23 13:35:12 +02:00
onWheel(&wheel_ev);
}
2015-09-20 05:44:50 +02:00
break;
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollWheelDown:
{
2016-01-17 02:57:08 +01:00
FWheelEvent wheel_ev (fc::MouseWheel_Event, FPoint(2,2), fc::WheelDown);
2015-05-23 13:35:12 +02:00
onWheel(&wheel_ev);
}
2015-09-20 05:44:50 +02:00
break;
default:
break;
2015-05-23 13:35:12 +02:00
}
if ( isVisible() )
drawList();
if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollPageForward )
{
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
}
//----------------------------------------------------------------------
void FListBox::cb_HBarChange (FWidget*, void*)
{
int distance = 1;
int xoffset_before = xoffset;
int xoffset_end = max_line_width - getWidth() + nf_offset + 4;
int scrollType = hbar->getScrollType();
2015-05-23 13:35:12 +02:00
switch ( scrollType )
{
case FScrollbar::scrollPageBackward:
distance = getWidth() - nf_offset - 4;
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepBackward:
xoffset -= distance;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset = 0;
break;
case FScrollbar::scrollPageForward:
distance = getWidth() - nf_offset - 4;
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepForward:
xoffset += distance;
if ( xoffset > max_line_width - getWidth() + nf_offset + 4 )
xoffset = max_line_width - getWidth() + nf_offset + 4;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset = 0;
2015-05-23 13:35:12 +02:00
break;
case FScrollbar::scrollJump:
{
int val = hbar->getValue();
2015-05-23 13:35:12 +02:00
if ( xoffset == val )
break;
2015-05-23 13:35:12 +02:00
xoffset = val;
if ( xoffset > max_line_width - getWidth() + nf_offset + 4 )
xoffset = max_line_width - getWidth() + nf_offset + 4;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset = 0;
2015-05-23 13:35:12 +02:00
break;
}
case FScrollbar::scrollWheelUp:
if ( xoffset == 0 )
break;
2015-05-23 13:35:12 +02:00
xoffset -= 4;
2015-05-23 13:35:12 +02:00
if ( xoffset < 0 )
xoffset=0;
2015-05-23 13:35:12 +02:00
break;
case FScrollbar::scrollWheelDown:
if ( xoffset == xoffset_end )
break;
2015-05-23 13:35:12 +02:00
xoffset += 4;
2015-05-23 13:35:12 +02:00
if ( xoffset > xoffset_end )
xoffset = xoffset_end;
2015-05-23 13:35:12 +02:00
break;
2015-09-20 05:44:50 +02:00
default:
break;
2015-05-23 13:35:12 +02:00
}
if ( isVisible() )
{
drawList();
updateTerminal();
flush_out();
}
if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollWheelDown )
{
hbar->setValue (xoffset);
if ( hbar->isVisible() && xoffset_before != xoffset )
hbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
flush_out();
}
}
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
void FListBox::insert ( FString item
, fc::brackets_type b
, bool s )
2015-05-23 13:35:12 +02:00
{
int len, element_count;
len = int(item.getLength());
2015-05-23 13:35:12 +02:00
if ( b )
len += 2;
if ( len > max_line_width )
2015-05-23 13:35:12 +02:00
{
max_line_width = len;
if ( len >= getWidth() - nf_offset - 3 )
2015-05-23 13:35:12 +02:00
{
hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4);
hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4);
hbar->calculateSliderValues();
if ( ! hbar->isVisible() )
hbar->setVisible();
2015-05-23 13:35:12 +02:00
}
}
FListBoxItem listItem (item);
listItem.brackets = b;
listItem.selected = s;
2015-09-24 00:41:43 +02:00
data.push_back (listItem);
2015-05-23 13:35:12 +02:00
element_count = int(count());
vbar->setMaximum(element_count - getHeight() + 2);
vbar->setPageSize(element_count, getHeight() - 2);
vbar->calculateSliderValues();
if ( ! vbar->isVisible() && element_count >= getHeight() - 1 )
vbar->setVisible();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
void FListBox::insert ( long item
, fc::brackets_type b
, bool s )
2015-05-23 13:35:12 +02:00
{
insert (FString().setNumber(item), b, s);
}
//----------------------------------------------------------------------
void FListBox::remove (int item)
{
int element_count;
if ( int(count()) < item )
return;
2015-09-24 00:41:43 +02:00
data.erase (data.begin() + item - 1);
2015-05-23 13:35:12 +02:00
element_count = int(count());
max_line_width = 0;
2015-05-23 13:35:12 +02:00
for (int i=0; i < element_count; i++)
{
int len = int(data[uInt(i)].getText().getLength());
if ( len > max_line_width )
max_line_width = len;
2015-05-23 13:35:12 +02:00
}
hbar->setMaximum(max_line_width - getWidth() + nf_offset + 4);
hbar->setPageSize(max_line_width, getWidth() - nf_offset - 4);
if ( hbar->isVisible() && max_line_width < getWidth() - nf_offset - 3 )
hbar->hide();
2015-05-23 13:35:12 +02:00
vbar->setMaximum(element_count - getHeight() + 2);
vbar->setPageSize(element_count, getHeight() - 2);
if ( vbar->isVisible() && element_count < getHeight() - 1 )
vbar->hide();
2015-05-23 13:35:12 +02:00
if ( current >= item && current > 1 )
current--;
2015-05-23 13:35:12 +02:00
if ( current > element_count )
current = element_count;
if ( yoffset > element_count - getHeight() + 2 )
yoffset = element_count - getHeight() + 2;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
}
//----------------------------------------------------------------------
void FListBox::clear()
{
int size;
char* blank;
data.clear();
current = 0;
xoffset = 0;
yoffset = 0;
max_line_width = 0;
2015-05-23 13:35:12 +02:00
last_current = -1;
last_yoffset = -1;
vbar->setMinimum(0);
vbar->setValue(0);
vbar->hide();
2015-05-23 13:35:12 +02:00
hbar->setMinimum(0);
hbar->setValue(0);
hbar->hide();
2015-05-23 13:35:12 +02:00
// clear list from screen
setColor (wc.list_fg, wc.list_bg);
size = getWidth() - 2;
if ( size < 0 )
return;
2015-05-23 13:35:12 +02:00
blank = new char[size+1];
memset(blank, ' ', uLong(size));
blank[size] = '\0';
for (int y=0; y < getHeight()-2; y++)
2015-05-23 13:35:12 +02:00
{
printPos (2, 2 + y);
2015-05-23 13:35:12 +02:00
print (blank);
}
2015-05-23 13:35:12 +02:00
delete[] blank;
}
//----------------------------------------------------------------------
void FListBox::setText (FString txt)
{
2015-09-22 04:18:20 +02:00
text = txt;
2015-05-23 13:35:12 +02:00
}