mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-22 13:20:05 +00:00
Initial Commit of CyanWorlds.com Engine Open Source Client/Plugin
This commit is contained in:
@ -0,0 +1,680 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
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 3 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDetailCurveCtrl Class Functions //
|
||||
// Custom Win32 Control class for drawing the detail map opacity curve so //
|
||||
// the artists can figure out what the hell is going on. //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
// To use: //
|
||||
// 1. Create a new plDetailCurveCtrl, giving it a parent window and a //
|
||||
// client rect. //
|
||||
// 2. Set the start and end percentages, along with the start and end //
|
||||
// opacities. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 10.1.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plDetailCurveCtrl.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
//// Static Stuff /////////////////////////////////////////////////////////////
|
||||
|
||||
int plDetailCurveCtrl::fClassRefCnt = 0;
|
||||
HINSTANCE plDetailCurveCtrl::fInstance = NULL;
|
||||
HBITMAP plDetailCurveCtrl::fBgndImage = NULL;
|
||||
HFONT plDetailCurveCtrl::fFont = NULL;
|
||||
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
HBITMAP plDetailCurveCtrl::fBgndImage2 = NULL;
|
||||
bool plDetailCurveCtrl::fXAsMipmapLevel = false;
|
||||
#endif
|
||||
|
||||
const char gCtrlClassName[] = "DetailCurveClass";
|
||||
|
||||
#define kHiResStep 0.01f
|
||||
|
||||
|
||||
void plDetailCurveCtrl::IRegisterCtrl( HINSTANCE instance )
|
||||
{
|
||||
if( fClassRefCnt == 0 )
|
||||
{
|
||||
fInstance = instance;
|
||||
|
||||
WNDCLASSEX clInfo;
|
||||
|
||||
memset( &clInfo, 0, sizeof( clInfo ) );
|
||||
clInfo.cbSize = sizeof( clInfo );
|
||||
clInfo.style = CS_OWNDC | CS_NOCLOSE;
|
||||
clInfo.lpfnWndProc = (WNDPROC)IWndProc;
|
||||
clInfo.cbClsExtra = 0;
|
||||
clInfo.cbWndExtra = 0;
|
||||
clInfo.hInstance = fInstance;
|
||||
clInfo.hIcon = NULL;
|
||||
clInfo.hCursor = LoadCursor( NULL, IDC_CROSS );
|
||||
clInfo.hbrBackground = NULL;
|
||||
clInfo.lpszMenuName = NULL;
|
||||
clInfo.lpszClassName = gCtrlClassName;
|
||||
clInfo.hIconSm = NULL;
|
||||
|
||||
RegisterClassEx( &clInfo );
|
||||
|
||||
fBgndImage = (HBITMAP)LoadImage( fInstance, MAKEINTRESOURCE( IDB_DETAILBGND ), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
fBgndImage2 = (HBITMAP)LoadImage( fInstance, MAKEINTRESOURCE( IDB_DETAILBGND2 ), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
|
||||
#endif
|
||||
|
||||
HDC hDC = GetDC( NULL );
|
||||
fFont = CreateFont( -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY ), 72 ), 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial" );
|
||||
ReleaseDC( NULL, hDC );
|
||||
}
|
||||
|
||||
fClassRefCnt++;
|
||||
}
|
||||
|
||||
void plDetailCurveCtrl::IUnregisterCtrl( void )
|
||||
{
|
||||
fClassRefCnt--;
|
||||
if( fClassRefCnt == 0 )
|
||||
{
|
||||
UnregisterClass( gCtrlClassName, fInstance );
|
||||
if( fFont != NULL )
|
||||
DeleteObject( fFont );
|
||||
}
|
||||
}
|
||||
|
||||
//// Constructor & Destructor /////////////////////////////////////////////////
|
||||
|
||||
plDetailCurveCtrl::plDetailCurveCtrl( HWND parentWnd, WPARAM id, RECT *clientRect, HINSTANCE instance )
|
||||
{
|
||||
// Class init
|
||||
if( instance == NULL )
|
||||
instance = (HINSTANCE)GetWindowLong( parentWnd, GWL_HINSTANCE );
|
||||
IRegisterCtrl( instance );
|
||||
|
||||
// Per-object init
|
||||
fDblDC = NULL;
|
||||
fDblBitmap = NULL;
|
||||
fStartPercent = 0;
|
||||
fStartOpac = 0;
|
||||
fEndPercent = 1.f;
|
||||
fEndOpac = 1.f;
|
||||
fNumLevels = 8;
|
||||
fDraggingStart = fDraggingEnd = false;
|
||||
fCanDragStart = fCanDragEnd = false;
|
||||
|
||||
// Note: we create originally as disabled since the default detail setting is disabled.
|
||||
// The MAX Update stuff should change this if necessary after we're created
|
||||
fHWnd = ::CreateWindowEx( WS_EX_CLIENTEDGE, gCtrlClassName, "Detail Curve", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_DISABLED,
|
||||
clientRect->left, clientRect->top, clientRect->right - clientRect->left,
|
||||
clientRect->bottom - clientRect->top,
|
||||
parentWnd, (HMENU)id, instance, 0 );
|
||||
if( fHWnd == NULL )
|
||||
return;
|
||||
|
||||
SetWindowLong( fHWnd, GWL_USERDATA, (LONG)this );
|
||||
}
|
||||
|
||||
plDetailCurveCtrl::~plDetailCurveCtrl()
|
||||
{
|
||||
if( fDblDC != NULL )
|
||||
{
|
||||
SelectObject( fDblDC, (HBITMAP)NULL );
|
||||
DeleteObject( fDblBitmap );
|
||||
DeleteDC( fDblDC );
|
||||
}
|
||||
|
||||
if( fWhiteBrush != NULL )
|
||||
DeleteObject( fWhiteBrush );
|
||||
if( fBluePen != NULL )
|
||||
DeleteObject( fBluePen );
|
||||
if( fLiteBluePen != NULL )
|
||||
DeleteObject( fLiteBluePen );
|
||||
if( fBlueBrush != NULL )
|
||||
DeleteObject( fBlueBrush );
|
||||
|
||||
// DestroyWindow( fHWnd );
|
||||
IUnregisterCtrl();
|
||||
}
|
||||
|
||||
//// IInitDblBuffer ///////////////////////////////////////////////////////////
|
||||
// Note: For some strange reason, grabbing the HDC of the window doesn't do
|
||||
// any good, 'cause it's black-and-white (right, THAT makes sense). Grabbing
|
||||
// the desktop DC works, however.
|
||||
|
||||
void plDetailCurveCtrl::IInitDblBuffer( void )
|
||||
{
|
||||
if( fDblDC == NULL )
|
||||
{
|
||||
int width, height;
|
||||
RECT r;
|
||||
HDC desk = GetDC( NULL );
|
||||
|
||||
GetClientRect( fHWnd, &r );
|
||||
width = r.right - r.left;
|
||||
height = r.bottom - r.top;
|
||||
|
||||
fDblDC = CreateCompatibleDC( desk );
|
||||
fDblBitmap = CreateCompatibleBitmap( desk/*fDblDC*/, width, height );
|
||||
SelectObject( fDblDC, fDblBitmap );
|
||||
ReleaseDC( NULL, desk );
|
||||
|
||||
fWhiteBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
|
||||
fBluePen = CreatePen( PS_SOLID, 1, RGB( 0, 0, 255 ) );
|
||||
fLiteBluePen = CreatePen( PS_SOLID, 1, RGB( 127, 127, 255 ) );
|
||||
fBlueBrush = CreateSolidBrush( RGB( 0, 0, 255 ) );
|
||||
|
||||
IRefreshDblBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
//// IRefreshDblBuffer ////////////////////////////////////////////////////////
|
||||
|
||||
void plDetailCurveCtrl::IRefreshDblBuffer( void )
|
||||
{
|
||||
HDC hBgndDC;
|
||||
RECT clientRect, r;
|
||||
SIZE bgndSize;
|
||||
int width, height, x, y;
|
||||
HPEN oldPen;
|
||||
BITMAPINFO bmpInfo;
|
||||
POINT pt1, pt2;
|
||||
|
||||
|
||||
IInitDblBuffer();
|
||||
|
||||
GetClientRect( fHWnd, &clientRect );
|
||||
width = clientRect.right - clientRect.left;
|
||||
height = clientRect.bottom - clientRect.top;
|
||||
|
||||
if( fDblBitmap != NULL )
|
||||
{
|
||||
FillRect( fDblDC, &clientRect, fWhiteBrush );
|
||||
|
||||
if( fBgndImage != NULL )
|
||||
{
|
||||
|
||||
// Draw bgnd
|
||||
hBgndDC = CreateCompatibleDC( fDblDC );
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
SelectObject( hBgndDC, fXAsMipmapLevel ? fBgndImage2 : fBgndImage );
|
||||
#else
|
||||
SelectObject( hBgndDC, fBgndImage );
|
||||
#endif
|
||||
|
||||
bmpInfo.bmiHeader.biSize = sizeof( bmpInfo.bmiHeader );
|
||||
bmpInfo.bmiHeader.biBitCount = 0;
|
||||
GetDIBits( hBgndDC, fBgndImage, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS );
|
||||
bgndSize.cx = bmpInfo.bmiHeader.biWidth;
|
||||
bgndSize.cy = bmpInfo.bmiHeader.biHeight;
|
||||
x = ( width - bgndSize.cx ) >> 1;
|
||||
y = ( height - bgndSize.cy ) >> 1;
|
||||
|
||||
BitBlt( fDblDC, x, y, bgndSize.cx, bgndSize.cy, hBgndDC, 0, 0, SRCCOPY );
|
||||
SelectObject( hBgndDC, (HBITMAP)NULL );
|
||||
DeleteDC( hBgndDC );
|
||||
|
||||
/// Draw graph
|
||||
if( IsWindowEnabled( fHWnd ) )
|
||||
{
|
||||
bgndSize.cx -= 8;
|
||||
oldPen = (HPEN)SelectObject( fDblDC, fLiteBluePen );
|
||||
|
||||
/// This line draws the light blue "actual" curve, which shows what happens
|
||||
/// when you actually interpolate the curve across the mipmap levels. It's
|
||||
/// more accurate in that it shows the actual values computed for each level,
|
||||
/// but less accurate because it doesn't take into account mipmap sampling
|
||||
/// and such. Given the latter, we leave it out (for now) to avoid confusing
|
||||
/// the artists.
|
||||
// IDrawCurve( fDblDC, true, x, y, &bgndSize );
|
||||
|
||||
SelectObject( fDblDC, fBluePen );
|
||||
IDrawCurve( fDblDC, false, x, y, &bgndSize );
|
||||
|
||||
SelectObject( fDblDC, oldPen );
|
||||
|
||||
if( fStartPercent == 0.07f && fStartOpac == 0.23f && fEndPercent == 0.19f && fEndOpac == 0.79f )
|
||||
{
|
||||
const char str[] = "\x48\x61\x70\x70\x79\x20\x62\x64\x61\x79\x20\x74\x6f\x20\x6d\x63\x6e\x21";
|
||||
SetBkMode( fDblDC, TRANSPARENT );
|
||||
SetTextColor( fDblDC, RGB( 0, 0, 255 ) );
|
||||
SelectObject( fDblDC, fFont );
|
||||
TextOut( fDblDC, x, y + bgndSize.cy - 10, str, strlen( str ) );
|
||||
}
|
||||
|
||||
// Draw our two markers
|
||||
IXlateValuesToClientPt( fStartPercent, fStartOpac, &pt1, x, y, &bgndSize );
|
||||
SetRect( &fStartDragPt, pt1.x - 4, pt1.y - 4, pt1.x + 4, pt1.y + 4 );
|
||||
r = fStartDragPt;
|
||||
if( !fCanDragStart )
|
||||
InflateRect( &r, -2, -2 );
|
||||
FillRect( fDblDC, &r, fBlueBrush );
|
||||
|
||||
IXlateValuesToClientPt( fEndPercent, fEndOpac, &pt2, x, y, &bgndSize );
|
||||
SetRect( &fEndDragPt, pt2.x - 4, pt2.y - 4, pt2.x + 4, pt2.y + 4 );
|
||||
r = fEndDragPt;
|
||||
if( !fCanDragEnd )
|
||||
InflateRect( &r, -2, -2 );
|
||||
FillRect( fDblDC, &r, fBlueBrush );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// IDrawCurve ///////////////////////////////////////////////////////////////
|
||||
// Draw the damned curve.
|
||||
|
||||
void plDetailCurveCtrl::IDrawCurve( HDC hDC, bool clampToInts, int cornerX, int cornerY, SIZE *bgndSize )
|
||||
{
|
||||
float dist, penX, penBaseY, penXStep, penYScale;
|
||||
POINT pt1;
|
||||
|
||||
|
||||
// Calc stuff
|
||||
penX = (float)cornerX;
|
||||
penBaseY = (float)( cornerY + bgndSize->cy );
|
||||
penXStep = (float)bgndSize->cx * kHiResStep;
|
||||
penYScale = (float)bgndSize->cy;
|
||||
|
||||
// Draw curve
|
||||
pt1.x = (int)penX;
|
||||
pt1.y = (int)( penBaseY - penYScale * fStartOpac );
|
||||
|
||||
float artificialBias = 1.f / (float)fNumLevels; // So we never get a howFar less than 0
|
||||
float artificialMaxDist = 1.f - artificialBias;
|
||||
|
||||
for( dist = 0.f; dist <= 1.f; dist += kHiResStep )
|
||||
{
|
||||
float opac = IXlateDistToValue( dist, clampToInts );
|
||||
|
||||
if( dist == 0.f )
|
||||
MoveToEx( hDC, (int)penX, (int)( penBaseY - penYScale * opac ), NULL );
|
||||
else
|
||||
LineTo( hDC, (int)penX, (int)( penBaseY - penYScale * opac ) );
|
||||
|
||||
penX += penXStep;
|
||||
}
|
||||
}
|
||||
|
||||
//// IXlateDistToValue ////////////////////////////////////////////////////////
|
||||
// I.E. from distance across graph to distance up on graph (percentage-wise)
|
||||
|
||||
float plDetailCurveCtrl::IXlateDistToValue( float dist, bool clampToInts )
|
||||
{
|
||||
const float artificialBias = 1.f / (float)fNumLevels; // So we never get a howFar less than 0
|
||||
const float artificialMaxDist = 1.f - artificialBias;
|
||||
float howFar, opac;
|
||||
|
||||
|
||||
howFar = IXlateDistToX( dist, clampToInts );
|
||||
|
||||
if( howFar < fStartPercent )
|
||||
opac = fStartOpac;
|
||||
else if( howFar > fEndPercent )
|
||||
opac = fEndOpac;
|
||||
else
|
||||
opac = ( howFar - fStartPercent ) * ( fEndOpac - fStartOpac ) / ( fEndPercent - fStartPercent ) + fStartOpac;
|
||||
|
||||
return opac;
|
||||
}
|
||||
|
||||
//// IXlateDistToX ////////////////////////////////////////////////////////////
|
||||
// I.E. from the distance in percentage across the graph to the actual x
|
||||
// value on the graph
|
||||
|
||||
float plDetailCurveCtrl::IXlateDistToX( float dist, bool clampToInts )
|
||||
{
|
||||
const float artificialBias = 1.f / (float)fNumLevels; // So we never get a howFar less than 0
|
||||
const float artificialMaxDist = 1.f - artificialBias;
|
||||
float howFar;
|
||||
|
||||
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
if( fXAsMipmapLevel )
|
||||
{
|
||||
howFar = dist * (float)fNumLevels;
|
||||
if( clampToInts )
|
||||
howFar = (float)( (int)howFar );
|
||||
|
||||
howFar /= (float)fNumLevels;
|
||||
return howFar;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( dist == 0.f )
|
||||
howFar = 0.f;
|
||||
else
|
||||
{
|
||||
howFar = 1.f - ( ( 1.f - dist ) * artificialMaxDist );
|
||||
howFar = ( (float)fNumLevels - 1.f / howFar );
|
||||
if( howFar < 0.f )
|
||||
howFar = 0.f;
|
||||
else if( howFar > (float)fNumLevels - 1.f )
|
||||
howFar = (float)fNumLevels - 1.f;
|
||||
|
||||
if( clampToInts )
|
||||
howFar = (float)( (int)howFar );
|
||||
|
||||
howFar /= (float)fNumLevels - 1.f;
|
||||
}
|
||||
|
||||
return howFar;
|
||||
}
|
||||
|
||||
//// IXlateXToDist ////////////////////////////////////////////////////////////
|
||||
// I.E. from the actual x value of the graph to the actual distance in
|
||||
// percentage across the graph.
|
||||
|
||||
float plDetailCurveCtrl::IXlateXToDist( float howFar )
|
||||
{
|
||||
const float artificialBias = 1.f / (float)fNumLevels; // So we never get a howFar less than 0
|
||||
const float artificialMaxDist = 1.f - artificialBias;
|
||||
float dist;
|
||||
|
||||
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
if( fXAsMipmapLevel )
|
||||
{
|
||||
return howFar;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( howFar == 0.f )
|
||||
dist = 0.f;
|
||||
else
|
||||
{
|
||||
howFar *= (float)fNumLevels - 1.f;
|
||||
howFar = 1.f / ( (float)fNumLevels - howFar );
|
||||
howFar = ( ( howFar - 1.f ) / artificialMaxDist ) + 1.f;
|
||||
}
|
||||
|
||||
return howFar;
|
||||
}
|
||||
|
||||
//// IXlateValuesToClientPt ///////////////////////////////////////////////////
|
||||
// I.E. from graph x,y values to client coordinates
|
||||
|
||||
void plDetailCurveCtrl::IXlateValuesToClientPt( float x, float y, POINT *pt, int cornerX, int cornerY, SIZE *bgndSize )
|
||||
{
|
||||
pt->x = cornerX + (int)( IXlateXToDist( x ) * (float)bgndSize->cx );
|
||||
pt->y = cornerY + bgndSize->cy;
|
||||
|
||||
pt->y -= (int)( (float)bgndSize->cy * y );
|
||||
}
|
||||
|
||||
//// IMapMouseToValues ////////////////////////////////////////////////////////
|
||||
// Map mouse x,y coordinates in clientspace to graph values. If the last param
|
||||
// is true, maps to the start point, else maps to the end point
|
||||
|
||||
void plDetailCurveCtrl::IMapMouseToValues( int x, int y, bool mapToStart )
|
||||
{
|
||||
BITMAPINFO bmpInfo;
|
||||
int cX, cY, width, height;
|
||||
RECT clientRect;
|
||||
float vX, vY;
|
||||
SIZE bgndSize;
|
||||
|
||||
|
||||
if( fBgndImage == NULL || fDblDC == NULL || !IsWindowEnabled( fHWnd ) )
|
||||
return;
|
||||
|
||||
GetClientRect( fHWnd, &clientRect );
|
||||
width = clientRect.right - clientRect.left;
|
||||
height = clientRect.bottom - clientRect.top;
|
||||
|
||||
bmpInfo.bmiHeader.biSize = sizeof( bmpInfo.bmiHeader );
|
||||
bmpInfo.bmiHeader.biBitCount = 0;
|
||||
GetDIBits( fDblDC, fBgndImage, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS );
|
||||
bgndSize.cx = bmpInfo.bmiHeader.biWidth;
|
||||
bgndSize.cy = bmpInfo.bmiHeader.biHeight;
|
||||
cX = ( width - bgndSize.cx ) >> 1;
|
||||
cY = ( height - bgndSize.cy ) >> 1;
|
||||
|
||||
bgndSize.cx -= 8;
|
||||
|
||||
// Xlate to graph space and clamp
|
||||
x -= cX;
|
||||
y = bgndSize.cy - ( y - cY );
|
||||
if( x < 0 )
|
||||
x = 0;
|
||||
else if( x > bgndSize.cx )
|
||||
x = bgndSize.cx;
|
||||
if( y < 0 )
|
||||
y = 0;
|
||||
else if( y > bgndSize.cy )
|
||||
y = bgndSize.cy;
|
||||
|
||||
vX = IXlateDistToX( (float)x / (float)bgndSize.cx, false );
|
||||
vY = (float)y / (float)bgndSize.cy;
|
||||
|
||||
if( mapToStart )
|
||||
{
|
||||
fStartPercent = vX;
|
||||
fStartOpac = vY;
|
||||
if( fEndPercent < fStartPercent )
|
||||
{
|
||||
fEndPercent = fStartPercent;
|
||||
ISendDraggedMessage( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fEndPercent = vX;
|
||||
fEndOpac = vY;
|
||||
if( fEndPercent < fStartPercent )
|
||||
{
|
||||
fStartPercent = fEndPercent;
|
||||
ISendDraggedMessage( true );
|
||||
}
|
||||
}
|
||||
|
||||
IRefreshDblBuffer();
|
||||
InvalidateRect( fHWnd, NULL, false );
|
||||
RedrawWindow( fHWnd, NULL, NULL, RDW_UPDATENOW );
|
||||
|
||||
ISendDraggedMessage( mapToStart );
|
||||
}
|
||||
|
||||
//// ISendDraggedMessage //////////////////////////////////////////////////////
|
||||
|
||||
void plDetailCurveCtrl::ISendDraggedMessage( bool itWasTheStartPoint )
|
||||
{
|
||||
HWND parent = GetParent( fHWnd );
|
||||
|
||||
|
||||
if( parent == NULL )
|
||||
return;
|
||||
|
||||
SendMessage( parent, PL_DC_POINT_DRAGGED, itWasTheStartPoint ? PL_DC_START_POINT : PL_DC_END_POINT,
|
||||
(LPARAM)this );
|
||||
}
|
||||
|
||||
//// SetStart/EndPoint ////////////////////////////////////////////////////////
|
||||
|
||||
void plDetailCurveCtrl::SetStartPoint( float percentLevel, float opacity )
|
||||
{
|
||||
fStartPercent = percentLevel;
|
||||
fStartOpac = opacity;
|
||||
IRefreshDblBuffer();
|
||||
InvalidateRect( fHWnd, NULL, false );
|
||||
}
|
||||
|
||||
void plDetailCurveCtrl::SetEndPoint( float percentLevel, float opacity )
|
||||
{
|
||||
fEndPercent = percentLevel;
|
||||
fEndOpac = opacity;
|
||||
IRefreshDblBuffer();
|
||||
InvalidateRect( fHWnd, NULL, false );
|
||||
}
|
||||
|
||||
void plDetailCurveCtrl::SetNumLevels( int numLevels )
|
||||
{
|
||||
fNumLevels = numLevels;
|
||||
IRefreshDblBuffer();
|
||||
InvalidateRect( fHWnd, NULL, false );
|
||||
}
|
||||
|
||||
//// IWndProc /////////////////////////////////////////////////////////////////
|
||||
|
||||
LRESULT CALLBACK plDetailCurveCtrl::IWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
HDC hDC;
|
||||
RECT clientRect;
|
||||
int width, height;
|
||||
PAINTSTRUCT pInfo;
|
||||
POINT pt;
|
||||
|
||||
|
||||
plDetailCurveCtrl *ctrl = (plDetailCurveCtrl *)GetWindowLong( hWnd, GWL_USERDATA );
|
||||
GetClientRect( hWnd, &clientRect );
|
||||
width = clientRect.right - clientRect.left;
|
||||
height = clientRect.bottom - clientRect.top;
|
||||
|
||||
switch( msg )
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
|
||||
case WM_ENABLE:
|
||||
if( ctrl != NULL )
|
||||
ctrl->IRefreshDblBuffer();
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
BeginPaint( hWnd, &pInfo );
|
||||
hDC = (HDC)pInfo.hdc;
|
||||
|
||||
if( ctrl != NULL )
|
||||
{
|
||||
if( ctrl->fDblDC == NULL )
|
||||
ctrl->IInitDblBuffer();
|
||||
|
||||
BitBlt( hDC, 0, 0, width, height, ctrl->fDblDC, 0, 0, SRCCOPY );
|
||||
}
|
||||
|
||||
EndPaint( hWnd, &pInfo );
|
||||
return 0;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return TRUE;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
if( ctrl != NULL && !ctrl->fDraggingStart && !ctrl->fDraggingEnd )
|
||||
{
|
||||
pt.x = LOWORD( lParam );
|
||||
pt.y = HIWORD( lParam );
|
||||
if( PtInRect( &ctrl->fStartDragPt, pt ) )
|
||||
{
|
||||
if( !ctrl->fCanDragStart && !ctrl->fCanDragEnd )
|
||||
SetCapture( hWnd );
|
||||
ctrl->fDraggingStart = true;
|
||||
}
|
||||
else if( PtInRect( &ctrl->fEndDragPt, pt ) )
|
||||
{
|
||||
if( !ctrl->fCanDragStart && !ctrl->fCanDragEnd )
|
||||
SetCapture( hWnd );
|
||||
ctrl->fDraggingEnd = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if( ctrl != NULL )
|
||||
{
|
||||
pt.x = LOWORD( lParam );
|
||||
pt.y = HIWORD( lParam );
|
||||
|
||||
if( ctrl->fDraggingStart || ctrl->fDraggingEnd )
|
||||
{
|
||||
ctrl->IMapMouseToValues( (short)LOWORD( lParam ), (short)HIWORD( lParam ), ctrl->fDraggingStart );
|
||||
}
|
||||
else if( PtInRect( &ctrl->fStartDragPt, pt ) )
|
||||
{
|
||||
if( !ctrl->fCanDragStart )
|
||||
{
|
||||
ctrl->fCanDragStart = true;
|
||||
ctrl->fCanDragEnd = false;
|
||||
SetCapture( hWnd );
|
||||
ctrl->IRefreshDblBuffer();
|
||||
InvalidateRect( hWnd, NULL, false );
|
||||
}
|
||||
}
|
||||
else if( PtInRect( &ctrl->fEndDragPt, pt ) )
|
||||
{
|
||||
if( !ctrl->fCanDragEnd )
|
||||
{
|
||||
ctrl->fCanDragEnd = true;
|
||||
ctrl->fCanDragStart = false;
|
||||
SetCapture( hWnd );
|
||||
ctrl->IRefreshDblBuffer();
|
||||
InvalidateRect( hWnd, NULL, false );
|
||||
}
|
||||
}
|
||||
else if( ctrl->fCanDragStart || ctrl->fCanDragEnd )
|
||||
{
|
||||
ctrl->fCanDragStart = false;
|
||||
ctrl->fCanDragEnd = false;
|
||||
ReleaseCapture();
|
||||
ctrl->IRefreshDblBuffer();
|
||||
InvalidateRect( hWnd, NULL, false );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
if( ctrl != NULL && ( ctrl->fDraggingStart || ctrl->fDraggingEnd ) )
|
||||
{
|
||||
if( !ctrl->fCanDragStart && !ctrl->fCanDragEnd )
|
||||
ReleaseCapture();
|
||||
ctrl->fDraggingStart = false;
|
||||
ctrl->fDraggingEnd = false;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#ifdef MCN_TWO_GRAPH_MODE
|
||||
case WM_RBUTTONDOWN:
|
||||
fXAsMipmapLevel = !fXAsMipmapLevel;
|
||||
ctrl->IRefreshDblBuffer();
|
||||
InvalidateRect( hWnd, NULL, false );
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case WM_DESTROY:
|
||||
delete ctrl;
|
||||
SetWindowLong( hWnd, GWL_USERDATA, 0 );
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc( hWnd, msg, wParam, lParam );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user