📄 ruler.cpp
字号:
label->pos = pos; label->lx = mLeft - 1000; // don't display label->ly = mTop - 1000; // don't display label->text = wxT(""); mDC->SetFont(major? *mMajorFont: *mMinorFont); l = LabelString(d, major); mDC->GetTextExtent(l, &strW, &strH); if (mOrientation == wxHORIZONTAL) { strLen = strW; strPos = pos - strW/2; if (strPos < 0) strPos = 0; if (strPos + strW >= mLength) strPos = mLength - strW; strLeft = mLeft + strPos; if (mFlip) strTop = mTop + 4; else strTop = mBottom - strH - 6; } else { strLen = strH; strPos = pos - strH/2; if (strPos < 0) strPos = 0; if (strPos + strH >= mLength) strPos = mLength - strH; strTop = mTop + strPos; if (mFlip) strLeft = mLeft + 5; else strLeft = mRight - strW - 6; } // See if any of the pixels we need to draw this // label is already covered int i; for(i=0; i<strLen; i++) if (mBits[strPos+i]) return; // If not, position the label and give it text label->lx = strLeft; label->ly = strTop; label->text = l; // And mark these pixels, plus some surrounding // ones (the spacing between labels), as covered int leftMargin = mSpacing; if (strPos < leftMargin) leftMargin = strPos; strPos -= leftMargin; strLen += leftMargin; int rightMargin = mSpacing; if (strPos + strLen > mLength - mSpacing) rightMargin = mLength - strPos - strLen; strLen += rightMargin; for(i=0; i<strLen; i++) mBits[strPos+i] = 1;}void Ruler::Update(){ Update(NULL, 0, 0);}void Ruler::Update( Envelope *speedEnv, long minSpeed, long maxSpeed ){ // This gets called when something has been changed // (i.e. we've been invalidated). Recompute all // tick positions. int i; int j; mNumMajor = 0; mMajorLabels = new Label[mLength+1]; mNumMinor = 0; mMinorLabels = new Label[mLength+1]; if (mBits) delete[] mBits; mBits = new int[mLength+1]; if (mUserBits) for(i=0; i<=mLength; i++) mBits[i] = mUserBits[i]; else for(i=0; i<=mLength; i++) mBits[i] = 0; if(mLog==false) { double UPP = (mMax-mMin)/mLength; // Units per pixel FindLinearTickSizes(UPP); // Left and Right Edges if (mLabelEdges) { Tick(0, mMin, true); Tick(mLength, mMax, true); } // Zero (if it's in the middle somewhere) if (mMin * mMax < 0.0) { int mid = (int)(mLength*(mMin/(mMin-mMax)) + 0.5); Tick(mid, 0.0, true); } double sg = UPP > 0.0? 1.0: -1.0; // Major ticks double d = mMin - UPP/2; double lastD = d; int majorInt = (int)floor(sg * d / mMajor); i = -1; while(i <= mLength) { double warpfactor; if( d>0 && speedEnv != NULL ) { warpfactor = speedEnv->Average( lastD, d ); // Now we re-scale so that 0.5 is normal speed and // 0 and 1.0 are min% and max% of normal speed warpfactor = (maxSpeed * (1 - warpfactor) + warpfactor * minSpeed) / 100.0; } else warpfactor = 1.0; i++; lastD = d; d += UPP*warpfactor; if ((int)floor(sg * d / mMajor) > majorInt) { majorInt = (int)floor(sg * d / mMajor); Tick(i, sg * majorInt * mMajor, true); } } // Minor ticks d = mMin - UPP/2; lastD = d; int minorInt = (int)floor(sg * d / mMinor); i = -1; while(i <= mLength) { double warpfactor; if( d>0 && speedEnv != NULL ) { warpfactor = speedEnv->Average( lastD, d ); // Now we re-scale so that 0.5 is normal speed and // 0 and 1.0 are min% and max% of normal speed warpfactor = (maxSpeed * (1 - warpfactor) + warpfactor * minSpeed) / 100.0; } else warpfactor = 1.0; i++; lastD = d; d += UPP*warpfactor; if ((int)floor(sg * d / mMinor) > minorInt) { minorInt = (int)floor(sg * d / mMinor); Tick(i, sg * minorInt * mMinor, false); } } // Left and Right Edges if (mLabelEdges) { Tick(0, mMin, true); Tick(mLength, mMax, true); } } else { // log case double loLog = log10(mMin); double hiLog = log10(mMax); double scale = mLength/(hiLog - loLog); int loDecade = (int) floor(loLog); int hiDecade = (int) ceil(hiLog); int pos; double val; double startDecade = pow(10., (double)loDecade); // Major ticks are the decades double decade = startDecade; for(i=loDecade; i<hiDecade; i++) { if(i!=loDecade) { val = decade; if(val > mMin && val < mMax) { pos = (int)(((log10(val) - loLog)*scale)+0.5); Tick(pos, val, true); } } decade *= 10.; } // Minor ticks are multiples of decades decade = startDecade; for(i=loDecade; i<hiDecade; i++) { for(j=2; j<=9; j++) { val = decade * j; if(val > mMin && val < mMax) { pos = (int)(((log10(val) - loLog)*scale)+0.5); Tick(pos, val, false); } } decade *= 10.; } } mValid = true;}void Ruler::Draw(wxDC& dc){ Draw( dc, NULL, 0, 0 );}void Ruler::Draw(wxDC& dc, Envelope *speedEnv, long minSpeed, long maxSpeed){ mDC = &dc; if (!mValid) Update( speedEnv, minSpeed, maxSpeed ); mDC->SetPen(*wxBLACK_PEN); mDC->SetTextForeground(*wxBLACK); if (mOrientation == wxHORIZONTAL) { if (mFlip) mDC->DrawLine(mLeft, mTop, mRight+1, mTop); else mDC->DrawLine(mLeft, mBottom, mRight+1, mBottom); } else { if (mFlip) mDC->DrawLine(mLeft, mTop, mLeft, mBottom+1); else mDC->DrawLine(mRight, mTop, mRight, mBottom+1); } int i; mDC->SetFont(*mMajorFont); for(i=0; i<mNumMajor; i++) { int pos = mMajorLabels[i].pos; if (mOrientation == wxHORIZONTAL) { if (mFlip) mDC->DrawLine(mLeft + pos, mTop, mLeft + pos, mTop + 4); else mDC->DrawLine(mLeft + pos, mBottom - 4, mLeft + pos, mBottom); } else { if (mFlip) mDC->DrawLine(mLeft, mTop + pos, mLeft + 4, mTop + pos); else mDC->DrawLine(mRight - 4, mTop + pos, mRight, mTop + pos); } if (mMajorLabels[i].text != wxT("")) mDC->DrawText(mMajorLabels[i].text, mMajorLabels[i].lx, mMajorLabels[i].ly); } mDC->SetFont(*mMinorFont); for(i=0; i<mNumMinor; i++) { int pos = mMinorLabels[i].pos; if (mOrientation == wxHORIZONTAL) { if (mFlip) mDC->DrawLine(mLeft + pos, mTop, mLeft + pos, mTop + 2); else mDC->DrawLine(mLeft + pos, mBottom - 2, mLeft + pos, mBottom); } else { if (mFlip) mDC->DrawLine(mLeft, mTop + pos, mLeft + 2, mTop + pos); else mDC->DrawLine(mRight - 2, mTop + pos, mRight, mTop + pos); } if (mMinorLabels[i].text != wxT("")) mDC->DrawText(mMinorLabels[i].text, mMinorLabels[i].lx, mMinorLabels[i].ly); }}//// RulerPanel//BEGIN_EVENT_TABLE(RulerPanel, wxPanel) EVT_PAINT(RulerPanel::OnPaint) EVT_SIZE(RulerPanel::OnSize)END_EVENT_TABLE()IMPLEMENT_CLASS(RulerPanel, wxPanel)RulerPanel::RulerPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos /*= wxDefaultPosition*/, const wxSize& size /*= wxDefaultSize*/): wxPanel(parent, id, pos, size){ int width, height; GetClientSize(&width, &height); ruler.SetBounds(0, 0, width, height);}RulerPanel::~RulerPanel(){}void RulerPanel::OnPaint(wxPaintEvent &evt){ wxPaintDC dc(this); ruler.Draw(dc);}void RulerPanel::OnSize(wxSizeEvent &evt){ int width, height; GetClientSize(&width, &height); ruler.SetBounds(0, 0, width-1, height-1); Refresh(false);}/********************************************************************** Implementation of AdornedRulerPanel. Either we find a way to make this more generic, Or it will move out of the widgets subdirectory into its own source file.**********************************************************************///#include <math.h>//#include <wx/dcscreen.h>//#include "Ruler.h"#include "../ViewInfo.h"#include "../AColor.h"#if 0AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size ) : RulerPanel( parent, id, pos, size ){ ruler.SetLabelEdges(false); ruler.SetFormat(Ruler::TimeFormat);}#endifAdornedRulerPanel::AdornedRulerPanel(){ ruler.SetLabelEdges(false); ruler.SetFormat(Ruler::TimeFormat);}AdornedRulerPanel::~AdornedRulerPanel(){}void AdornedRulerPanel::SetSize( const wxRect & r ){ mRect = r;}void AdornedRulerPanel::GetSize( int * width, int * height ){ *width = mRect.width; *height= mRect.height;}void AdornedRulerPanel::DrawAdornedRuler( wxDC * dc, ViewInfo * pViewInfo, bool text, bool indicator, bool bRecording){ wxRect r; mViewInfo = pViewInfo; GetSize(&r.width, &r.height); r.x = 0; r.y = 0; DrawBorder(dc, r); if (pViewInfo->sel0 < pViewInfo->sel1) DrawSelection(dc, r); if( indicator ) DrawIndicator(dc, bRecording); DrawMarks(dc, r, text);}void AdornedRulerPanel::DrawBorder(wxDC * dc, wxRect & r){ // Draw AdornedRulerPanel border AColor::Medium(dc, false); dc->DrawRectangle(r); r.width--; r.height--; AColor::Bevel(*dc, true, r); dc->SetPen(*wxBLACK_PEN); dc->DrawLine(r.x, r.y + r.height + 1, r.x + r.width + 1, r.y + r.height + 1);}void AdornedRulerPanel::DrawSelection(wxDC * dc, const wxRect r){ // Draw selection double sel0 = mViewInfo->sel0 - mViewInfo->h + GetLeftOffset() / mViewInfo->zoom; double sel1 = mViewInfo->sel1 - mViewInfo->h + GetLeftOffset() / mViewInfo->zoom; if (sel0 < 0.0) sel0 = 0.0; if (sel1 > (r.width / mViewInfo->zoom)) sel1 = r.width / mViewInfo->zoom; int p0 = int (sel0 * mViewInfo->zoom + 0.5); int p1 = int (sel1 * mViewInfo->zoom + 0.5); wxBrush selectedBrush; selectedBrush.SetColour(148, 148, 170); wxPen selectedPen; selectedPen.SetColour(148, 148, 170); dc->SetBrush(selectedBrush); dc->SetPen(selectedPen); wxRect sr; sr.x = p0; sr.y = 1; sr.width = p1 - p0 - 1; sr.height = GetRulerHeight() - 3; dc->DrawRectangle(sr);}void AdornedRulerPanel::DrawMarks(wxDC * dc, const wxRect r, bool /*text */ ){ ruler.SetBounds(r.x, r.y, r.x + r.width - 1, r.y + r.height - 1); double min = mViewInfo->h - GetLeftOffset() / mViewInfo->zoom; double max = min + r.width / mViewInfo->zoom; ruler.SetRange(min, max); ruler.Draw(*dc);}////This draws the little triangular indicator on the //AdornedRulerPanel.//void AdornedRulerPanel::DrawIndicator(wxDC * dc, bool bRecording){ // Draw indicator double ind = indicatorPos; if (ind >= mViewInfo->h && ind <= (mViewInfo->h + mViewInfo->screen)) { int indp = GetLeftOffset() + int ((ind - mViewInfo->h) * mViewInfo->zoom); AColor::IndicatorColor(dc, bRecording );// dc->SetPen(*wxTRANSPARENT_PEN);// dc->SetBrush(*wxBLACK_BRUSH); int indsize = 6; wxPoint tri[3]; tri[0].x = indp; tri[0].y = (indsize * 3)/2 + 1; tri[1].x = indp - indsize; tri[1].y = 1; tri[2].x = indp + indsize; tri[2].y = 1; dc->DrawPolygon(3, tri); }}// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: 126e06c2-f0c8-490f-bdd6-12581013f13f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -