home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
srcos2
/
vcanvas.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-14
|
20KB
|
593 lines
//===============================================================
// vCanvas - a scrolling window canvas for drawing
//
// Copyright (C) 1995-1999 Bruce E. Wampler
//
// This file is part of the V C++ GUI Framework, and is covered
// under the terms of the GNU Library General Public License,
// Version 2. This library has NO WARRANTY. See the source file
// vapp.cxx for more complete information about license terms.
//===============================================================
#include <v/vos2.h> // for OS/2 stuff
#include <v/vcanvas.h> // our header
#include <v/vwindow.h> // need to use some vwindow stuff
VCursor vCanvasPane::_currentCursor = -1; // for cursor
//================>>> vCanvasPane::vCanvasPane <<<========================
vCanvasPane::vCanvasPane(PaneType pt) : vPane(pt)
{
SysDebug(Constructor,"vCanvasPane::vCanvasPane() constructor\n")
_cpDC = 0; // no pane DC
_currentCursor = VC_Arrow;
}
//================>>> vCanvasPane::~vCanvasPane <<<========================
vCanvasPane::~vCanvasPane()
{
SysDebug(Destructor,"vCanvasPane::~vCanvasPane() destructor\n")
if (_cpDC != 0)
delete _cpDC; // free the DC
}
//==================>>> vCanvasPane::initialize <<<==========================
// pWidget is client window handle
//
void vCanvasPane::initialize(vWindow* pWindow, HWND pWidget)
{
_HScrlHwnd = 0; // no scroll bar to start
_HScrlShown = 1;
_HScrlTop = 0;
_VScrlHwnd = 0; // no scroll bar to start
_VScrlShown = 1;
_VScrlTop = 0;
// now, build the items in the widget provided
vPane::initialize(pWindow, pWidget); // initialize base class
pWindow->_canvasPane = this; // easy access to/from window
_hasFocus = 0; // we don't start out with focus
_drawWindow = pWindow->winHwnd(); // frame window handle
_drawCanvas = pWidget; // client window handle
// set the height and width of our window
RECTL rc;
// CAUTION: returned rc coords are inclusive/exclusive
WinQueryWindowRect(_drawCanvas, &rc);
_height = rc.yTop - rc.yBottom; // update the local stuff
_width = rc.xRight - rc.xLeft;
// After the drawing widget has been created, we can create
// the V DC for it to use.
CreateDC();
_parentWin->_WinHeight = _height;
_parentWin->_WinWidth = _width;
SetHScroll(_HScrlShown, 0); // initial values for scroll bar
SetVScroll(_VScrlShown, 0);
_HOn = _VOn = 0; // both start out off
_parentWin->SetWinCursor(_currentCursor);
// Now need to fake out enter focus so the first mouse
// click is ignored.
if (!_hasFocus)
{
_hasFocus = 1;
EnterFocus(); // call the virtual function
}
}
//==================>>> vCanvasPane::CreateDC <<<========================
void vCanvasPane::CreateDC(void)
{
if (!_cpDC)
_cpDC = new vCanvasPaneDC(this); // create a CanvasPaneDC
}
//====================>>> vCanvasPane::ShowPane <<<======================
void vCanvasPane::ShowPane(int OnOrOff) VCONST
{
if (OnOrOff)
{
WinSetWindowPos (_drawWindow, HWND_TOP,
0,0,0,0,
SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE);
}
else
{
WinSetWindowPos (_drawWindow, HWND_TOP,
0,0,0,0,
SWP_MINIMIZE | SWP_ACTIVATE);
}
}
//=====================>>> vCanvasPane::SetHeightWidth <<<=========================
void vCanvasPane::SetWidthHeight(int width, int height)
{
if (height <= 0 || width <= 0)
return;
// we need to compute the total height of all command and status bars
RECTL oldFrameRcl, oldClientRcl;
WinQueryWindowRect(_drawWindow, &oldFrameRcl);
WinQueryWindowRect(_drawCanvas, &oldClientRcl);
WinCalcFrameRect(_drawWindow, &oldClientRcl, FALSE);
int barHeight = (oldFrameRcl.yTop - oldFrameRcl.yBottom) -
(oldClientRcl.yTop - oldClientRcl.yBottom);
_parentWin->_WinHeight = _height = height;
_parentWin->_WinWidth = _width = width;
RECTL rcl;
rcl.xLeft = 0;
rcl.yBottom = 0;
rcl.xRight = width; // client width
rcl.yTop = height; // client height
// compute the frame size to hold desired client
WinCalcFrameRect(_drawWindow, &rcl, FALSE);
// resize the frame and subclassed procedure will fix everything else
WinSetWindowPos(_drawWindow, 0,
0, 0,
rcl.xRight - rcl.xLeft, // width
rcl.yTop - rcl.yBottom + barHeight, // height
SWP_SIZE);
}
// ************************************************************************
//---------------------- Mouse Pointer Stuff -----------------------------
// ************************************************************************
//==================>>> vCanvasPane::SetCursor <<<============================
void vCanvasPane::SetCursor(VCursor id)
{
// Set to current cursor
if (id < VC_None || id > VC_LAST)
{
SysDebug1(BadVals,"vCanvasPane::SetCursor(id=%d)\n",id)
return;
}
if (id == VC_None) // special case
UnSetCursor();
SysDebug1(WindowEvents,"vCanvasPane::SetCursor(id=%d)\n",id)
_currentCursor = id;
_parentWin->SetWinCursor(_currentCursor);
}
//===================>>> vCanvasPane::UnSetCursor <<<=========================
void vCanvasPane::UnSetCursor(void)
{
_currentCursor = CA_None;
}
// ************************************************************************
// ---------------------- Scrolling Stuff ---------------------------------
// ************************************************************************
//=======================>>> vCanvasPane::HPage <<<============================
void vCanvasPane::HPage(int Shown, int Top)
{
// This is the main way a user app gets scrolling events, and
// will usually override this guy to handle what is actually
// drawn in the canvas window.
// This should then be called to actually change the display.
SysDebug2(WindowEvents,"vCanvasPane::HPage(Shown: %d, Top: %d)\n",Shown, Top);
SetHScroll(Shown,Top);
}
//=======================>>> vCanvasPane::HScroll <<<==========================
void vCanvasPane::HScroll(int step)
{
// This is the way the user app gets step events - either page or
// single step events. The default doesn't have to do anything.
SysDebug1(WindowEvents,"vCanvasPane::HScroll(%d)\n",step);
if (step < 0)
{
if (_HScrlTop - 1 >= 0)
SetHScroll(_HScrlShown, --_HScrlTop);
}
else
{
if (_HScrlTop + 1 <= 100)
SetHScroll(_HScrlShown, ++_HScrlTop);
}
}
//=====================>>> vCanvasPane::ShowHScroll <<<=========================
void vCanvasPane::ShowHScroll(int OnOff)
{
if (OnOff) // Turn on
{
if (_HOn) // Already on
return;
_HOn = 1;
// create the scroll bars
SBCDATA sbcd;
sbcd.cb = sizeof(SBCDATA);
sbcd.sHilite = 0;
sbcd.posFirst = 0;
sbcd.posLast = 100;
sbcd.posThumb = 0;
sbcd.cVisible = 1;
sbcd.cTotal = 100;
_HScrlHwnd = WinCreateWindow(_drawWindow, // parent
WC_SCROLLBAR, // window class
NULL, // window text
SBS_HORZ, // horizontal
0,0, // position
0,0, // size
_drawWindow, // owner
HWND_TOP, // bottom Z-order
FID_HORZSCROLL, // ID
&sbcd, // class data
NULL); // no presentation params
// notify frame of changes so can resize client
WinSendMsg(_drawWindow, WM_UPDATEFRAME,
MPFROMSHORT(FCF_HORZSCROLL ), 0);
// set range to 0-100
// WinSendMsg (ScrollBar, SBM_SETSCROLLBAR,
// MPFROMSHORT(0),MPFROM2SHORT(0,100));
}
else // Turn off
{
if (!_HOn) // Already off
return;
_HOn = 0;
WinDestroyWindow (WinWindowFromID(_drawWindow, FID_HORZSCROLL));
// notify frame of changes so can resize client
WinSendMsg(_drawWindow, WM_UPDATEFRAME,
MPFROMSHORT(FCF_HORZSCROLL ), 0);
}
}
//=====================>>> vCanvasPane::ShowVScroll <<<=========================
void vCanvasPane::ShowVScroll(int OnOff)
{
if (OnOff) // Turn on
{
if (_VOn) // Already on
return;
_VOn = 1;
SBCDATA sbcd;
// set range to 0-100
sbcd.cb = sizeof(SBCDATA);
sbcd.sHilite = 0;
sbcd.posFirst = 0;
sbcd.posLast = 100;
sbcd.posThumb = 0;
sbcd.cVisible = 1;
sbcd.cTotal = 100;
_VScrlHwnd = WinCreateWindow(_drawWindow, // parent
WC_SCROLLBAR, // window class
NULL, // window text
SBS_VERT, // vertical
0,0, // position
0,0, // size
_drawWindow, // owner
HWND_TOP, // bottom Z-order
FID_VERTSCROLL, // ID
&sbcd, // class data
NULL); // no presentation params
// notify frame of changes so can resize client
WinSendMsg(_drawWindow, WM_UPDATEFRAME,
MPFROMSHORT(FCF_VERTSCROLL ), 0);
// set range to 0-100
// WinSendMsg (ScrollBar, SBM_SETSCROLLBAR,
// MPFROMSHORT(0),MPFROM2SHORT(0,100));
}
else // Turn off
{
if (!_VOn) // Already off
return;
_VOn = 0;
WinDestroyWindow (WinWindowFromID(_drawWindow, FID_VERTSCROLL));
// notify frame of changes so can resize client
WinSendMsg(_drawWindow, WM_UPDATEFRAME,
MPFROMSHORT(FCF_VERTSCROLL ), 0);
}
}
//=====================>>> vCanvasPane::GetHScroll <<<=========================
int vCanvasPane::GetHScroll(int& Shown, int& Top) VCONST // V:1.13
{
Shown = _HScrlShown; Top = _HScrlTop;
return _HOn;
}
//=====================>>> vCanvasPane::SetHScroll <<<=========================
void vCanvasPane::SetHScroll(int Shown, int Top)
{
// Make sure we are setting to valid values, and are changing things!
if (Shown < 0 || Shown > 100 || Top < 0 || Top > 100)
return;
_HScrlShown = Shown;
_HScrlTop = Top;
WinSendMsg (WinWindowFromID(_drawWindow, FID_HORZSCROLL),
SBM_SETPOS, MPFROMSHORT(Top), 0);
WinSendMsg (WinWindowFromID(_drawWindow, FID_HORZSCROLL),
SBM_SETTHUMBSIZE, MPFROM2SHORT(Shown, 100), 0);
}
//========================>>> vCanvasPane::VPage <<<===========================
void vCanvasPane::VPage(int Shown, int Top)
{
SysDebug2(WindowEvents,"vCanvasPane::VPage(Shown: %d, Top: %d)\n",Shown, Top);
SetVScroll(Shown,Top);
}
//========================>>> vCanvasPane::VScroll <<<=========================
void vCanvasPane::VScroll(int step)
{
// This is the way the user app gets step events - either page or
// single step events. Default updates the display
SysDebug1(WindowEvents,"vCanvasPane::VScroll(%d)\n",step);
if (step < 0)
{
if (_VScrlTop - 1 >= 0)
SetVScroll(_VScrlShown, --_VScrlTop);
}
else
{
if (_VScrlTop + 1 <= 100)
SetVScroll(_VScrlShown, ++_VScrlTop);
}
}
//=====================>>> vCanvasPane::GetVScroll <<<=========================
int vCanvasPane::GetVScroll(int& Shown, int& Top) VCONST // V:1.13
{
Shown = _VScrlShown; Top = _VScrlTop;
return _VOn;
}
//=====================>>> vCanvasPane::SetVScroll <<<=========================
void vCanvasPane::SetVScroll(int Shown, int Top)
{
// Make sure we are setting to valid values, and are changing things!
if (Shown < 0 || Shown > 100 || Top < 0 || Top > 100)
return;
_VScrlShown = Shown;
_VScrlTop = Top;
WinSendMsg (WinWindowFromID(_drawWindow, FID_VERTSCROLL),
SBM_SETPOS, MPFROMSHORT(Top), 0);
WinSendMsg (WinWindowFromID(_drawWindow, FID_VERTSCROLL),
SBM_SETTHUMBSIZE, MPFROM2SHORT(Shown, 100), 0);
}
//====================>>> vCanvasPane::HScrollEV <<<=======================
void vCanvasPane::HScrollEV(int code, int pos, HWND control)
{
switch (code)
{
case SB_LINERIGHT: // Right one unit
HScroll(1);
break;
case SB_LINELEFT: // Left one unit
HScroll(-1);
break;
case SB_PAGERIGHT: // Page Right - use 10
if (_HScrlTop <= 90)
{
_HScrlTop += 10;
HPage(_HScrlShown, _HScrlTop);
}
else
{
_HScrlTop = 100;
HPage(_HScrlShown, 100);
}
break;
case SB_PAGELEFT: // Page Left - use -10
if (_HScrlTop >= 10)
{
_HScrlTop -= 10;
HPage(_HScrlShown, _HScrlTop);
}
else
{
_HScrlTop = 0;
HPage(_HScrlShown, 0);
}
break;
case SB_SLIDERPOSITION: // move to position given
_HScrlTop = pos;
HPage(_HScrlShown, pos);
break;
case SB_SLIDERTRACK: // for continuous motion
_HScrlTop = pos;
HPage(_HScrlShown, pos);
break;
}
}
//====================>>> vCanvasPane::VScrollEV <<<=======================
void vCanvasPane::VScrollEV(int code, int pos, HWND control)
{
switch (code)
{
case SB_LINEDOWN: // Down one unit
VScroll(1);
break;
case SB_LINEUP: // Up one unit
VScroll(-1);
break;
case SB_PAGEDOWN: // Page Down - use 10
if (_VScrlTop <= 90)
{
_VScrlTop += 10;
VPage(_VScrlShown, _VScrlTop);
}
else
{
_VScrlTop = 100;
VPage(_VScrlShown, 100);
}
break;
case SB_PAGEUP: // Page Up - use -10
if (_VScrlTop >= 10)
{
_VScrlTop -= 10;
VPage(_VScrlShown, _VScrlTop);
}
else
{
_VScrlTop = 0;
VPage(_VScrlShown, 0);
}
break;
case SB_SLIDERPOSITION: // move to position given
_VScrlTop = pos;
VPage(_VScrlShown, pos);
break;
case SB_SLIDERTRACK: // continuous motion
_VScrlTop = pos;
VPage(_VScrlShown, pos);
break;
default:
return;
}
}
// ************************************************************************
//
// Redraw/resize/focus
//
// ************************************************************************
//=====================>>> vCanvasPane::ExposeEV <<<==========================
void vCanvasPane::ExposeEV(void)
{
SysDebug(WindowEvents,"vCanvasPane::ExposeEV()\n")
// ERRORID errorCode;
// errorCode = WinGetLastError(theApp->AppHab());
// SysDebug1(WindowEvents,"1) ExposeEV() ErrorCode = %8x\n", errorCode)
// we need to bracket the WM_PAINT with WinBeginPaint/WinEndPAint
// this will also update _cpDC->_rcl with the update Rectl
RECTL rc;
WinBeginPaint(_drawCanvas, _cpDC->handleDC(), &rc);
// _cpDC->BeginPaint();
int x = 0, y = 0, width = 0, height = 0;
// convert from OS/2 to V coord space
// CAUTION: WinQuery return rc coords are inclusive/exclusive
x = rc.xLeft ;
y = (_height -1) - rc.yTop;
height = rc.yTop - rc.yBottom;
width = rc.xRight - rc.xLeft;
_cpDC->ClearRect(x, y, width, height);
Redraw(x, y , width, height);
WinEndPaint(_cpDC->handleDC());
// _cpDC->EndPaint();
}
//=====================>>> vCanvasPane::EnterFocus <<<========================
void vCanvasPane::EnterFocus(void)
{
SysDebug(WindowEvents,"vCanvasPane::EnterFocus()\n")
}
//=====================>>> vCanvasPane::EnterEV <<<==========================
void vCanvasPane::EnterEV(void)
{
if (_hasFocus) // don't double enter focus
return;
_hasFocus = 1;
EnterFocus(); // call the virtual function
}
//======================>>> vCanvasPane::FontChanged <<<===========================
void vCanvasPane::FontChanged(VCONST vFont& vf)
{
// Called when the font is changed.
SysDebug1(WindowEvents,"vCanvasPane::FontChanged(%d)\n",vf)
}
//=====================>>> vCanvasPane::LeaveFocus <<<=======================
void vCanvasPane::LeaveFocus()
{
SysDebug(WindowEvents,"vCanvasPane::LeaveFocus()\n")
}
//=====================>>> vCanvasPane::LeaveEV <<<==========================
void vCanvasPane::LeaveEV()
{
if (!_hasFocus) // don't double leave focus
return;
_hasFocus = 0;
LeaveFocus(); // call the virtual function
}
//=====================>>> vCanvasPane::MouseDown <<<==========================
void vCanvasPane::MouseDown(int x, int y, int button)
{
// the mouse coords are in World Space since V interface is in World Space
SysDebug3(MouseEvents,"vCanvasPane::MouseDown(x:%d,y:%d,btn:%d)\n",x,y,button)
}
//=====================>>> vCanvasPane::MouseUp <<<============================
void vCanvasPane::MouseUp(int x, int y, int button)
{
// the mouse coords are in World Space since V interface is in World Space
SysDebug3(MouseEvents,"vCanvasPane::MouseUp(x:%d,y:%d,btn:%d)\n",x,y,button)
}
//=====================>>> vCanvasPane::MouseMove <<<==========================
void vCanvasPane::MouseMove(int x, int y, int button)
{
// the mouse coords are in World Space since V interface is in World Space
SysDebug3(MouseEvents,"vCanvasPane::MouseMove(x:%d,y:%d,btn:%d)\n",x,y,button)
}
//=======================>>> vCanvasPane::Redraw <<<==========================
void vCanvasPane::Redraw(int x, int y, int width, int height)
{
// Redraw in vCanvasPane is a no-op.
#ifdef vDEBUG // Don't have a SysDebug4 macro, so do it by hand
if (DebugState.WindowEvents && DebugState.System)
printf("vCanvasPane::Redraw(x=%d, y=%d, w=%d, h=%d)\n",x,y,width,height);
#endif
}
//=====================>>> vCanvasPane::Resize <<<============================
void vCanvasPane::Resize(int newW, int newH)
{
// This is the routine the user will override to intercept size changes
SysDebug2(WindowEvents,"vCanvasPane::Resize(newW:%d, newH:%d)\n",newW,newH)
}
//==================>>> vCanvasPane::ResizeEV <<<========================
void vCanvasPane::ResizeEV(int w, int h)
{
_parentWin->_WinHeight = _height = h;
_parentWin->_WinWidth = _width = w;
Resize((int)w, (int)h); // Call the virtual function
}