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
This commit is contained in:
parent
e1aed9319d
commit
42f70a5d3d
@ -28,6 +28,7 @@ DrawButton::~DrawButton(void)
|
||||
void
|
||||
DrawButton::AttachedToWindow()
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
ReplaceTransparentColor(&fOn, Parent()->ViewColor());
|
||||
ReplaceTransparentColor(&fOff, Parent()->ViewColor());
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -7,16 +7,13 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
@ -11,6 +11,23 @@
|
||||
#include <Bitmap.h>
|
||||
#include <Font.h>
|
||||
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user