finalcut/src/ftextview.cpp

988 lines
20 KiB
C++
Raw Normal View History

// File: ftextview.cpp
// Provides: class FTextView
2015-05-23 13:35:12 +02:00
#include "fdialog.h"
2015-05-23 13:35:12 +02:00
#include "fstatusbar.h"
#include "ftextview.h"
//----------------------------------------------------------------------
// class FTextView
//----------------------------------------------------------------------
// constructor and destructor
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
FTextView::FTextView(FWidget* parent)
: FWidget(parent)
, data()
, vbar(0)
, hbar(0)
2015-09-22 04:18:20 +02:00
, xoffset(0)
, yoffset(0)
, nf_offset(0)
, maxLineWidth(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
}
//----------------------------------------------------------------------
FTextView::~FTextView() // destructor
{
delete vbar;
delete hbar;
2015-05-23 13:35:12 +02:00
}
// public methods of FTextView
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
2017-03-17 22:59:06 +01:00
const FString FTextView::getText() const
2015-05-23 13:35:12 +02:00
{
uInt len, rows, idx;
2015-05-23 13:35:12 +02:00
if ( data.empty() )
return FString("");
2015-05-23 13:35:12 +02:00
len = 0;
rows = getRows();
2015-05-23 13:35:12 +02:00
for (uInt i = 0 ; i < rows; i++)
len += data[i].getLength() + 1;
2015-05-23 13:35:12 +02:00
FString s(len + 1);
idx = 0;
for (uInt i = 0 ; i < rows; i++)
{
const wchar_t* p = data[i].wc_str();
if ( p )
{
while ( (s[idx++] = *p++) != 0 );
s[idx - 1] = '\n';
}
else
{
s[idx++] = '\n';
}
}
s[idx - 1] = 0;
return s;
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FTextView::setGeometry (int x, int y, int w, int h, bool adjust)
2015-05-23 13:35:12 +02:00
{
// Set the text view geometry
FWidget::setGeometry(x, y, w, h, adjust);
int width = getWidth();
int height = getHeight();
if ( isNewFont() )
{
vbar->setGeometry (width, 1, 2, height - 1);
hbar->setGeometry (1, height, width - 2, 1);
}
else
{
vbar->setGeometry (width, 2, 1, height - 2);
hbar->setGeometry (2, height, width - 2, 1);
}
vbar->resize();
hbar->resize();
}
//----------------------------------------------------------------------
void FTextView::setPosition (int pos)
{
int last_line = int(getRows());
if ( pos < 0 || pos > last_line - getHeight() + 2 )
return;
yoffset = pos;
if ( isVisible() )
drawText();
vbar->setValue (yoffset);
if ( vbar->isVisible() )
vbar->drawBar();
flush_out();
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
void FTextView::setText (const FString& str)
{
clear();
insert(str, -1);
}
//----------------------------------------------------------------------
void FTextView::hide()
{
int n, size;
short fg, bg;
char* blank;
FWidget* parent_widget = getParentWidget();
FWidget::hide();
2015-05-23 13:35:12 +02:00
if ( parent_widget )
2015-05-23 13:35:12 +02:00
{
fg = parent_widget->getForegroundColor();
bg = parent_widget->getBackgroundColor();
}
else
{
fg = wc.dialog_fg;
bg = wc.dialog_bg;
}
setColor (fg, bg);
n = isNewFont() ? 1 : 0;
size = getWidth() + n;
if ( size < 0 )
return;
2017-08-12 22:55:29 +02:00
try
{
blank = new char[size + 1];
2017-08-12 22:55:29 +02:00
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
return;
}
std::memset(blank, ' ', uLong(size));
blank[size] = '\0';
for (int y = 0; y < getHeight(); y++)
{
setPrintPos (1, 1 + y);
print (blank);
2015-05-23 13:35:12 +02:00
}
delete[] blank;
2015-09-24 00:41:43 +02:00
flush_out();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FTextView::append (const FString& str)
2015-05-23 13:35:12 +02:00
{
insert(str, -1);
}
//----------------------------------------------------------------------
void FTextView::insert (const FString& str, int pos)
{
stringLines::iterator iter;
stringLines text_split;
FString s;
uLong end;
if ( pos < 0 || pos >= int(getRows()) )
pos = int(getRows());
2015-05-23 13:35:12 +02:00
if ( str.isEmpty() )
s = "\n";
else
s = FString(str).rtrim().expandTabs(getTabstop());
2015-10-11 21:56:16 +02:00
iter = data.begin();
text_split = s.split("\r\n");
end = text_split.size();
2015-10-11 21:56:16 +02:00
for (uInt i = 0; i < end; i++)
2015-05-23 13:35:12 +02:00
{
uInt len;
text_split[i] = text_split[i].removeBackspaces()
.removeDel()
.replaceControlCodes()
.rtrim();
len = text_split[i].getLength();
2015-05-23 13:35:12 +02:00
if ( len > maxLineWidth )
{
maxLineWidth = len;
if ( len > uInt(getWidth() - nf_offset - 2) )
{
hbar->setMaximum (int(maxLineWidth) - getWidth() + nf_offset + 2);
hbar->setPageSize (int(maxLineWidth), getWidth() - nf_offset - 2);
hbar->calculateSliderValues();
if ( ! hbar->isVisible() )
hbar->setVisible();
}
}
2015-05-23 13:35:12 +02:00
}
2015-10-11 21:56:16 +02:00
data.insert (iter + pos, text_split.begin(), text_split.end());
vbar->setMaximum (int(getRows()) - getHeight() + 2 - nf_offset);
vbar->setPageSize (int(getRows()), getHeight() - 2 + nf_offset);
vbar->calculateSliderValues();
2015-10-11 21:56:16 +02:00
if ( ! vbar->isVisible() && int(getRows()) >= getHeight() + nf_offset - 1 )
vbar->setVisible();
2015-05-23 13:35:12 +02:00
if ( vbar->isVisible() && int(getRows()) < getHeight() + nf_offset - 1 )
vbar->hide();
processChanged();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FTextView::replaceRange (const FString& str, int start, int end)
2015-05-23 13:35:12 +02:00
{
stringLines::iterator iter;
if ( start > end )
return;
2015-05-23 13:35:12 +02:00
if ( start < 0 || start >= int(getRows()) )
return;
2015-05-23 13:35:12 +02:00
if ( end < 0 || end >= int(getRows()) )
return;
2015-05-23 13:35:12 +02:00
iter = data.begin();
data.erase (iter + start, iter + end + 1);
2015-05-23 13:35:12 +02:00
if ( ! str.isNull() )
insert(str, start);
}
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
void FTextView::clear()
2015-05-23 13:35:12 +02:00
{
int size;
2015-05-23 13:35:12 +02:00
char* blank;
data.clear();
xoffset = 0;
yoffset = 0;
maxLineWidth = 0;
vbar->setMinimum(0);
vbar->setValue(0);
vbar->hide();
hbar->setMinimum(0);
hbar->setValue(0);
hbar->hide();
// clear list from screen
setColor();
size = getWidth() - 2;
if ( size < 0 )
return;
2017-08-12 22:55:29 +02:00
try
{
blank = new char[size + 1];
2017-08-12 22:55:29 +02:00
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
return;
}
std::memset(blank, ' ', uLong(size));
2015-05-23 13:35:12 +02:00
blank[size] = '\0';
for (int y = 0; y < getHeight() + nf_offset - 2; y++)
2015-05-23 13:35:12 +02:00
{
setPrintPos (2, 2 - nf_offset + y);
2015-05-23 13:35:12 +02:00
print (blank);
}
2015-05-23 13:35:12 +02:00
delete[] blank;
processChanged();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FTextView::onKeyPress (FKeyEvent* ev)
2015-05-23 13:35:12 +02:00
{
int last_line = int(getRows());
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_up:
if ( yoffset > 0 )
yoffset--;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_down:
if ( yoffset + getHeight() + nf_offset <= last_line + 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
break;
case fc::Fkey_right:
if ( xoffset + getWidth() - nf_offset <= int(maxLineWidth) + 1 )
2015-05-23 13:35:12 +02:00
xoffset++;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_left:
if ( xoffset > 0 )
xoffset--;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_ppage:
yoffset -= getHeight() - 2;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_npage:
if ( last_line >= getHeight() )
yoffset += getHeight() - 2;
if ( yoffset > last_line - getHeight() - nf_offset + 2 )
yoffset = last_line - getHeight() - nf_offset + 2;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_home:
yoffset = 0;
2015-09-20 05:44:50 +02:00
ev->accept();
2015-05-23 13:35:12 +02:00
break;
case fc::Fkey_end:
if ( last_line >= getHeight() )
yoffset = last_line - getHeight() - nf_offset + 2;
2015-09-20 05:44:50 +02:00
ev->accept();
break;
default:
2015-05-23 13:35:12 +02:00
break;
}
2015-09-20 05:44:50 +02:00
if ( ev->isAccepted() )
2015-05-23 13:35:12 +02:00
{
if ( isVisible() )
drawText();
vbar->setValue (yoffset);
if ( vbar->isVisible() )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() )
hbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
2015-09-24 00:41:43 +02:00
flush_out();
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FTextView::onMouseDown (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
FWidget* parent;
FDialog* dialog;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton )
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();
if ( getStatusBar() )
getStatusBar()->drawMessage();
2015-05-23 13:35:12 +02:00
}
parent = getParentWidget();
if ( parent
&& parent->isDialogWidget()
&& (dialog = static_cast<FDialog*>(parent)) != 0
&& dialog->isResizeable()
&& ! dialog->isZoomed() )
{
int b = ev->getButton();
const FPoint& tp = ev->getTermPos();
const FPoint& p = parent->termToWidgetPos(tp);
parent->setFocus();
2017-08-12 22:55:29 +02:00
try
{
FMouseEvent* _ev = new FMouseEvent (fc::MouseDown_Event, p, tp, b);
FApplication::sendEvent (parent, _ev);
delete _ev;
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
}
}
}
//----------------------------------------------------------------------
void FTextView::onMouseUp (FMouseEvent* ev)
{
FWidget* parent = getParentWidget();
FDialog* dialog;
if ( parent
&& parent->isDialogWidget()
&& (dialog = static_cast<FDialog*>(parent)) != 0
&& dialog->isResizeable()
&& ! dialog->isZoomed() )
{
int b = ev->getButton();
const FPoint& tp = ev->getTermPos();
const FPoint& p = parent->termToWidgetPos(tp);
parent->setFocus();
2017-08-12 22:55:29 +02:00
try
{
FMouseEvent* _ev = new FMouseEvent (fc::MouseUp_Event, p, tp, b);
FApplication::sendEvent (parent, _ev);
delete _ev;
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
}
}
if ( vbar->isVisible() )
vbar->redraw();
if ( hbar->isVisible() )
hbar->redraw();
}
//----------------------------------------------------------------------
void FTextView::onMouseMove (FMouseEvent* ev)
{
FWidget* parent = getParentWidget();
FDialog* dialog;
if ( parent
&& parent->isDialogWidget()
&& (dialog = static_cast<FDialog*>(parent)) != 0
&& dialog->isResizeable()
&& ! dialog->isZoomed() )
{
int b = ev->getButton();
const FPoint& tp = ev->getTermPos();
const FPoint& p = parent->termToWidgetPos(tp);
parent->setFocus();
2017-08-12 22:55:29 +02:00
try
{
FMouseEvent* _ev = new FMouseEvent (fc::MouseMove_Event, p, tp, b);
FApplication::sendEvent (parent, _ev);
delete _ev;
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
}
}
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FTextView::onWheel (FWheelEvent* ev)
2015-05-23 13:35:12 +02:00
{
int last_line = int(getRows());
2015-09-20 05:44:50 +02:00
int wheel = ev->getWheel();
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 )
yoffset=0;
2015-05-23 13:35:12 +02:00
break;
2016-01-17 02:57:08 +01:00
case fc::WheelDown:
2015-09-20 05:44:50 +02:00
{
int yoffset_end = last_line - getClientHeight();
2015-09-20 05:44:50 +02:00
if ( yoffset_end < 0 )
yoffset_end = 0;
2015-09-20 05:44:50 +02:00
if ( yoffset == yoffset_end )
break;
2015-09-20 05:44:50 +02:00
yoffset += 4;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
}
break;
default:
break;
}
if ( isVisible() )
drawText();
vbar->setValue (yoffset);
if ( vbar->isVisible() )
vbar->drawBar();
hbar->setValue (xoffset);
if ( hbar->isVisible() )
hbar->drawBar();
updateTerminal();
}
//----------------------------------------------------------------------
void FTextView::onFocusIn (FFocusEvent*)
{
if ( getStatusBar() )
getStatusBar()->drawMessage();
}
//----------------------------------------------------------------------
void FTextView::onFocusOut (FFocusEvent*)
{
if ( getStatusBar() )
{
getStatusBar()->clearMessage();
getStatusBar()->drawMessage();
}
}
// protected methods of FTextView
//----------------------------------------------------------------------
void FTextView::adjustSize()
{
FWidget::adjustSize();
int width = getWidth();
int height = getHeight();
int last_line = int(getRows());
int max_width = int(maxLineWidth);
if ( xoffset >= max_width - width - nf_offset )
xoffset = max_width - width - nf_offset - 1;
if ( xoffset < 0 )
xoffset = 0;
if ( yoffset > last_line - height - nf_offset + 2 )
yoffset = last_line - height - nf_offset + 2;
if ( yoffset < 0 )
yoffset = 0;
vbar->setMaximum (last_line - height + 2 - nf_offset);
vbar->setPageSize (last_line, height - 2 + nf_offset);
vbar->setX (width);
vbar->setHeight (height - 2 + nf_offset, false);
vbar->setValue (yoffset);
vbar->resize();
hbar->setMaximum (max_width - width + nf_offset + 2);
hbar->setPageSize (max_width, width - nf_offset - 2);
hbar->setY (height);
hbar->setWidth (width - 2, false);
hbar->setValue (xoffset);
hbar->resize();
if ( last_line < height + nf_offset - 1 )
vbar->hide();
else
vbar->setVisible();
if ( max_width < width - nf_offset - 1 )
hbar->hide();
else
hbar->setVisible();
}
// private methods of FTextView
//----------------------------------------------------------------------
void FTextView::init()
{
setForegroundColor (wc.dialog_fg);
setBackgroundColor (wc.dialog_bg);
2017-08-12 22:55:29 +02:00
try
{
vbar = new FScrollbar(fc::vertical, this);
vbar->setMinimum(0);
vbar->setValue(0);
vbar->hide();
2017-08-12 22:55:29 +02:00
hbar = new FScrollbar(fc::horizontal, this);
hbar->setMinimum(0);
hbar->setValue(0);
hbar->hide();
}
catch (const std::bad_alloc& ex)
{
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
return;
}
vbar->addCallback
(
"change-value",
F_METHOD_CALLBACK (this, &FTextView::cb_VBarChange)
);
hbar->addCallback
(
"change-value",
F_METHOD_CALLBACK (this, &FTextView::cb_HBarChange)
);
nf_offset = isNewFont() ? 1 : 0;
setTopPadding(1);
setLeftPadding(1);
setBottomPadding(1);
setRightPadding(1 + nf_offset);
}
//----------------------------------------------------------------------
void FTextView::draw()
{
FWidget* parent = getParentWidget();
bool is_text_dialog;
setColor();
if ( isMonochron() )
setReverse(true);
if ( parent
&& parent->isDialogWidget()
&& isPaddingIgnored()
&& getGeometry() == FRect ( 1
, 2
, parent->getWidth()
, parent->getHeight() - 1) )
{
is_text_dialog = true;
}
else
is_text_dialog = false;
if ( ! (is_text_dialog || isNewFont()) )
drawBorder();
if ( isMonochron() )
setReverse(false);
if ( vbar->isVisible() )
vbar->redraw();
if ( hbar->isVisible() )
hbar->redraw();
drawText();
if ( hasFocus() && getStatusBar() )
{
2017-03-26 20:40:04 +02:00
const FString& msg = getStatusbarMessage();
const FString& curMsg = getStatusBar()->getMessage();
if ( curMsg != msg )
{
getStatusBar()->setMessage(msg);
getStatusBar()->drawMessage();
}
}
setCursorPos (getWidth(), getHeight());
updateTerminal();
flush_out();
}
//----------------------------------------------------------------------
void FTextView::drawText()
{
uInt start, end;
if ( data.empty() || getHeight() <= 2 || getWidth() <= 2 )
return;
start = 0;
end = uInt(getHeight() + nf_offset - 2);
if ( end > getRows() )
end = getRows();
setColor();
if ( isMonochron() )
setReverse(true);
for (uInt y = start; y < end; y++)
{
uInt i, len;
FString line;
const wchar_t* line_str;
setPrintPos (2, 2 - nf_offset + int(y));
line = data[y + uInt(yoffset)].mid ( uInt(1 + xoffset)
, uInt(getWidth() - nf_offset - 2) );
line_str = line.wc_str();
len = line.getLength();
for (i = 0; i < len; i++)
{
wchar_t ch = line_str[i];
bool utf8 = (Encoding == fc::UTF8) ? true : false;
// only printable and 1 column per character
if ( ( (utf8 && std::iswprint(wint_t(ch)))
|| (!utf8 && ch < 256 && std::isprint(ch)) )
&& wcwidth(ch) == 1 )
{
print (ch);
2015-09-20 05:44:50 +02:00
}
else
print ('.');
}
2015-09-20 05:44:50 +02:00
for (; i < uInt(getWidth() - nf_offset - 2); i++)
print (' ');
2015-05-23 13:35:12 +02:00
}
if ( isMonochron() )
setReverse(false);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FTextView::processChanged()
2015-05-23 13:35:12 +02:00
{
emitCallback("changed");
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FTextView::cb_VBarChange (FWidget*, data_ptr)
2015-05-23 13:35:12 +02:00
{
FScrollbar::sType scrollType;
2015-05-23 13:35:12 +02:00
int distance = 1;
int last_line = int(getRows());
int yoffset_before = yoffset;
int yoffset_end = last_line - getClientHeight();
scrollType = vbar->getScrollType();
2015-05-23 13:35:12 +02:00
switch ( int(scrollType) )
2015-05-23 13:35:12 +02:00
{
case FScrollbar::noScroll:
break;
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollPageBackward:
distance = getClientHeight();
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepBackward:
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 = getClientHeight();
2015-10-01 03:48:58 +02:00
// fall through
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollStepForward:
yoffset += distance;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
if ( yoffset < 0 )
yoffset = 0;
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
yoffset = val;
if ( yoffset > yoffset_end )
yoffset = yoffset_end;
2015-05-23 13:35:12 +02:00
if ( yoffset < 0 )
yoffset = 0;
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);
break;
}
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);
break;
}
}
if ( isVisible() )
{
drawText();
updateTerminal();
}
if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollPageForward )
2015-05-23 13:35:12 +02:00
{
vbar->setValue (yoffset);
if ( vbar->isVisible() && yoffset_before != yoffset )
vbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
}
}
//----------------------------------------------------------------------
void FTextView::cb_HBarChange (FWidget*, data_ptr)
2015-05-23 13:35:12 +02:00
{
FScrollbar::sType scrollType;
2015-05-23 13:35:12 +02:00
int distance = 1;
int xoffset_before = xoffset;
int xoffset_end = int(maxLineWidth) - getClientWidth();
scrollType = hbar->getScrollType();
2015-05-23 13:35:12 +02:00
switch ( scrollType )
{
case FScrollbar::noScroll:
break;
2015-05-23 13:35:12 +02:00
case FScrollbar::scrollPageBackward:
distance = getClientWidth();
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;
2015-05-23 13:35:12 +02:00
break;
case FScrollbar::scrollPageForward:
distance = getClientWidth();
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 > int(maxLineWidth) - getClientWidth() )
xoffset = int(maxLineWidth) - getClientWidth();
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 > int(maxLineWidth) - getClientWidth() )
xoffset = int(maxLineWidth) - getClientWidth();
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;
}
if ( isVisible() )
{
drawText();
updateTerminal();
}
if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollWheelDown )
2015-05-23 13:35:12 +02:00
{
hbar->setValue (xoffset);
if ( hbar->isVisible() && xoffset_before != xoffset )
hbar->drawBar();
2015-05-23 13:35:12 +02:00
updateTerminal();
}
}