home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
scrolbar.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-04
|
10KB
|
357 lines
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. You are free
* to copy, modify or distribute this software as you see fit,
* and to use it for any purpose, provided this copyright
* notice and the following disclaimer are included with all
* copies.
*
* DISCLAIMER
*
* The author makes no warranties, either expressed or implied,
* with respect to this software, its quality, performance,
* merchantability, or fitness for any particular purpose. This
* software is distributed AS IS. The user of this software
* assumes all risks as to its quality and performance. In no
* event shall the author be liable for any direct, indirect or
* consequential damages, even if the author has been advised
* as to the possibility of such damages.
*
*/
#if defined(__GNUC__)
#pragma implementation
#endif
#include "ui/scrolbar.h"
#include "ui/cntroler.h"
#include "ui/interval.h"
#if defined(__MS_WINDOWS__)
#include <windows.h>
#elif defined(__X_MOTIF__)
#include <Xm/ScrollBar.h>
#endif
#if defined(__GNUC__) && __GNUC_MINOR__ >= 6
template class CL_Binding<UI_ScrollBar>;
#endif
/*------------------ ScrollBar Object ---------------------------*/
typedef CL_Binding<UI_ScrollBar> Bind;
UI_ScrollBar::UI_ScrollBar (UI_VObjCollection* p,
const UI_Rectangle& shape,
UI_ViewID id, long bstyle)
: UI_SimpleVObject (p, shape, id, bstyle), _range (0, 100)
{
_model = new CL_Interval (0,0);
_ownModel = TRUE;
Bind bind (this, &UI_ScrollBar::_RangeChanged);
_range.AddDependent (bind, 1); // Second parameter unused
_lineAmount = 1;
_pageAmount = 10;
_smoothScroll = TRUE;
_vertical = TRUE;
}
UI_ScrollBar::~UI_ScrollBar()
{
}
UI_WindowClass UI_ScrollBar::WindowClass () const
{
#if defined(__MS_WINDOWS__)
return "scrollbar";
#elif defined(__OS2__)
return WC_SCROLLBAR;
#elif defined(__X_MOTIF__)
return xmScrollBarWidgetClass;
#endif
}
bool UI_ScrollBar::MakeVisualElement ()
{
bool b = UI_SimpleVObject::MakeVisualElement ();
#if defined(__X_MOTIF__)
Arg args[1];
XtSetArg (args[0], XmNorientation,
_vertical ? XmVERTICAL : XmHORIZONTAL);
XtSetValues (_xwidget, args, 1);
#endif
return b;
}
void UI_ScrollBar::_PrivateInitialize()
{
UI_SimpleVObject::_PrivateInitialize();
#if defined(__MS_WINDOWS__)
SetScrollRange ((HWND) _handle, SB_CTL, _range.Low(), _range.High(),
TRUE);
CL_Interval& interval = *(CL_Interval*) _model;
SetScrollPos (_handle, SB_CTL, interval.Low(), TRUE);
#elif defined(__OS2__)
_RangeChanged (*this, 0); // Force an initialization of range
_ModelChanged (*this, 0); // Force initialization of model
#elif defined(__X_MOTIF__)
_RangeChanged (*this, 0); // Force an initialization of range
_ModelChanged (*this, 0); // Force initialization of model
XtAddCallback (_xwidget, XmNdragCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNincrementCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNpageIncrementCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNdecrementCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNpageDecrementCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNtoBottomCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNtoTopCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
XtAddCallback (_xwidget, XmNvalueChangedCallback,
&UI_ScrollBar::ScrollBarCallback, (XtPointer) this);
#endif
}
#if defined(__X_MOTIF__)
void UI_ScrollBar::ScrollBarCallback (Widget w, void* client, void* call)
{
UI_ScrollBar* bar = (UI_ScrollBar *) client;
UI_EventType type;
XmScrollBarCallbackStruct* cb = (XmScrollBarCallbackStruct*) call;
switch (cb->reason) {
case XmCR_DRAG:
type = Event_Scroll;
break;
case XmCR_DECREMENT:
type = Event_ScrollBackwardLine;
break;
case XmCR_INCREMENT:
type = Event_ScrollForwardLine;
break;
case XmCR_PAGE_DECREMENT:
type = Event_ScrollBackwardPage;
break;
case XmCR_PAGE_INCREMENT:
type = Event_ScrollForwardPage;
break;
case XmCR_TO_TOP:
type = Event_ScrollToBegin;
break;
case XmCR_TO_BOTTOM:
type = Event_ScrollToEnd;
break;
case XmCR_VALUE_CHANGED:
type = Event_FinishScroll;
break;
default:
CL_Error::Warning ("UI_ScrollBar callback: unknown reason");
break;
};
int val, slsize, inc, page_inc;
XmScrollBarGetValues (bar->_xwidget, &val, &slsize, &inc, &page_inc);
bar->_SetModelValue (CL_Interval (val, val+slsize-1));
UI_Event* evt = new UI_Event (type, bar, bar);
evt->param = val;
_Controller->AddEvent (evt);
}
#endif // __X_MOTIF__
bool UI_ScrollBar::HandleEvent (UI_Event* e)
{
UI_EventType type = e->Type();
if (type < Event_Scroll || type > Event_ScrollToPosition) {
return ProcessEvent (e);
}
long pos = ((CL_Interval*) _model)->Low();
switch (type) {
case Event_ScrollToBegin:
pos = _range.Low();
break;
case Event_ScrollToEnd:
pos = _range.High();
break;
case Event_ScrollForwardLine:
pos = minl (_range.High(), pos + _lineAmount);
break;
case Event_ScrollBackwardLine:
pos = maxl (_range.Low(), pos - _lineAmount);
break;
case Event_ScrollForwardPage:
pos = minl (_range.High(), pos + _pageAmount);
break;
case Event_ScrollBackwardPage:
pos = maxl (_range.Low (), pos - _pageAmount);
break;
case Event_ScrollToPosition:
case Event_Scroll:
pos = e->param;
break;
default:
break;
}
#if defined(__MS_WINDOWS__)
_SetModelValue (CL_Interval (pos, pos));
SetScrollPos (_handle, SB_CTL, pos, TRUE);
#elif defined(__OS2__)
WinSendMsg (_handle, SBM_SETPOS, (MPARAM) pos, 0);
long len = ((CL_Interval*) _model)->Length();
_SetModelValue (CL_Interval (pos, pos + len-1));
#endif
if (_clientSet.Size () == 0)
return FALSE;
if (type != Event_Scroll || _smoothScroll)
_clientSet.NotifyAll (*this);
return TRUE;
}
CL_Interval& UI_ScrollBar::Range ()
{
return _range;
}
#if defined(__X_MOTIF__)
static void _SetResources (Widget scroll, const CL_Interval& model,
const CL_Interval& range, short line, short page)
{
XmScrollBarSetValues (scroll, model.Low(), model.Length(), line, page,
FALSE);
Arg args[2];
XtSetArg (args[0] , XmNminimum, range.Low ());
XtSetArg (args[1] , XmNmaximum, range.High () + model.Length());
XtSetValues (scroll, args, 2);
XmUpdateDisplay (scroll);
}
#endif
bool UI_ScrollBar::_ModelChanged (CL_Object&, long)
{
#if defined(__MS_WINDOWS__)
if (_handle)
SetScrollPos (_handle, SB_CTL, ((CL_Interval*) _model)->Low(),
TRUE);
#elif defined(__OS2__)
if (_handle) {
CL_Interval& value = *(CL_Interval*) _model;
WinSendMsg (_handle, SBM_SETSCROLLBAR,
MPFROM2SHORT (value.Low(), value.High()),
MPFROM2SHORT (_range.Low(), _range.High()));
}
#elif defined(__X_MOTIF__)
if (_xwidget) {
CL_Interval& value = *(CL_Interval*) _model;
_SetResources (_xwidget, value, _range, _lineAmount, _pageAmount);
}
#endif
return TRUE;
}
bool UI_ScrollBar::_RangeChanged (CL_Object&, long)
{
#if defined(__MS_WINDOWS__)
if (_handle > 0)
SetScrollRange (_handle, SB_CTL, _range.Low(), _range.High(),
TRUE);
#elif defined(__OS2__)
if (_handle) {
CL_Interval& value = *(CL_Interval*) _model;
WinSendMsg (_handle, SBM_SETSCROLLBAR,
MPFROM2SHORT (value.Low(), value.High()),
MPFROM2SHORT (_range.Low(), _range.High()));
}
#elif defined(__X_MOTIF__)
if (_xwidget) {
CL_Interval& value = *(CL_Interval*) _model;
_SetResources (_xwidget, value, _range, _lineAmount, _pageAmount);
}
#endif
return TRUE;
}
/*---------------------VScrollBar------------------------------------*/
UI_VScrollBar::UI_VScrollBar
(UI_VObjCollection* p, const UI_Rectangle& shape,
UI_ViewID id, long bstyle)
: UI_ScrollBar (p, shape, id, bstyle)
{
#if defined (__MS_WINDOWS__)
if (_style == -1)
_style = WS_VISIBLE | SBS_VERT | WS_CHILD;
#elif defined (__OS2__)
_style = SBS_VERT | WS_VISIBLE;
#endif
}
/*-------------------------HScrollBar----------------------------*/
UI_HScrollBar::UI_HScrollBar
(UI_VObjCollection* p, const UI_Rectangle& shape,
UI_ViewID id, long bstyle)
: UI_ScrollBar (p, shape, id, bstyle)
{
#if defined(__MS_WINDOWS__)
if (_style == -1)
_style = WS_VISIBLE | SBS_HORZ | WS_CHILD;
#elif defined (__OS2__)
_style = SBS_HORZ | WS_VISIBLE;
#endif
}