From 42f70a5d3d3b1c904e2dd8ff63abdf0623b02faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 4 Jun 2006 13:49:44 +0000 Subject: [PATCH] TrackSlider now uses an offscreen bitmap to avoid flickering on side thumbs I'm not so pleased with the code, though it works nice on Dano at least. Still lot of graphics bugs on Haiku DrawButton is now transparent little refactoring in ScopeView git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17718 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/soundrecorder/DrawButton.cpp | 1 + src/apps/soundrecorder/ScopeView.cpp | 10 +- src/apps/soundrecorder/TrackSlider.cpp | 709 +++++++++++++------------ src/apps/soundrecorder/TrackSlider.h | 31 +- 4 files changed, 412 insertions(+), 339 deletions(-) diff --git a/src/apps/soundrecorder/DrawButton.cpp b/src/apps/soundrecorder/DrawButton.cpp index 79e542e2f3..c4a42f485c 100644 --- a/src/apps/soundrecorder/DrawButton.cpp +++ b/src/apps/soundrecorder/DrawButton.cpp @@ -28,6 +28,7 @@ DrawButton::~DrawButton(void) void DrawButton::AttachedToWindow() { + SetViewColor(B_TRANSPARENT_COLOR); ReplaceTransparentColor(&fOn, Parent()->ViewColor()); ReplaceTransparentColor(&fOff, Parent()->ViewColor()); } diff --git a/src/apps/soundrecorder/ScopeView.cpp b/src/apps/soundrecorder/ScopeView.cpp index 091399ea6c..fc22607ffa 100644 --- a/src/apps/soundrecorder/ScopeView.cpp +++ b/src/apps/soundrecorder/ScopeView.cpp @@ -23,6 +23,7 @@ ScopeView::ScopeView(BRect rect, uint32 resizeFlags) : BView(rect, "scope", resizeFlags, B_WILL_DRAW | B_FRAME_EVENTS), fThreadId(-1), fBitmap(NULL), + fBitmapView(NULL), fIsRendering(false), fMediaTrack(NULL), fQuitting(false), @@ -31,14 +32,6 @@ ScopeView::ScopeView(BRect rect, uint32 resizeFlags) fLeftTime(0), fTotalTime(1000000) { - fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true); - memset(fBitmap->Bits(), 0, fBitmap->BitsLength()); - - rect.OffsetToSelf(B_ORIGIN); - rect.right -= 2; - fBitmapView = new BView(rect.OffsetToSelf(B_ORIGIN), "bitmapView", B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW); - fBitmap->AddChild(fBitmapView); - fRenderSem = create_sem(0, "scope rendering"); fHeight = Bounds().Height(); } @@ -54,6 +47,7 @@ void ScopeView::AttachedToWindow() { SetViewColor(B_TRANSPARENT_COLOR); + InitBitmap(); Run(); } diff --git a/src/apps/soundrecorder/TrackSlider.cpp b/src/apps/soundrecorder/TrackSlider.cpp index 7eddfd81d3..1600590331 100644 --- a/src/apps/soundrecorder/TrackSlider.cpp +++ b/src/apps/soundrecorder/TrackSlider.cpp @@ -7,16 +7,13 @@ #include #include +#include #include "TrackSlider.h" #include "icon_button.h" TrackSlider::TrackSlider(BRect rect, const char *title, BMessage *msg, uint32 resizeFlags) : BControl(rect, "slider", NULL, msg, resizeFlags, B_WILL_DRAW | B_FRAME_EVENTS), - leftBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8), - rightBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8), - leftThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8), - rightThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8), fLeftTime(0), fRightTime(1000000), fMainTime(0), fTotalTime(1000000), fLeftTracking(false), fRightTracking(false), fMainTracking(false) { @@ -33,27 +30,13 @@ TrackSlider::TrackSlider(BRect rect, const char *title, BMessage *msg, uint32 re break; } } - leftBitmap.SetBits(kLeftTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8); - rightBitmap.SetBits(kRightTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8); - leftThumbBitmap.SetBits(kLeftThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8); - rightThumbBitmap.SetBits(kRightThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8); - - fRight = Bounds().right - kLeftRightTrackSliderWidth; - if (fTotalTime == 0) { - fLeftX = 14; - fRightX = fRight; - fPositionX = 15; - } else { - fLeftX = 14 + (fRight - 15) * ((double)fLeftTime / fTotalTime); - fRightX = 15 + (fRight - 16) * ((double)fRightTime / fTotalTime); - fPositionX = 15 + (fRight - 14) * ((double)fMainTime / fTotalTime); - } + } TrackSlider::~TrackSlider() { - + delete fBitmap; } @@ -62,14 +45,392 @@ TrackSlider::AttachedToWindow() { BControl::AttachedToWindow(); SetViewColor(B_TRANSPARENT_COLOR); + InitBitmap(); + RenderBitmap(); } +void +TrackSlider::InitBitmap() +{ + if (fBitmapView) { + fBitmap->RemoveChild(fBitmapView); + delete fBitmapView; + } + if (fBitmap) + delete fBitmap; + + BRect rect = Bounds(); + + fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true); + + fBitmapView = new SliderOffscreenView(rect.OffsetToSelf(B_ORIGIN), "bitmapView"); + fBitmap->AddChild(fBitmapView); + + fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth; + if (fTotalTime == 0) { + fBitmapView->fLeftX = 14; + fBitmapView->fRightX = fBitmapView->fRight; + fBitmapView->fPositionX = 15; + } else { + fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime); + fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime); + fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime); + } +} + #define SLIDER_BASE 10 +void +TrackSlider::RenderBitmap() +{ + /* rendering */ + if (fBitmap->Lock()) { + fBitmapView->DrawX(); + fBitmap->Unlock(); + } +} + + void TrackSlider::Draw(BRect updateRect) { + DrawBitmapAsync(fBitmap, BPoint(0,0)); + + DrawCounter(fMainTime, fBitmapView->fPositionX, fMainTracking); + if (fLeftTracking) + DrawCounter(fLeftTime, fBitmapView->fLeftX, fLeftTracking); + else if (fRightTracking) + DrawCounter(fRightTime, fBitmapView->fRightX, fRightTracking); + + DrawMarker(fBitmapView->fPositionX); + + Sync(); +} + + +void +TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking) +{ + // timecounter + + rgb_color gray = {128,128,128}; + rgb_color blue = {0,0,140}; + rgb_color blue2 = {146,146,214}; + rgb_color white = {255,255,255}; + + char string[12]; + TimeToString(timestamp, string); + int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2; + + float counterX = position; + if (counterX < 39) + counterX = 39; + if (counterX > fBitmapView->fRight - 23) + counterX = fBitmapView->fRight - 23; + + BeginLineArray(4); + if (!isTracking) { + AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), gray); + AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-8), gray); + AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), white); + AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), white); + SetHighColor(216,216,216); + } else { + AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), blue); + AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), blue2); + AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), blue2); + AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+3,SLIDER_BASE-9), blue2); + SetHighColor(48,48,241); + } + EndLineArray(); + FillRect(BRect(counterX-halfwidth-3,SLIDER_BASE-8,counterX+halfwidth+3,SLIDER_BASE)); + + SetDrawingMode(B_OP_COPY); + if (isTracking) + SetHighColor(255,255,255); + else + SetHighColor(0,0,0); + SetLowColor(ViewColor()); + + SetFont(&fFont); + DrawString(string, BPoint(counterX-halfwidth, SLIDER_BASE-1)); + +} + + +void +TrackSlider::DrawMarker(float position) +{ + rgb_color black = {0,0,0}; + rgb_color rose = {255,152,152}; + rgb_color red = {255,0,0}; + rgb_color bordeau = {178,0,0}; + rgb_color white = {255,255,255}; + + BeginLineArray(30); + AddLine(BPoint(position,SLIDER_BASE+7), BPoint(position-4,SLIDER_BASE+3), black); + AddLine(BPoint(position-4,SLIDER_BASE+3), BPoint(position-4,SLIDER_BASE+1), black); + AddLine(BPoint(position-4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+1), black); + AddLine(BPoint(position+4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+3), black); + AddLine(BPoint(position+4,SLIDER_BASE+3), BPoint(position,SLIDER_BASE+7), black); + + + AddLine(BPoint(position-3,SLIDER_BASE+2), BPoint(position+3,SLIDER_BASE+2), rose); + AddLine(BPoint(position-3,SLIDER_BASE+3), BPoint(position-1,SLIDER_BASE+5), rose); + + AddLine(BPoint(position-2,SLIDER_BASE+3), BPoint(position+2,SLIDER_BASE+3), red); + AddLine(BPoint(position-1,SLIDER_BASE+4), BPoint(position+1,SLIDER_BASE+4), red); + AddLine(BPoint(position,SLIDER_BASE+5), BPoint(position,SLIDER_BASE+5), red); + + AddLine(BPoint(position,SLIDER_BASE+6), BPoint(position+3,SLIDER_BASE+3), bordeau); + + AddLine(BPoint(position,SLIDER_BASE+12), BPoint(position-4,SLIDER_BASE+16), black); + AddLine(BPoint(position-4,SLIDER_BASE+16), BPoint(position-4,SLIDER_BASE+17), black); + AddLine(BPoint(position-4,SLIDER_BASE+17), BPoint(position+4,SLIDER_BASE+17), black); + AddLine(BPoint(position+4,SLIDER_BASE+17), BPoint(position+4,SLIDER_BASE+16), black); + AddLine(BPoint(position+4,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+12), black); + AddLine(BPoint(position-4,SLIDER_BASE+18), BPoint(position+4,SLIDER_BASE+18), white); + + AddLine(BPoint(position-3,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+13), rose); + + AddLine(BPoint(position-2,SLIDER_BASE+16), BPoint(position+2,SLIDER_BASE+16), red); + AddLine(BPoint(position-1,SLIDER_BASE+15), BPoint(position+1,SLIDER_BASE+15), red); + AddLine(BPoint(position,SLIDER_BASE+14), BPoint(position,SLIDER_BASE+14), red); + + AddLine(BPoint(position+1,SLIDER_BASE+14), BPoint(position+3,SLIDER_BASE+16), bordeau); + + EndLineArray(); +} + + +void +TrackSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + if (!IsTracking()) + return; + + uint32 mouseButtons; + BPoint where; + GetMouse(&where, &mouseButtons, true); + + // button not pressed, exit + if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) { + Invoke(); + SetTracking(false); + } + + UpdatePosition(point); +} + + +void +TrackSlider::MouseDown(BPoint point) +{ + if (!Bounds().InsetBySelf(2,2).Contains(point)) + return; + + UpdatePosition(point); + SetTracking(true); + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS); +} + + +void +TrackSlider::MouseUp(BPoint point) +{ + if (!IsTracking()) + return; + if (Bounds().InsetBySelf(2,2).Contains(point)) { + UpdatePosition(point); + } + + fLeftTracking = fRightTracking = fMainTracking = false; + + Invoke(); + SetTracking(false); + Draw(Bounds()); + Flush(); +} + + +void +TrackSlider::UpdatePosition(BPoint point) +{ + BRect leftRect(fBitmapView->fLeftX-9, SLIDER_BASE+3, fBitmapView->fLeftX, SLIDER_BASE+16); + BRect rightRect(fBitmapView->fRightX, SLIDER_BASE+3, fBitmapView->fRightX+9, SLIDER_BASE+16); + + if (!(fRightTracking || fMainTracking) && (fLeftTracking || ((point.x < fBitmapView->fPositionX-4) && leftRect.Contains(point)))) { + if (!IsTracking()) + fBitmapView->fLastX = point.x - fBitmapView->fLeftX; + fBitmapView->fLeftX = MIN(MAX(point.x - fBitmapView->fLastX, 15), fBitmapView->fRight); + fLeftTime = (bigtime_t)(MAX(MIN((fBitmapView->fLeftX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime); + fLeftTracking = true; + + BMessage msg = *Message(); + msg.AddInt64("left", fLeftTime); + + if (fBitmapView->fPositionX < fBitmapView->fLeftX) { + fBitmapView->fPositionX = fBitmapView->fLeftX + 1; + fMainTime = fLeftTime; + msg.AddInt64("main", fMainTime); + if (fBitmapView->fRightX < fBitmapView->fPositionX) { + fBitmapView->fRightX = fBitmapView->fPositionX; + fRightTime = fMainTime; + msg.AddInt64("right", fRightTime); + } + } + + Invoke(&msg); + RenderBitmap(); + + //printf("fLeftPos : %Ld\n", fLeftTime); + } else if (!fMainTracking && (fRightTracking || ((point.x > fBitmapView->fPositionX+4) && rightRect.Contains(point)))) { + if (!IsTracking()) + fBitmapView->fLastX = point.x - fBitmapView->fRightX; + fBitmapView->fRightX = MIN(MAX(point.x - fBitmapView->fLastX, 15), fBitmapView->fRight); + fRightTime = (bigtime_t)(MAX(MIN((fBitmapView->fRightX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime); + fRightTracking = true; + + BMessage msg = *Message(); + msg.AddInt64("right", fRightTime); + + if (fBitmapView->fPositionX > fBitmapView->fRightX) { + fBitmapView->fPositionX = fBitmapView->fRightX; + fMainTime = fRightTime; + msg.AddInt64("main", fMainTime); + if (fBitmapView->fLeftX > fBitmapView->fPositionX) { + fBitmapView->fLeftX = fBitmapView->fPositionX - 1; + fLeftTime = fMainTime; + msg.AddInt64("left", fLeftTime); + } + } + + Invoke(&msg); + RenderBitmap(); + + //printf("fRightPos : %Ld\n", fRightTime); + } else { + fBitmapView->fPositionX = MIN(MAX(point.x, 15), fBitmapView->fRight); + fMainTime = (bigtime_t)(MAX(MIN((fBitmapView->fPositionX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime); + fMainTracking = true; + + BMessage msg = *Message(); + msg.AddInt64("main", fMainTime); + + if (fBitmapView->fRightX < fBitmapView->fPositionX) { + fBitmapView->fRightX = fBitmapView->fPositionX; + fRightTime = fMainTime; + msg.AddInt64("right", fRightTime); + RenderBitmap(); + } else if (fBitmapView->fLeftX > fBitmapView->fPositionX) { + fBitmapView->fLeftX = fBitmapView->fPositionX - 1; + fLeftTime = fMainTime; + msg.AddInt64("left", fLeftTime); + RenderBitmap(); + } + + Invoke(&msg); + //printf("fPosition : %Ld\n", fMainTime); + } + Draw(Bounds()); + Flush(); +} + + +void +TrackSlider::TimeToString(bigtime_t timestamp, char *string) +{ + uint32 hours = timestamp / 3600000000LL; + timestamp -= hours * 3600000000LL; + uint32 minutes = timestamp / 60000000LL; + timestamp -= minutes * 60000000LL; + uint32 seconds = timestamp / 1000000LL; + timestamp -= seconds * 1000000LL; + uint32 centiseconds = timestamp / 10000LL; + sprintf(string, "%02ld:%02ld:%02ld:%02ld", hours, minutes, seconds, centiseconds); + +} + + +void +TrackSlider::SetMainTime(bigtime_t timestamp, bool reset) +{ + fMainTime = timestamp; + fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime); + if (reset) { + fRightTime = fTotalTime; + fLeftTime = 0; + fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime); + fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime); + } + Invalidate(); +} + +void +TrackSlider::SetTotalTime(bigtime_t timestamp, bool reset) +{ + fTotalTime = timestamp; + if (reset) { + fMainTime = 0; + fRightTime = fTotalTime; + fLeftTime = 0; + } + fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime); + fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime); + fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime); + Invalidate(); +} + + +void +TrackSlider::ResetMainTime() +{ + fMainTime = fLeftTime; + fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime); + Invalidate(); +} + + +void +TrackSlider::FrameResized(float width, float height) +{ + fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth; + fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime); + InitBitmap(); + fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime); + fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime); + RenderBitmap(); + Invalidate(); +} + + +SliderOffscreenView::SliderOffscreenView(BRect frame, char *name) + : BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW), + leftBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8), + rightBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8), + leftThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8), + rightThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8) +{ + leftBitmap.SetBits(kLeftTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8); + rightBitmap.SetBits(kRightTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8); + leftThumbBitmap.SetBits(kLeftThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8); + rightThumbBitmap.SetBits(kRightThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8); +} + + +SliderOffscreenView::~SliderOffscreenView() +{ + +} + + +void +SliderOffscreenView::DrawX() +{ + SetHighColor(216,216,216); + FillRect(Bounds()); + SetHighColor(189,186,189); StrokeLine(BPoint(11,SLIDER_BASE+1), BPoint(fRight,SLIDER_BASE+1)); SetHighColor(0,0,0); @@ -78,17 +439,8 @@ TrackSlider::Draw(BRect updateRect) StrokeLine(BPoint(11,SLIDER_BASE+17), BPoint(fRight,SLIDER_BASE+17)); SetHighColor(231,227,231); StrokeLine(BPoint(11,SLIDER_BASE+18), BPoint(fRight,SLIDER_BASE+18)); - + SetDrawingMode(B_OP_OVER); - - SetHighColor(216,216,216); - FillRect(BRect(0,1,fPositionX < 18 ? 18 : fPositionX-22,SLIDER_BASE)); - FillRect(BRect(fPositionX < 18 ? 65 : fPositionX > fRight - 3 ? fRight : fPositionX+22,0,Bounds().right,SLIDER_BASE)); - FillRect(BRect(0,0,Bounds().right,0)); - FillRect(BRect(0,SLIDER_BASE+18,Bounds().right,SLIDER_BASE+21)); - FillRect(BRect(0,0,10,SLIDER_BASE+21)); - FillRect(BRect(Bounds().right - 10,0,Bounds().right,SLIDER_BASE+21)); - SetLowColor(HighColor()); BPoint leftPoint(5,SLIDER_BASE+1); @@ -97,7 +449,7 @@ TrackSlider::Draw(BRect updateRect) BPoint rightPoint(fRight + 1,SLIDER_BASE+1); DrawBitmapAsync(&rightBitmap, BRect(BPoint(5,0), kLeftRightTrackSliderSize), BRect(rightPoint, rightPoint+kLeftRightTrackSliderSize-BPoint(5,0))); - + SetHighColor(153,153,153); FillRect(BRect(11,SLIDER_BASE+3,fLeftX-9,SLIDER_BASE+16)); FillRect(BRect(fRightX+9,SLIDER_BASE+3,fRight,SLIDER_BASE+16)); @@ -172,298 +524,5 @@ TrackSlider::Draw(BRect updateRect) DrawBitmapAsync(&rightThumbBitmap, BRect(BPoint(6,0), kLeftRightThumbSize), BRect(rightThumbPoint, rightThumbPoint+kLeftRightThumbSize-BPoint(6,0))); - rgb_color black = {0,0,0}; - rgb_color rose = {255,152,152}; - rgb_color red = {255,0,0}; - rgb_color bordeau = {178,0,0}; - rgb_color white = {255,255,255}; - - DrawCounter(fMainTime, fPositionX, fMainTracking); - if (fLeftTracking) - DrawCounter(fLeftTime, fLeftX, fLeftTracking); - else if (fRightTracking) - DrawCounter(fRightTime, fRightX, fRightTracking); - - BeginLineArray(30); - AddLine(BPoint(fPositionX,SLIDER_BASE+7), BPoint(fPositionX-4,SLIDER_BASE+3), black); - AddLine(BPoint(fPositionX-4,SLIDER_BASE+3), BPoint(fPositionX-4,SLIDER_BASE+1), black); - AddLine(BPoint(fPositionX-4,SLIDER_BASE+1), BPoint(fPositionX+4,SLIDER_BASE+1), black); - AddLine(BPoint(fPositionX+4,SLIDER_BASE+1), BPoint(fPositionX+4,SLIDER_BASE+3), black); - AddLine(BPoint(fPositionX+4,SLIDER_BASE+3), BPoint(fPositionX,SLIDER_BASE+7), black); - - - AddLine(BPoint(fPositionX-3,SLIDER_BASE+2), BPoint(fPositionX+3,SLIDER_BASE+2), rose); - AddLine(BPoint(fPositionX-3,SLIDER_BASE+3), BPoint(fPositionX-1,SLIDER_BASE+5), rose); - - AddLine(BPoint(fPositionX-2,SLIDER_BASE+3), BPoint(fPositionX+2,SLIDER_BASE+3), red); - AddLine(BPoint(fPositionX-1,SLIDER_BASE+4), BPoint(fPositionX+1,SLIDER_BASE+4), red); - AddLine(BPoint(fPositionX,SLIDER_BASE+5), BPoint(fPositionX,SLIDER_BASE+5), red); - - AddLine(BPoint(fPositionX,SLIDER_BASE+6), BPoint(fPositionX+3,SLIDER_BASE+3), bordeau); - - AddLine(BPoint(fPositionX,SLIDER_BASE+12), BPoint(fPositionX-4,SLIDER_BASE+16), black); - AddLine(BPoint(fPositionX-4,SLIDER_BASE+16), BPoint(fPositionX-4,SLIDER_BASE+17), black); - AddLine(BPoint(fPositionX-4,SLIDER_BASE+17), BPoint(fPositionX+4,SLIDER_BASE+17), black); - AddLine(BPoint(fPositionX+4,SLIDER_BASE+17), BPoint(fPositionX+4,SLIDER_BASE+16), black); - AddLine(BPoint(fPositionX+4,SLIDER_BASE+16), BPoint(fPositionX,SLIDER_BASE+12), black); - AddLine(BPoint(fPositionX-4,SLIDER_BASE+18), BPoint(fPositionX+4,SLIDER_BASE+18), white); - - AddLine(BPoint(fPositionX-3,SLIDER_BASE+16), BPoint(fPositionX,SLIDER_BASE+13), rose); - - AddLine(BPoint(fPositionX-2,SLIDER_BASE+16), BPoint(fPositionX+2,SLIDER_BASE+16), red); - AddLine(BPoint(fPositionX-1,SLIDER_BASE+15), BPoint(fPositionX+1,SLIDER_BASE+15), red); - AddLine(BPoint(fPositionX,SLIDER_BASE+14), BPoint(fPositionX,SLIDER_BASE+14), red); - - AddLine(BPoint(fPositionX+1,SLIDER_BASE+14), BPoint(fPositionX+3,SLIDER_BASE+16), bordeau); - - EndLineArray(); - - - - Flush(); -} - - -void -TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking) -{ - // timecounter - - rgb_color gray = {128,128,128}; - rgb_color blue = {0,0,140}; - rgb_color blue2 = {146,146,214}; - rgb_color white = {255,255,255}; - - char string[12]; - TimeToString(timestamp, string); - int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2; - - float counterX = position; - if (counterX < 39) - counterX = 39; - if (counterX > fRight - 23) - counterX = fRight - 23; - - BeginLineArray(4); - if (!isTracking) { - AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), gray); - AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-8), gray); - AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), white); - AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), white); - SetHighColor(216,216,216); - } else { - AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), blue); - AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), blue2); - AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), blue2); - AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+3,SLIDER_BASE-9), blue2); - SetHighColor(48,48,241); - } - EndLineArray(); - FillRect(BRect(counterX-halfwidth-3,SLIDER_BASE-8,counterX+halfwidth+3,SLIDER_BASE)); - - SetDrawingMode(B_OP_COPY); - if (isTracking) - SetHighColor(255,255,255); - else - SetHighColor(0,0,0); - SetLowColor(ViewColor()); - - SetFont(&fFont); - DrawString(string, BPoint(counterX-halfwidth, SLIDER_BASE-1)); - -} - - -void -TrackSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - if (!IsTracking()) - return; - - uint32 mouseButtons; - BPoint where; - GetMouse(&where, &mouseButtons, true); - - // button not pressed, exit - if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) { - Invoke(); - SetTracking(false); - } - - UpdatePosition(point); -} - - -void -TrackSlider::MouseDown(BPoint point) -{ - if (!Bounds().InsetBySelf(2,2).Contains(point)) - return; - - UpdatePosition(point); - SetTracking(true); - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY| B_LOCK_WINDOW_FOCUS); -} - - -void -TrackSlider::MouseUp(BPoint point) -{ - if (!IsTracking()) - return; - if (Bounds().InsetBySelf(2,2).Contains(point)) { - UpdatePosition(point); - } - - fLeftTracking = fRightTracking = fMainTracking = false; - - Invoke(); - SetTracking(false); - Draw(Bounds()); - Flush(); -} - - -void -TrackSlider::UpdatePosition(BPoint point) -{ - BRect leftRect(fLeftX-9, SLIDER_BASE+3, fLeftX, SLIDER_BASE+16); - BRect rightRect(fRightX, SLIDER_BASE+3, fRightX+9, SLIDER_BASE+16); - - if (!(fRightTracking || fMainTracking) && (fLeftTracking || ((point.x < fPositionX-4) && leftRect.Contains(point)))) { - if (!IsTracking()) - fLastX = point.x - fLeftX; - fLeftX = MIN(MAX(point.x - fLastX, 15), fRight); - fLeftTime = (bigtime_t)(MAX(MIN((fLeftX - 15) / (fRight - 14),1), 0) * fTotalTime); - fLeftTracking = true; - - BMessage msg = *Message(); - msg.AddInt64("left", fLeftTime); - - if (fPositionX < fLeftX) { - fPositionX = fLeftX + 1; - fMainTime = fLeftTime; - msg.AddInt64("main", fMainTime); - if (fRightX < fPositionX) { - fRightX = fPositionX; - fRightTime = fMainTime; - msg.AddInt64("right", fRightTime); - } - } - - Invoke(&msg); - - //printf("fLeftPos : %Ld\n", fLeftTime); - } else if (!fMainTracking && (fRightTracking || ((point.x > fPositionX+4) && rightRect.Contains(point)))) { - if (!IsTracking()) - fLastX = point.x - fRightX; - fRightX = MIN(MAX(point.x - fLastX, 15), fRight); - fRightTime = (bigtime_t)(MAX(MIN((fRightX - 15) / (fRight - 14),1), 0) * fTotalTime); - fRightTracking = true; - - BMessage msg = *Message(); - msg.AddInt64("right", fRightTime); - - if (fPositionX > fRightX) { - fPositionX = fRightX; - fMainTime = fRightTime; - msg.AddInt64("main", fMainTime); - if (fLeftX > fPositionX) { - fLeftX = fPositionX - 1; - fLeftTime = fMainTime; - msg.AddInt64("left", fLeftTime); - } - } - - Invoke(&msg); - - //printf("fRightPos : %Ld\n", fRightTime); - } else { - fPositionX = MIN(MAX(point.x, 15), fRight); - fMainTime = (bigtime_t)(MAX(MIN((fPositionX - 15) / (fRight - 14),1), 0) * fTotalTime); - fMainTracking = true; - - BMessage msg = *Message(); - msg.AddInt64("main", fMainTime); - - if (fRightX < fPositionX) { - fRightX = fPositionX; - fRightTime = fMainTime; - msg.AddInt64("right", fRightTime); - } else if (fLeftX > fPositionX) { - fLeftX = fPositionX - 1; - fLeftTime = fMainTime; - msg.AddInt64("left", fLeftTime); - } - - Invoke(&msg); - //printf("fPosition : %Ld\n", fMainTime); - } - Draw(Bounds()); - Flush(); -} - - -void -TrackSlider::TimeToString(bigtime_t timestamp, char *string) -{ - uint32 hours = timestamp / 3600000000LL; - timestamp -= hours * 3600000000LL; - uint32 minutes = timestamp / 60000000LL; - timestamp -= minutes * 60000000LL; - uint32 seconds = timestamp / 1000000LL; - timestamp -= seconds * 1000000LL; - uint32 centiseconds = timestamp / 10000LL; - sprintf(string, "%02ld:%02ld:%02ld:%02ld", hours, minutes, seconds, centiseconds); - -} - - -void -TrackSlider::SetMainTime(bigtime_t timestamp, bool reset) -{ - fMainTime = timestamp; - fPositionX = 15 + (fRight - 14) * ((double)fMainTime / fTotalTime); - if (reset) { - fRightTime = fTotalTime; - fLeftTime = 0; - fLeftX = 14 + (fRight - 15) * ((double)fLeftTime / fTotalTime); - fRightX = 15 + (fRight - 16) * ((double)fRightTime / fTotalTime); - } - Invalidate(); -} - -void -TrackSlider::SetTotalTime(bigtime_t timestamp, bool reset) -{ - fTotalTime = timestamp; - if (reset) { - fMainTime = 0; - fRightTime = fTotalTime; - fLeftTime = 0; - } - fPositionX = 15 + (fRight - 14) * ((double)fMainTime / fTotalTime); - fLeftX = 14 + (fRight - 15) * ((double)fLeftTime / fTotalTime); - fRightX = 15 + (fRight - 16) * ((double)fRightTime / fTotalTime); - Invalidate(); -} - - -void -TrackSlider::ResetMainTime() -{ - fMainTime = fLeftTime; - fPositionX = 15 + (fRight - 14) * ((double)fMainTime / fTotalTime); - Invalidate(); -} - - -void -TrackSlider::FrameResized(float width, float height) -{ - fRight = Bounds().right - kLeftRightTrackSliderWidth; - fPositionX = 15 + (fRight - 14) * ((double)fMainTime / fTotalTime); - fLeftX = 14 + (fRight - 15) * ((double)fLeftTime / fTotalTime); - fRightX = 15 + (fRight - 16) * ((double)fRightTime / fTotalTime); - Invalidate(); + Sync(); } diff --git a/src/apps/soundrecorder/TrackSlider.h b/src/apps/soundrecorder/TrackSlider.h index be43902582..711ebf41bf 100644 --- a/src/apps/soundrecorder/TrackSlider.h +++ b/src/apps/soundrecorder/TrackSlider.h @@ -11,6 +11,23 @@ #include #include +class SliderOffscreenView : public BView { + +public: + SliderOffscreenView(BRect frame, char *name); + virtual ~SliderOffscreenView(); + virtual void DrawX(); + + BBitmap leftBitmap, rightBitmap; + BBitmap leftThumbBitmap, rightThumbBitmap; + float fRight; + + float fLeftX; + float fRightX; + float fPositionX; + float fLastX; +}; + class TrackSlider : public BControl { public: @@ -30,25 +47,27 @@ public: virtual void FrameResized(float width, float height); private: void DrawCounter(bigtime_t timestamp, float position, bool isTracking); + void DrawMarker(float position); void TimeToString(bigtime_t timestamp, char *string); void UpdatePosition(BPoint point); - BBitmap leftBitmap, rightBitmap, leftThumbBitmap, rightThumbBitmap; - float fRight; + void InitBitmap(); + void RenderBitmap(); + bigtime_t fLeftTime; bigtime_t fRightTime; bigtime_t fMainTime; bigtime_t fTotalTime; - float fPositionX; - float fLeftX; - float fRightX; - float fLastX; bool fLeftTracking; bool fRightTracking; bool fMainTracking; BFont fFont; + BBitmap *fBitmap; + SliderOffscreenView *fBitmapView; + }; + #endif /* TRACKSLIDER_H */