Mercurial > hg > hv
view Navigator.cpp @ 0:a6a46af64546
first upload
author | wenx <xue.wen@eecs.qmul.ac.uk> |
---|---|
date | Wed, 10 Aug 2011 14:55:38 +0100 |
parents | |
children |
line wrap: on
line source
/* Harmonic Visualiser An audio file viewer and editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2011 Wen Xue. 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. */ //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Navigator.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // ValidCtrCheck is used to assure that the components created do not have // any pure virtual functions. // static inline void ValidCtrCheck(TNavigator *) { new TNavigator(NULL); } //--------------------------------------------------------------------------- __fastcall TNavigator::TNavigator(TComponent* Owner) : TCustomControl(Owner) { x1=y1=0; x2=y2=1; FOnBackground=0; BkgBmp=new Graphics::TBitmap; } __fastcall TNavigator::~TNavigator() { delete BkgBmp; } void TNavigator::DrawArea() { Canvas->Brush->Style=bsClear; Canvas->Pen->Mode=pmXor; Canvas->Pen->Color=AreaColorX; X1=x1*Width, X2=x2*Width, Y1=y1*Height, Y2=y2*Height; if (X1+1<X2 && Y1+1<Y2) Canvas->Rectangle(X1, Y1, X2, Y2); else if (X1+1>=X2) { Canvas->MoveTo(X1, Y1); Canvas->LineTo(X1, Y2); } else { Canvas->MoveTo(X1, Y1); Canvas->LineTo(X2, Y1); } } TNavigatorHitTest TNavigator::HitTest(int X, int Y) { int Xa=1, Ya=1; //borderouter int Xb=1, Yb=1; //borderinner if (X2-X1<=3) Xb=0; if (Y2-Y1<=3) Yb=0; if (X2-X1<=1) Xb=-1; if (Y2-Y1<=1) Yb=-1; TNavigatorHitTest XTest, YTest; if (X<X1-Xa || X>X2+Xa) XTest=htOuter; else if (X1-Xa<=X && X<=X1+Xb) XTest=htLeft; else if (X1+Xb<X && X<X2-Xb) XTest=htInner; else XTest=htRight; if (Y<Y1-Ya || Y>Y2+Ya) YTest=htOuter; else if (Y1-Ya<=Y && Y<=Y1+Yb) YTest=htTop; else if (Y1+Yb<Y & Y<Y2-Yb) YTest=htInner; else YTest=htBottom; if (XTest==htInner && YTest==htInner) return htInner; if (YTest==htInner && XTest!=htOuter) return XTest; if (XTest==htInner && YTest!=htOuter) return YTest; return htOuter; } void __fastcall TNavigator::MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y) { if (Button==mbLeft) { X0=X, Y0=Y; x01=x1, x02=x2, y01=y1, y02=y2; FMouseAction=maNoAction; FHitTest=HitTest(X, Y); if (FHitTest!=htOuter) FMouseAction=maMove; if (Shift.Contains(ssCtrl)) { switch (FHitTest) { case htInner: break; case htLeft: case htTop: case htRight: case htBottom: case htTopLeft: case htTopRight: case htBottomRight: case htBottomLeft: FMouseAction=maSize; break; } } if (FMouseAction==maMove) Cursor=crSizeAll; else if (FMouseAction==maSize) { if (FHitTest==htLeft || FHitTest==htRight) Cursor=crSizeWE; else Cursor=crSizeNS; } ::SetCursor(Screen->Cursors[Cursor]); } if (Button==mbRight) { TPoint P=ClientToScreen(TPoint((X1+X2)/2, (Y1+Y2)/2)); SetCursorPos(P.x, P.y); } } void __fastcall TNavigator::MouseMove(TShiftState Shift, int X, int Y) { if (Shift.Contains(ssLeft)) { double destx1=x1, destx2=x2, desty1=y1, desty2=y2; int dX=X-X0; int dY=Y-Y0; double dx=dX*1.0/Width; double dy=dY*1.0/Height; if (FMouseAction==maMove) { if (x01+dx<0) dx=-x01; if (x02+dx>1) dx=1-x02; if (y01+dy<0) dy=-y01; if (y02+dy>1) dy=1-y02; destx1=x01+dx; destx2=x02+dx; desty1=y01+dy; desty2=y02+dy; } else if (FMouseAction==maSize) { switch(FHitTest) { case htLeft: if (x01+dx<0) dx=-x01; if (x01+dx>1) dx=1-x01; destx1=x01+dx; if (destx1>x02) {destx2=destx1; destx1=x02;} break; case htRight: if (x02+dx<0) dx=-x02; if (x02+dx>1) dx=1-x02; destx2=x02+dx; if (x01>destx2) {destx1=destx2; destx2=x01;} break; case htTop: if (y01+dy<0) dy=-y01; if (y01+dy>1) dy=1-y01; desty1=y01+dy; if (desty1>y02) {desty2=desty1; desty1=y02;} break; case htBottom: if (y02+dy<0) dy=-y02; if (y02+dy>1) dy=1-y02; desty2=y02+dy; if (y01>desty2) {desty1=desty2; desty2=y01;} break; } } if (destx1!=x1 || destx2!=x2 || desty1!=y1 || desty2!=y2) { SetArea(destx1, destx2, desty1, desty2); FOnAreaChange(this); } } else if (Shift.Contains(ssCtrl)) { TCursor NewCursor; FHitTest=HitTest(X, Y); if (FHitTest==htLeft || FHitTest==htRight) NewCursor=crSizeWE; else if (FHitTest==htTop || FHitTest==htBottom) NewCursor=crSizeNS; else if (FHitTest==htInner) NewCursor=crSizeAll; else NewCursor=crArrow; if (Cursor!=NewCursor) { Cursor=NewCursor; ::SetCursor(Screen->Cursors[Cursor]); } } else { if (Cursor!=crArrow) { Cursor=crArrow; ::SetCursor(Screen->Cursors[Cursor]); } } } void __fastcall TNavigator::MouseUp(TMouseButton Button, TShiftState, int, int) { if (Button==mbLeft) { Cursor=crArrow; ::SetCursor(Screen->Cursors[Cursor]); } } void __fastcall TNavigator::Paint() { Canvas->CopyRect(ClientRect, BkgBmp->Canvas, ClientRect);// if (FOnBackground) FOnBackground(this); DrawArea(); } void __fastcall TNavigator::Resize() { BkgBmp->Width=Width; BkgBmp->Height=Height; if (FOnBackground) FOnBackground(this); Invalidate(); TControl::Resize(); } void TNavigator::SetArea(double ax1, double ax2, double ay1, double ay2) { if (x1==ax1 && x2==ax2 && y1==ay1 && y2==ay2) return; DrawArea(); x1=ax1, x2=ax2, y1=ay1, y2=ay2; DrawArea(); } //--------------------------------------------------------------------------- namespace Navigator { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TNavigator)}; RegisterComponents("Samples", classes, 0); } } //---------------------------------------------------------------------------