/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
// Filename : OSLIDCUS.CPP
// Description : custom slide bar
#include
#include
// ------- begin of inline function bound ---------//
inline int bound(int v, int lowerLimit, int upperLimit)
{
err_when( lowerLimit > upperLimit );
return vupperLimit ? upperLimit : v);
}
// ------- end of inline function bound ---------//
// ------- begin of function SlideBar::init_scroll ---------//
void SlideBar::init_scroll(short x1, short y1, short x2, short y2, int viewSize, SlideBarFP dispFunc)
{
scrn_x1 = x1;
scrn_y1 = y1;
scrn_x2 = x2;
scrn_y2 = y2;
scrn_bar_width = 0;
scroll_type = 1;
view_size = viewSize;
disp_func = dispFunc;
drag_flag = 0;
}
// ------- end of function SlideBar::init_scroll ---------//
// ------- begin of function SlideBar::init_slide ---------//
// set view_size to 0
void SlideBar::init_slide(short x1, short y1, short x2, short y2, short barWidth, SlideBarFP dispFunc)
{
scrn_x1 = x1;
scrn_y1 = y1;
scrn_x2 = x2;
scrn_y2 = y2;
scrn_bar_width = barWidth;
scroll_type = 0;
view_size = 0;
disp_func = dispFunc;
drag_flag = 0;
}
// ------- end of function SlideBar::init_scroll ---------//
void SlideBar::set(int minRecno, int maxRecno, int viewRecno)
{
min_recno = minRecno;
max_recno = maxRecno;
view_recno = viewRecno;
// empty if (max_recno - min_recno + scroll_type == 0)
err_when( max_recno - min_recno + scroll_type < 0);
}
int SlideBar::set_view_recno(int viewRecno)
{
view_recno = viewRecno;
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
return view_recno;
}
void SlideBar::set_min_recno(int minRecno)
{
min_recno = minRecno;
err_when( max_recno - min_recno + scroll_type < 0);
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
}
void SlideBar::set_max_recno(int maxRecno)
{
max_recno = maxRecno;
err_when( max_recno - min_recno + scroll_type < 0);
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
}
int SlideBar::is_empty()
{
return max_recno - min_recno + scroll_type <= 0;
}
// [int] disablePaint : don't call paint (default = 0)
// return 2 if the view_recno does not change
int SlideBar::detect()
{
int retValue = 0;
if( !drag_flag )
{
short rectLeft = rect_left();
short rectRight = rect_right();
if( mouse.single_click(scrn_x1, scrn_y1, scrn_x2, scrn_y2) )
{
short clickX = mouse.click_x();
if( clickX >= rectLeft && clickX <= rectRight )
{
drag_flag = 1;
drag_cur_x = clickX;
drag_rect_left = rectLeft;
drag_last_view_recno = view_recno;
retValue = 2;
}
else
{
// suppose click position will be the center of the button
short newScrollButtonX1 = clickX - (rectRight - rectLeft)/2;
view_recno = calc_view_recno(newScrollButtonX1);
drag_flag = 1;
drag_cur_x = clickX;
drag_rect_left = rect_left(); // rect_left() != rectLeft
drag_last_view_recno = view_recno;
}
retValue = 1;
}
}
else
{
// detect draggin on the scroll bar, don't detect any other buttons
if( !mouse.left_press )
{
drag_flag = 0;
}
int oldValue = view_recno;
int dragX = mouse.cur_x;
int newScrollButtonX1 = dragX - drag_cur_x + drag_rect_left;
// control the boundary of scrollButtonY1
drag_last_view_recno = view_recno;
view_recno = calc_view_recno(newScrollButtonX1);
retValue = drag_last_view_recno == view_recno ? 2 : 1;
}
if( retValue == 1 )
paint();
return retValue;
}
void SlideBar::paint()
{
(*disp_func)(this, 1);
}
void SlideBar::paint(int newViewRecno)
{
set_view_recno(newViewRecno);
paint();
//view_recno = bound(newViewRecno, min_recno, max_recno);
//(*disp_func)(this, 1);
}
// instruction for disp_func
//
// for scroll bar style,
// draw a rectangle from rect_left() to rect_right()
// display from min_recno to max_recno
//
// for slider style,
// draw the slide button at (rect_left(), scrn_y2)
short SlideBar::rect_left()
{
err_when( view_recno < min_recno );
// err_when( view_recno > max_view_recno() );
if( is_empty() )
return scrn_x1; // empty
else
return bound( scrn_x1 + (view_recno-min_recno)*(scrn_x2-scrn_x1+1-scrn_bar_width)/(max_recno-min_recno+scroll_type),
scrn_x1, scrn_x2 );
}
short SlideBar::rect_right()
{
// slide bar style need not call rect_right(), it should be rect_left() + scrn_bar_width - 1
// as view_size = 0
err_when( view_recno < min_recno );
// err_when( view_recno > max_view_recno() );
if( is_empty() )
return scrn_x2; // empty
else
return bound( scrn_x1+scrn_bar_width-1 + (view_recno+view_size-min_recno)*(scrn_x2-scrn_x1+1-scrn_bar_width)/(max_recno-min_recno+scroll_type),
scrn_x1, scrn_x2 );
}
// reverse function, pass the proposed rect_left to return the corresponding view_recno
int SlideBar::calc_view_recno(short scrnX)
{
int nomin = (scrnX-scrn_x1)*(max_recno-min_recno+scroll_type);
int demon = (scrn_x2-scrn_x1+1-scrn_bar_width);
int roundDivision = (2*nomin+demon) / demon / 2;
return bound( min_recno + roundDivision, min_recno, max_view_recno() );
}
int SlideBar::max_view_recno()
{
if( is_empty() )
return min_recno;
else
return bound( max_recno - view_size + scroll_type, min_recno, max_recno);
}
// .....................................................//
// ------- begin of function SlideVBar::init_scroll ---------//
void SlideVBar::init_scroll(short x1, short y1, short x2, short y2, int viewSize, SlideVBarFP dispFunc)
{
scrn_x1 = x1;
scrn_y1 = y1;
scrn_x2 = x2;
scrn_y2 = y2;
scrn_bar_height = 0;
scroll_type = 1;
view_size = viewSize;
disp_func = dispFunc;
drag_flag = 0;
}
// ------- end of function SlideVBar::init_scroll ---------//
// ------- begin of function SlideVBar::init_slide ---------//
// set view_size to 0
void SlideVBar::init_slide(short x1, short y1, short x2, short y2, short barHeight, SlideVBarFP dispFunc)
{
scrn_x1 = x1;
scrn_y1 = y1;
scrn_x2 = x2;
scrn_y2 = y2;
scrn_bar_height = barHeight;
scroll_type = 0;
view_size = 0;
disp_func = dispFunc;
drag_flag = 0;
}
// ------- end of function SlideVBar::init_scroll ---------//
void SlideVBar::set(int minRecno, int maxRecno, int viewRecno)
{
min_recno = minRecno;
max_recno = maxRecno;
view_recno = viewRecno;
// empty if (max_recno - min_recno + scroll_type == 0)
err_when( max_recno - min_recno + scroll_type < 0);
}
int SlideVBar::set_view_recno(int viewRecno)
{
view_recno = viewRecno;
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
return view_recno;
}
void SlideVBar::set_min_recno(int minRecno)
{
min_recno = minRecno;
err_when( max_recno - min_recno + scroll_type < 0);
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
}
void SlideVBar::set_max_recno(int maxRecno)
{
max_recno = maxRecno;
err_when( max_recno - min_recno + scroll_type < 0);
if( view_recno > max_recno - view_size + scroll_type )
view_recno = max_recno - view_size + scroll_type;
if( view_recno < min_recno )
view_recno = min_recno;
}
int SlideVBar::is_empty()
{
return max_recno - min_recno + scroll_type <= 0;
}
// [int] disablePaint : don't call paint (default = 0)
// return 2 if the view_recno does not change
int SlideVBar::detect()
{
int retValue = 0;
if( !drag_flag )
{
short rectTop = rect_top();
short rectBottom = rect_bottom();
if( mouse.single_click(scrn_x1, scrn_y1, scrn_x2, scrn_y2) )
{
short clickY = mouse.click_y();
if( clickY >= rectTop && clickY <= rectBottom )
{
drag_flag = 1;
drag_cur_y = clickY;
drag_rect_top = rectTop;
drag_last_view_recno = view_recno;
retValue = 2;
}
else
{
// suppose click position will be the center of the button
short newScrollButtonY1 = clickY - (rectBottom - rectTop)/2;
view_recno = calc_view_recno(newScrollButtonY1);
drag_flag = 1;
drag_cur_y = clickY;
drag_rect_top = rect_top(); // rect_top() != rectTop
drag_last_view_recno = view_recno;
}
retValue = 1;
}
}
else
{
// detect draggin on the scroll bar, don't detect any other buttons
if( !mouse.left_press )
{
drag_flag = 0;
}
int oldValue = view_recno;
int dragY = mouse.cur_y;
int newScrollButtonY1 = dragY - drag_cur_y + drag_rect_top;
// control the boundary of scrollButtonY1
drag_last_view_recno = view_recno;
view_recno = calc_view_recno(newScrollButtonY1);
retValue = drag_last_view_recno == view_recno ? 2 : 1;
}
if( retValue == 1 )
paint();
return retValue;
}
void SlideVBar::paint()
{
(*disp_func)(this, 1);
}
void SlideVBar::paint(int newViewRecno)
{
set_view_recno(newViewRecno);
paint();
//view_recno = bound(newViewRecno, min_recno, max_recno);
//(*disp_func)(this, 1);
}
// instruction for disp_func
//
// for scroll bar style,
// draw a rectangle from rect_top() to rect_bottom()
// display from min_recno to max_recno
//
// for slider style,
// draw the slide button at (rect_top(), scrn_y2)
short SlideVBar::rect_top()
{
err_when( view_recno < min_recno );
// err_when( view_recno > max_view_recno() );
if( is_empty() )
return scrn_y1; // empty
else
return bound( scrn_y1 + (view_recno-min_recno)*(scrn_y2-scrn_y1+1-scrn_bar_height)/(max_recno-min_recno+scroll_type),
scrn_y1, scrn_y2 );
}
short SlideVBar::rect_bottom()
{
// slide bar style need not call rect_bottom(), it should be rect_top() + scrn_bar_height - 1
// as view_size = 0
err_when( view_recno < min_recno );
// err_when( view_recno > max_view_recno() );
if( is_empty() )
return scrn_y2; // empty
else
return bound( scrn_y1+scrn_bar_height-1 + (view_recno+view_size-min_recno)*(scrn_y2-scrn_y1+1-scrn_bar_height)/(max_recno-min_recno+scroll_type),
scrn_y1, scrn_y2 );
}
// reverse function, pass the proposed rect_top to return the corresponding view_recno
int SlideVBar::calc_view_recno(short scrnY)
{
int nomin = (scrnY-scrn_y1)*(max_recno-min_recno+scroll_type);
int demon = scrn_y2-scrn_y1+1-scrn_bar_height;
int roundDivision = (2*nomin+demon) / demon / 2;
return bound( min_recno + roundDivision, min_recno, max_view_recno() );
}
int SlideVBar::max_view_recno()
{
if( is_empty() )
return min_recno; // empty
else
return bound( max_recno - view_size + scroll_type, min_recno, max_recno);
}