xue@0: /* xue@0: Harmonic Visualiser xue@0: xue@0: An audio file viewer and editor. xue@0: Centre for Digital Music, Queen Mary, University of London. xue@0: This file copyright 2011 Wen Xue. xue@0: xue@0: This program is free software; you can redistribute it and/or xue@0: modify it under the terms of the GNU General Public License as xue@0: published by the Free Software Foundation; either version 2 of the xue@0: License, or (at your option) any later version. xue@0: */ xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: #include xue@0: xue@0: #pragma hdrstop xue@0: xue@0: #include "Navigator.h" xue@0: #pragma package(smart_init) xue@0: //--------------------------------------------------------------------------- xue@0: // ValidCtrCheck is used to assure that the components created do not have xue@0: // any pure virtual functions. xue@0: // xue@0: xue@0: static inline void ValidCtrCheck(TNavigator *) xue@0: { xue@0: new TNavigator(NULL); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: __fastcall TNavigator::TNavigator(TComponent* Owner) xue@0: : TCustomControl(Owner) xue@0: { xue@0: x1=y1=0; xue@0: x2=y2=1; xue@0: FOnBackground=0; xue@0: BkgBmp=new Graphics::TBitmap; xue@0: } xue@0: xue@0: __fastcall TNavigator::~TNavigator() xue@0: { xue@0: delete BkgBmp; xue@0: } xue@0: xue@0: void TNavigator::DrawArea() xue@0: { xue@0: Canvas->Brush->Style=bsClear; xue@0: Canvas->Pen->Mode=pmXor; xue@0: Canvas->Pen->Color=AreaColorX; xue@0: X1=x1*Width, X2=x2*Width, Y1=y1*Height, Y2=y2*Height; xue@0: if (X1+1Rectangle(X1, Y1, X2, Y2); xue@0: else if (X1+1>=X2) xue@0: { xue@0: Canvas->MoveTo(X1, Y1); xue@0: Canvas->LineTo(X1, Y2); xue@0: } xue@0: else xue@0: { xue@0: Canvas->MoveTo(X1, Y1); xue@0: Canvas->LineTo(X2, Y1); xue@0: } xue@0: } xue@0: xue@0: TNavigatorHitTest TNavigator::HitTest(int X, int Y) xue@0: { xue@0: int Xa=1, Ya=1; //borderouter xue@0: int Xb=1, Yb=1; //borderinner xue@0: if (X2-X1<=3) Xb=0; xue@0: if (Y2-Y1<=3) Yb=0; xue@0: if (X2-X1<=1) Xb=-1; xue@0: if (Y2-Y1<=1) Yb=-1; xue@0: xue@0: TNavigatorHitTest XTest, YTest; xue@0: xue@0: if (XX2+Xa) XTest=htOuter; xue@0: else if (X1-Xa<=X && X<=X1+Xb) XTest=htLeft; xue@0: else if (X1+XbY2+Ya) YTest=htOuter; xue@0: else if (Y1-Ya<=Y && Y<=Y1+Yb) YTest=htTop; xue@0: else if (Y1+YbCursors[Cursor]); xue@0: } xue@0: if (Button==mbRight) xue@0: { xue@0: TPoint P=ClientToScreen(TPoint((X1+X2)/2, (Y1+Y2)/2)); xue@0: SetCursorPos(P.x, P.y); xue@0: } xue@0: } xue@0: xue@0: void __fastcall TNavigator::MouseMove(TShiftState Shift, int X, int Y) xue@0: { xue@0: if (Shift.Contains(ssLeft)) xue@0: { xue@0: double destx1=x1, destx2=x2, desty1=y1, desty2=y2; xue@0: xue@0: int dX=X-X0; xue@0: int dY=Y-Y0; xue@0: xue@0: double dx=dX*1.0/Width; xue@0: double dy=dY*1.0/Height; xue@0: xue@0: if (FMouseAction==maMove) xue@0: { xue@0: if (x01+dx<0) dx=-x01; xue@0: if (x02+dx>1) dx=1-x02; xue@0: if (y01+dy<0) dy=-y01; xue@0: if (y02+dy>1) dy=1-y02; xue@0: destx1=x01+dx; xue@0: destx2=x02+dx; xue@0: desty1=y01+dy; xue@0: desty2=y02+dy; xue@0: } xue@0: else if (FMouseAction==maSize) xue@0: { xue@0: switch(FHitTest) xue@0: { xue@0: case htLeft: xue@0: if (x01+dx<0) dx=-x01; xue@0: if (x01+dx>1) dx=1-x01; xue@0: destx1=x01+dx; xue@0: if (destx1>x02) {destx2=destx1; destx1=x02;} xue@0: break; xue@0: case htRight: xue@0: if (x02+dx<0) dx=-x02; xue@0: if (x02+dx>1) dx=1-x02; xue@0: destx2=x02+dx; xue@0: if (x01>destx2) {destx1=destx2; destx2=x01;} xue@0: break; xue@0: case htTop: xue@0: if (y01+dy<0) dy=-y01; xue@0: if (y01+dy>1) dy=1-y01; xue@0: desty1=y01+dy; xue@0: if (desty1>y02) {desty2=desty1; desty1=y02;} xue@0: break; xue@0: case htBottom: xue@0: if (y02+dy<0) dy=-y02; xue@0: if (y02+dy>1) dy=1-y02; xue@0: desty2=y02+dy; xue@0: if (y01>desty2) {desty1=desty2; desty2=y01;} xue@0: break; xue@0: } xue@0: } xue@0: xue@0: if (destx1!=x1 || destx2!=x2 || desty1!=y1 || desty2!=y2) xue@0: { xue@0: SetArea(destx1, destx2, desty1, desty2); xue@0: FOnAreaChange(this); xue@0: } xue@0: } xue@0: else if (Shift.Contains(ssCtrl)) xue@0: { xue@0: TCursor NewCursor; xue@0: FHitTest=HitTest(X, Y); xue@0: if (FHitTest==htLeft || FHitTest==htRight) xue@0: NewCursor=crSizeWE; xue@0: else if (FHitTest==htTop || FHitTest==htBottom) xue@0: NewCursor=crSizeNS; xue@0: else if (FHitTest==htInner) xue@0: NewCursor=crSizeAll; xue@0: else xue@0: NewCursor=crArrow; xue@0: if (Cursor!=NewCursor) xue@0: { xue@0: Cursor=NewCursor; xue@0: ::SetCursor(Screen->Cursors[Cursor]); xue@0: } xue@0: } xue@0: else xue@0: { xue@0: if (Cursor!=crArrow) xue@0: { xue@0: Cursor=crArrow; xue@0: ::SetCursor(Screen->Cursors[Cursor]); xue@0: } xue@0: } xue@0: } xue@0: xue@0: void __fastcall TNavigator::MouseUp(TMouseButton Button, TShiftState, int, int) xue@0: { xue@0: if (Button==mbLeft) xue@0: { xue@0: Cursor=crArrow; xue@0: ::SetCursor(Screen->Cursors[Cursor]); xue@0: } xue@0: } xue@0: xue@0: void __fastcall TNavigator::Paint() xue@0: { xue@0: Canvas->CopyRect(ClientRect, BkgBmp->Canvas, ClientRect);// if (FOnBackground) FOnBackground(this); xue@0: DrawArea(); xue@0: } xue@0: xue@0: void __fastcall TNavigator::Resize() xue@0: { xue@0: BkgBmp->Width=Width; xue@0: BkgBmp->Height=Height; xue@0: if (FOnBackground) FOnBackground(this); xue@0: Invalidate(); xue@0: TControl::Resize(); xue@0: } xue@0: xue@0: void TNavigator::SetArea(double ax1, double ax2, double ay1, double ay2) xue@0: { xue@0: if (x1==ax1 && x2==ax2 && y1==ay1 && y2==ay2) return; xue@0: DrawArea(); xue@0: x1=ax1, x2=ax2, y1=ay1, y2=ay2; xue@0: DrawArea(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: namespace Navigator xue@0: { xue@0: void __fastcall PACKAGE Register() xue@0: { xue@0: TComponentClass classes[1] = {__classid(TNavigator)}; xue@0: RegisterComponents("Samples", classes, 0); xue@0: } xue@0: } xue@0: //---------------------------------------------------------------------------