finalcut/src/fscrollbar.cpp

731 lines
16 KiB
C++
Raw Normal View History

// File: fscrollbar.cpp
// Provides: class FScrollbar
2015-05-23 13:35:12 +02:00
#include "fscrollbar.h"
//----------------------------------------------------------------------
// class FScrollbar
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
FScrollbar::FScrollbar(FWidget* parent)
: FWidget(parent)
, scrollType(FScrollbar::noScroll)
, thresholdReached(false)
, thresholdTime(500)
, repeatTime(10)
, SliderClickPos(-1)
, SliderClickStopPos(-1)
, currentSliderPos(-1)
, SliderPos(0)
, SliderLength(18) // = BarLength
, BarLength(18) // = length - 2
, val(0)
, min(0)
, max(99)
, steps(1)
, pageSize(0)
, length(20)
, bar_orientation(fc::vertical)
, max_color(getMaxColor())
2015-05-23 13:35:12 +02:00
{
2015-09-22 04:18:20 +02:00
// The default scrollbar orientation is vertical
width = 1;
height = length;
init();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
2015-09-22 04:18:20 +02:00
FScrollbar::FScrollbar(int o, FWidget* parent)
: FWidget(parent)
, scrollType(FScrollbar::noScroll)
, thresholdReached(false)
, thresholdTime(500)
, repeatTime(10)
, SliderClickPos(-1)
, SliderClickStopPos(-1)
, currentSliderPos(-1)
, SliderPos(0)
, SliderLength(18) // = BarLength
, BarLength(18) // = length - 2
, val(0)
, min(0)
, max(99)
, steps(1)
, pageSize(0)
, length(20)
, bar_orientation(fc::vertical)
, max_color(getMaxColor())
2015-05-23 13:35:12 +02:00
{
setOrientation (o);
2015-09-22 04:18:20 +02:00
init();
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
FScrollbar::~FScrollbar()
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
}
// private methods of FScrollbar
//----------------------------------------------------------------------
void FScrollbar::init()
{
2015-09-22 04:18:20 +02:00
setGeometry(1, 1, width, height);
2015-05-23 13:35:12 +02:00
ignore_padding = true;
unsetFocusable();
}
//----------------------------------------------------------------------
void FScrollbar::draw()
{
updateVTerm(false);
2015-05-23 13:35:12 +02:00
drawButtons();
currentSliderPos = -1;
drawBar();
updateVTerm(true);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
int FScrollbar::getClickedScrollType (int x, int y)
{
int stype;
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
if ( y == 1 )
{
stype = FScrollbar::scrollStepBackward; // decrement button
}
else if ( y >1 && y <= SliderPos+1 )
{
stype = FScrollbar::scrollPageBackward; // before slider
}
else if ( y > SliderPos+SliderLength+1 && y < height )
{
stype = FScrollbar::scrollPageForward; // after slider
}
else if ( y == height )
{
stype = FScrollbar::scrollStepForward; // increment button
}
else
stype = FScrollbar::noScroll;
}
else // horizontal
{
if ( isNewFont() )
{
if ( x == 1 || x == 2 )
{
stype = FScrollbar::scrollStepBackward; // decrement button
}
else if ( x >2 && x <= SliderPos+2 )
{
stype = FScrollbar::scrollPageBackward; // before slider
}
else if ( x > SliderPos+SliderLength+2 && x < width-1 )
{
stype = FScrollbar::scrollPageForward; // after slider
}
else if ( x == width-1 || x == width )
{
stype = FScrollbar::scrollStepForward; // increment button
}
else
stype = FScrollbar::noScroll;
}
else
{
if ( x == 1 )
{
stype = FScrollbar::scrollStepBackward; // decrement button
}
else if ( x >1 && x <= SliderPos+1 )
{
stype = FScrollbar::scrollPageBackward; // before slider
}
else if ( x > SliderPos+SliderLength+1 && x < width )
{
stype = FScrollbar::scrollPageForward; // after slider
}
else if ( x == width )
{
stype = FScrollbar::scrollStepForward; // increment button
}
else
stype = FScrollbar::noScroll;
}
}
2015-05-23 13:35:12 +02:00
return stype;
}
//----------------------------------------------------------------------
void FScrollbar::processMiddleButton (int x, int y)
{
int new_val;
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
if ( y >1 && y < height )
{
2015-09-20 05:44:50 +02:00
new_val = int( round ( float(max-min) * (y-2.0-(SliderLength/2))
2015-05-23 13:35:12 +02:00
/ float(BarLength-SliderLength) ) );
}
else
return;
}
else // horizontal
{
int nf = isNewFont() ? 1 : 0;
2015-05-23 13:35:12 +02:00
if ( x > 1+nf && x < width-nf )
{
2015-09-20 05:44:50 +02:00
new_val = int( round ( float(max-min) * (x-2.0-nf-(SliderLength/2))
2015-05-23 13:35:12 +02:00
/ float(BarLength-SliderLength) ) );
}
else
return;
}
2015-05-23 13:35:12 +02:00
if ( new_val != val )
{
setValue(new_val);
drawBar();
updateTerminal();
scrollType = FScrollbar::scrollJump;
processScroll();
}
}
//----------------------------------------------------------------------
void FScrollbar::processScroll()
{
emitCallback("change-value");
}
// public methods of FScrollbar
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FScrollbar::onMouseDown (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
&& ev->getButton() != fc::MiddleButton )
2015-05-23 13:35:12 +02:00
return;
if ( min == max )
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
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::MiddleButton )
2015-05-23 13:35:12 +02:00
{
processMiddleButton (mouse_x, mouse_y);
return;
}
// process LeftButton
scrollType = getClickedScrollType(mouse_x, mouse_y);
if ( bar_orientation == fc::vertical )
{
if ( mouse_y > SliderPos+1 && mouse_y <= SliderPos+SliderLength+1 )
SliderClickPos = mouse_y; // on slider
}
else // horizontal
{
if ( isNewFont() )
{
if ( mouse_x > SliderPos+2 && mouse_x <= SliderPos+SliderLength+2 )
SliderClickPos = mouse_x; // on slider
}
else
{
if ( mouse_x > SliderPos+1 && mouse_x <= SliderPos+SliderLength+1 )
SliderClickPos = mouse_x; // on slider
}
}
if ( SliderClickPos > 0 )
scrollType = FScrollbar::scrollJump;
if ( scrollType == FScrollbar::scrollPageBackward
|| scrollType == FScrollbar::scrollPageForward )
{
if ( bar_orientation == fc::vertical )
SliderClickStopPos = mouse_y - 2;
else
if ( isNewFont() )
SliderClickStopPos = mouse_x - 3;
else
SliderClickStopPos = mouse_x - 2;
}
else
SliderClickStopPos = -1;
if ( scrollType >= FScrollbar::scrollStepBackward
&& scrollType <= FScrollbar::scrollPageForward )
{
processScroll();
thresholdReached = false;
addTimer(thresholdTime);
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FScrollbar::onMouseUp (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton
&& ev->getButton() != fc::MiddleButton )
2015-05-23 13:35:12 +02:00
return;
SliderClickPos = -1;
if ( scrollType != FScrollbar::noScroll )
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
scrollType = FScrollbar::noScroll;
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FScrollbar::onMouseMove (FMouseEvent* ev)
2015-05-23 13:35:12 +02:00
{
int mouse_x, mouse_y, newScrollType;
2016-01-17 02:57:08 +01:00
if ( ev->getButton() != fc::LeftButton
&& ev->getButton() != fc::MiddleButton )
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
2016-01-17 02:57:08 +01:00
if ( ev->getButton() == fc::MiddleButton )
2015-05-23 13:35:12 +02:00
{
processMiddleButton (mouse_x, mouse_y);
return;
}
// process LeftButton
newScrollType = getClickedScrollType(mouse_x, mouse_y);
if ( scrollType == FScrollbar::scrollJump )
{
int new_val;
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
int dy = mouse_y - SliderClickPos;
SliderClickPos = mouse_y;
2015-09-20 05:44:50 +02:00
new_val = int( round ( float((max-min) * (SliderPos + dy))
2015-05-23 13:35:12 +02:00
/ float(BarLength-SliderLength) ) );
}
else // horizontal
{
int dx = mouse_x - SliderClickPos;
SliderClickPos = mouse_x;
2015-09-20 05:44:50 +02:00
new_val = int( round ( float((max-min) * (SliderPos + dx))
2015-05-23 13:35:12 +02:00
/ float(BarLength-SliderLength) ) );
}
2015-05-23 13:35:12 +02:00
if ( new_val != val )
{
setValue(new_val);
drawBar();
updateTerminal();
processScroll();
}
}
if ( mouse_x < 1 || mouse_x > width
|| mouse_y < 1 || mouse_y > height )
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
}
else if ( scrollType != FScrollbar::scrollJump )
{
addTimer(repeatTime);
}
if ( scrollType != newScrollType )
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
2015-09-20 05:44:50 +02:00
void FScrollbar::onWheel (FWheelEvent* ev)
2015-05-23 13:35:12 +02:00
{
2015-09-20 05:44:50 +02:00
int wheel = ev->getWheel();
2015-05-23 13:35:12 +02:00
if ( scrollType != FScrollbar::noScroll )
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
scrollType = FScrollbar::noScroll;
}
2016-01-17 02:57:08 +01:00
if ( wheel == fc::WheelUp )
2015-05-23 13:35:12 +02:00
scrollType = FScrollbar::scrollWheelUp;
2016-01-17 02:57:08 +01:00
else if ( wheel == fc::WheelDown )
2015-05-23 13:35:12 +02:00
scrollType = FScrollbar::scrollWheelDown;
processScroll();
}
//----------------------------------------------------------------------
void FScrollbar::onTimer (FTimerEvent*)
{
if ( scrollType == FScrollbar::noScroll )
return;
if ( ! thresholdReached )
{
thresholdReached = true;
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
addTimer(repeatTime);
}
if ( ( scrollType == scrollPageBackward
&& SliderPos < SliderClickStopPos )
|| ( scrollType == scrollPageForward
2015-09-24 00:41:43 +02:00
&& SliderPos+SliderLength > SliderClickStopPos ) )
2015-05-23 13:35:12 +02:00
{
2015-12-19 20:51:04 +01:00
delOwnTimer();
2015-05-23 13:35:12 +02:00
return;
}
processScroll();
}
//----------------------------------------------------------------------
void FScrollbar::resize()
{
FWidget::resize();
setOrientation (bar_orientation);
setValue (val);
calculateSliderValues();
}
//----------------------------------------------------------------------
void FScrollbar::redraw()
{
draw();
}
//----------------------------------------------------------------------
void FScrollbar::setMinimum (int minimum)
{
2015-09-22 04:18:20 +02:00
min = minimum;
2015-05-23 13:35:12 +02:00
calculateSliderValues();
}
//----------------------------------------------------------------------
void FScrollbar::setMaximum (int maximum)
{
2015-09-22 04:18:20 +02:00
max = maximum;
2015-05-23 13:35:12 +02:00
calculateSliderValues();
}
//----------------------------------------------------------------------
void FScrollbar::setRange(int minimum, int maximum)
{
2015-09-22 04:18:20 +02:00
min = minimum;
max = maximum;
2015-05-23 13:35:12 +02:00
calculateSliderValues();
}
//----------------------------------------------------------------------
void FScrollbar::setValue (int value)
{
2015-09-22 04:18:20 +02:00
val = value;
2015-05-23 13:35:12 +02:00
calculateSliderValues();
}
//----------------------------------------------------------------------
void FScrollbar::setSteps (float st)
{
if ( st <= 0 )
steps = 1;
else
steps = st;
2015-05-23 13:35:12 +02:00
if ( pageSize == 0 )
2015-09-20 05:44:50 +02:00
pageSize = int(float(max)/steps);
2015-05-23 13:35:12 +02:00
}
//----------------------------------------------------------------------
void FScrollbar::setPageSize (int document_size, int page_size)
{
if ( page_size == 0 )
{
pageSize = document_size;
2015-09-22 04:18:20 +02:00
steps = 1.0;
2015-05-23 13:35:12 +02:00
}
else
{
pageSize = page_size;
2015-09-22 04:18:20 +02:00
steps = float(float(document_size) / float(page_size));
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
void FScrollbar::calculateSliderValues()
{
if ( isNewFont() && bar_orientation == fc::horizontal )
BarLength = length - 4;
else
BarLength = length - 2;
2015-09-20 05:44:50 +02:00
SliderLength = int(float(BarLength) / steps);
2015-05-23 13:35:12 +02:00
if ( SliderLength < 1 )
SliderLength = 1;
else if ( SliderLength > BarLength )
SliderLength = BarLength;
if ( val == min )
{
SliderPos = 0;
return;
}
2015-05-23 13:35:12 +02:00
if ( val == max )
{
SliderPos = BarLength - SliderLength;
return;
}
SliderPos = int( round ( float((BarLength-SliderLength) * val)
/ float(max-min) ) );
if ( SliderPos < 0 )
SliderPos = 0;
else if ( SliderPos > BarLength - SliderLength )
SliderPos = BarLength - SliderLength;
}
//----------------------------------------------------------------------
void FScrollbar::setOrientation (int o)
{
int nf = 0;
length = (height > width) ? height : width;
if ( o == fc::vertical && bar_orientation == fc::horizontal )
{
width = 1;
height = length;
}
else if ( o == fc::horizontal && bar_orientation == fc::vertical )
{
height = 1;
width = length;
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
nf = 2;
}
SliderLength = BarLength = length-nf-2;
bar_orientation = o;
}
//----------------------------------------------------------------------
void FScrollbar::setGeometry (int x, int y, int w, int h, bool adjust)
{
FWidget::setGeometry (x, y, w, h, adjust);
int nf = 0;
length = (h > w) ? h : w;
if ( bar_orientation == fc::vertical )
{
width = isNewFont() ? 2 : 1;
height = length;
}
else // horizontal
{
height = 1;
width = length;
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
nf = 2;
}
SliderLength = BarLength = length-nf-2;
}
//----------------------------------------------------------------------
void FScrollbar::drawBar()
{
if (SliderPos != currentSliderPos)
{
int z;
updateVTerm(false);
2015-10-11 21:56:16 +02:00
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
2015-05-23 13:35:12 +02:00
for (z=1; z <= SliderPos; z++)
{
gotoxy (xpos+xmin-1, ypos+ymin-1+z);
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
print (fc::NF_border_line_left); // ⎸
2015-05-23 13:35:12 +02:00
if ( isMonochron() || max_color < 16 )
print (fc::MediumShade); // ▒
else
print (' ');
}
2015-05-23 13:35:12 +02:00
setColor (wc.scrollbar_bg, wc.scrollbar_fg);
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
for (z=1; z <= SliderLength; z++)
{
gotoxy (xpos+xmin-1, ypos+ymin-1+SliderPos+z);
if ( isNewFont() )
print (' ');
print (' ');
}
2015-05-23 13:35:12 +02:00
if ( isMonochron() )
2015-10-11 21:56:16 +02:00
setReverse(true);
2015-05-23 13:35:12 +02:00
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
2015-05-23 13:35:12 +02:00
for (z=SliderPos+SliderLength+1; z <= BarLength; z++)
{
gotoxy (xpos+xmin-1, ypos+ymin-1+z);
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
print (fc::NF_border_line_left); // ⎸
2015-05-23 13:35:12 +02:00
if ( isMonochron() || max_color < 16 )
print (fc::MediumShade);
else
print (' ');
}
}
else // horizontal
{
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
z = 0;
2015-05-23 13:35:12 +02:00
if ( isNewFont() )
gotoxy (xpos+xmin+1+z, ypos+ymin-1);
else
gotoxy (xpos+xmin+z, ypos+ymin-1);
for (; z < SliderPos; z++)
{
if ( isNewFont() )
print (fc::NF_border_line_upper); // ¯
else if ( isMonochron() || max_color < 16 )
print (fc::MediumShade); // ▒
else
print (' ');
}
2015-05-23 13:35:12 +02:00
setColor (wc.scrollbar_bg, wc.scrollbar_fg);
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
z = 0;
2015-05-23 13:35:12 +02:00
for (; z < SliderLength; z++)
print (' ');
2015-05-23 13:35:12 +02:00
if ( isMonochron() )
2015-10-11 21:56:16 +02:00
setReverse(true);
2015-05-23 13:35:12 +02:00
setColor (wc.scrollbar_fg, wc.scrollbar_bg);
z = SliderPos + SliderLength + 1;
2015-05-23 13:35:12 +02:00
for (; z <= BarLength; z++)
{
if ( isNewFont() )
print (fc::NF_border_line_upper); // ¯
else if ( isMonochron() || max_color < 16 )
print (fc::MediumShade); // ▒
else
print (' ');
}
}
2015-05-23 13:35:12 +02:00
currentSliderPos = SliderPos;
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(false);
updateVTerm(true);
2015-05-23 13:35:12 +02:00
}
}
//----------------------------------------------------------------------
void FScrollbar::drawButtons()
{
setColor (wc.scrollbar_button_fg, wc.scrollbar_button_bg);
if ( isNewFont() )
{
2015-10-11 21:56:16 +02:00
gotoxy (xpos+xmin-1, ypos+ymin-1);
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
print (fc::NF_rev_up_arrow1);
print (fc::NF_rev_up_arrow2);
gotoxy (xpos+xmin-1, ypos+ymin+length-2);
print (fc::NF_rev_down_arrow1);
print (fc::NF_rev_down_arrow2);
}
else // horizontal
{
print (fc::NF_rev_left_arrow1);
print (fc::NF_rev_left_arrow2);
gotoxy (xpos+xmin+length-3, ypos+ymin-1);
print (fc::NF_rev_right_arrow1);
print (fc::NF_rev_right_arrow2);
}
}
else
{
2015-10-11 21:56:16 +02:00
gotoxy (xpos+xmin-1, ypos+ymin-1);
if ( isMonochron() )
setReverse(true);
2015-05-23 13:35:12 +02:00
if ( bar_orientation == fc::vertical )
{
if ( isCygwinTerminal() )
print ('^');
else
print (fc::BlackUpPointingTriangle); // ▲
2015-05-23 13:35:12 +02:00
gotoxy (xpos+xmin-1, ypos+ymin+length-2);
2015-05-23 13:35:12 +02:00
if ( isCygwinTerminal() )
print ('v');
else
print (fc::BlackDownPointingTriangle); // ▼
}
else // horizontal
{
print (fc::BlackLeftPointingPointer); // ◄
gotoxy (xpos+xmin+length-2, ypos+ymin-1);
print (fc::BlackRightPointingPointer); // ►
2015-10-11 21:56:16 +02:00
2015-05-23 13:35:12 +02:00
}
2015-10-11 21:56:16 +02:00
if ( isMonochron() )
setReverse(false);
2015-05-23 13:35:12 +02:00
}
}