From 1abde80b3b6b9a7d0e3ec23e9a799bb381af65ca Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 28 Nov 2017 14:07:02 +0100 Subject: [PATCH] ZipOMatic: modernize barberpole widget * Use the code/graphic of the new barberpole (Haikudepot) * See #13808 * I hope soon we will have a system standard widget --- .../tracker/zipomatic/ZipOMaticActivity.cpp | 233 +++++++++--------- .../tracker/zipomatic/ZipOMaticActivity.h | 15 +- 2 files changed, 133 insertions(+), 115 deletions(-) diff --git a/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp b/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp index e087c8e350..d9003aad82 100644 --- a/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp +++ b/src/add-ons/tracker/zipomatic/ZipOMaticActivity.cpp @@ -9,6 +9,8 @@ #include "ZipOMaticActivity.h" +#include + #include @@ -16,17 +18,15 @@ Activity::Activity(const char* name) : BView(name, B_WILL_DRAW | B_FRAME_EVENTS), fIsRunning(false), - fBitmap(NULL) + fBitmap(NULL), + fSpinSpeed(0.15), + fColors(NULL), + fNumColors(0), + fScrollOffset(0.0), + fStripeWidth(0.0), + fNumStripes(0) { - fPattern.data[0] = 0x0f; - fPattern.data[1] = 0x1e; - fPattern.data[2] = 0x3c; - fPattern.data[3] = 0x78; - fPattern.data[4] = 0xf0; - fPattern.data[5] = 0xe1; - fPattern.data[6] = 0xc3; - fPattern.data[7] = 0x87; - + _InactiveColors(); SetExplicitMinSize(BSize(17, 17)); SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 17)); }; @@ -35,14 +35,15 @@ Activity::Activity(const char* name) Activity::~Activity() { delete fBitmap; + delete[] fColors; } void Activity::AllAttached() { - SetViewColor(B_TRANSPARENT_COLOR); _CreateBitmap(); + FrameResized(Bounds().Width(), Bounds().Height()); } @@ -50,6 +51,7 @@ void Activity::Start() { fIsRunning = true; + _ActiveColors(); Window()->SetPulseRate(100000); SetFlags(Flags() | B_PULSE_NEEDED); Invalidate(); @@ -69,6 +71,7 @@ void Activity::Stop() { fIsRunning = false; + _InactiveColors(); Window()->SetPulseRate(500000); SetFlags(Flags() & (~B_PULSE_NEEDED)); Invalidate(); @@ -85,17 +88,28 @@ Activity::IsRunning() void Activity::Pulse() { - uchar tmp = fPattern.data[7]; - - for (int j = 7; j > 0; --j) - fPattern.data[j] = fPattern.data[j - 1]; - - fPattern.data[0] = tmp; - + fScrollOffset += fStripeWidth / (1.0f / fSpinSpeed); + if (fScrollOffset >= fStripeWidth * fNumColors) { + // Cycle completed, jump back to where we started + fScrollOffset = 0; + } Invalidate(); } +void +Activity::SetColors(const rgb_color* colors, uint32 numColors) +{ + delete[] fColors; + rgb_color* colorsCopy = new rgb_color[numColors]; + for (uint32 i = 0; i < numColors; i++) + colorsCopy[i] = colors[i]; + + fColors = colorsCopy; + fNumColors = numColors; +} + + void Activity::Draw(BRect rect) { @@ -118,97 +132,43 @@ Activity::_DrawOnBitmap(bool running) { if (fBitmap->Lock()) { - BRect rect = fBitmap->Bounds(); + BRect bounds = fBitmap->Bounds(); fBitmapView->SetDrawingMode(B_OP_COPY); - rgb_color color; - color.red = 0; - color.green = 0; - color.blue = 0; - color.alpha = 255; - - if (running) - color.blue = 200; - - fBitmapView->SetHighColor(color); + // Draw color stripes + float position = -fStripeWidth * (fNumColors + 0.5) + fScrollOffset; + // Starting position: beginning of the second color cycle + // The + 0.5 is so we start out without a partially visible stripe + // on the left side (makes it simpler to loop) + BRect innerFrame = bounds; + innerFrame.InsetBy(-2, -2); - // draw the pole - rect.InsetBy(2, 2); - fBitmapView->FillRect(rect, fPattern); - - // draw frame + be_control_look->DrawStatusBar(fBitmapView, innerFrame, innerFrame, + ui_color(B_PANEL_BACKGROUND_COLOR), + running ? ui_color(B_STATUS_BAR_COLOR) + : ui_color(B_PANEL_BACKGROUND_COLOR), + bounds.Width()); + fBitmapView->SetDrawingMode(B_OP_ALPHA); + uint32 colorIndex = 0; + for (uint32 i = 0; i < fNumStripes; i++) { + fBitmapView->SetHighColor(fColors[colorIndex]); + colorIndex++; + if (colorIndex >= fNumColors) + colorIndex = 0; - // left - color.red = 150; - color.green = 150; - color.blue = 150; - fBitmapView->SetHighColor(color); - fBitmapView->SetDrawingMode(B_OP_OVER); - BPoint point_a = fBitmap->Bounds().LeftTop(); - BPoint point_b = fBitmap->Bounds().LeftBottom(); - point_b.y -= 1; - fBitmapView->StrokeLine(point_a, point_b); - point_a.x += 1; - point_b.x += 1; - point_b.y -= 1; - fBitmapView->StrokeLine(point_a, point_b); + BRect stripeFrame = fStripe.Frame(); + fStripe.MapTo(stripeFrame, + stripeFrame.OffsetToCopy(position, 0.0)); + fBitmapView->FillPolygon(&fStripe); - // top - point_a = fBitmap->Bounds().LeftTop(); - point_b = fBitmap->Bounds().RightTop(); - point_b.x -= 1; - fBitmapView->StrokeLine(point_a, point_b); - point_a.y += 1; - point_b.y += 1; - point_b.x -= 1; - fBitmapView->StrokeLine(point_a, point_b); + position += fStripeWidth; + } - // right - color.red = 255; - color.green = 255; - color.blue = 255; - fBitmapView->SetHighColor(color); - point_a = fBitmap->Bounds().RightTop(); - point_b = fBitmap->Bounds().RightBottom(); - fBitmapView->StrokeLine(point_a, point_b); - point_a.y += 1; - point_a.x -= 1; - point_b.x -= 1; - fBitmapView->StrokeLine(point_a, point_b); - - // bottom - point_a = fBitmap->Bounds().LeftBottom(); - point_b = fBitmap->Bounds().RightBottom(); - fBitmapView->StrokeLine(point_a, point_b); - point_a.x += 1; - point_a.y -= 1; - point_b.y -= 1; - fBitmapView->StrokeLine(point_a, point_b); - - // some blending - color.red = 150; - color.green = 150; - color.blue = 150; - fBitmapView->SetHighColor(color); - fBitmapView->SetDrawingMode(B_OP_SUBTRACT); - fBitmapView->StrokeRect(rect); - - rect.InsetBy(1, 1); - _LightenBitmapHighColor(& color); - fBitmapView->StrokeRect(rect); - - rect.InsetBy(1, 1); - _LightenBitmapHighColor(& color); - fBitmapView->StrokeRect(rect); - - rect.InsetBy(1, 1); - _LightenBitmapHighColor(& color); - fBitmapView->StrokeRect(rect); - - rect.InsetBy(1, 1); - _LightenBitmapHighColor(& color); - fBitmapView->StrokeRect(rect); + fBitmapView->SetDrawingMode(B_OP_COPY); + // Draw box around it + be_control_look->DrawTextControlBorder(fBitmapView, bounds, bounds, + ui_color(B_PANEL_BACKGROUND_COLOR), B_PLAIN_BORDER); fBitmapView->Sync(); fBitmap->Unlock(); @@ -216,22 +176,11 @@ Activity::_DrawOnBitmap(bool running) } -void -Activity::_LightenBitmapHighColor(rgb_color* color) -{ - color->red -= 30; - color->green -= 30; - color->blue -= 30; - - fBitmapView->SetHighColor(*color); -} - - void Activity::_CreateBitmap(void) { BRect rect = Bounds(); - fBitmap = new BBitmap(rect, B_CMAP8, true); + fBitmap = new BBitmap(rect, B_RGBA32, true); fBitmapView = new BView(Bounds(), "buffer", B_FOLLOW_NONE, 0); fBitmap->AddChild(fBitmapView); } @@ -242,6 +191,62 @@ Activity::FrameResized(float width, float height) { delete fBitmap; _CreateBitmap(); + // Choose stripe width so that at least 2 full stripes fit into the view, + // but with a minimum of 5px. Larger views get wider stripes, but they + // grow slower than the view and are capped to a maximum of 200px. + fStripeWidth = (width / (fIsRunning ? 4 : 6)) + 5; + if (fStripeWidth > 200) + fStripeWidth = 200; + + BPoint stripePoints[4]; + stripePoints[0].Set(fStripeWidth * 0.5, 0.0); // top left + stripePoints[1].Set(fStripeWidth * 1.5, 0.0); // top right + stripePoints[2].Set(fStripeWidth, height); // bottom right + stripePoints[3].Set(0.0, height); // bottom left + + fStripe = BPolygon(stripePoints, 4); + + fNumStripes = (int32)ceilf((width) / fStripeWidth) + 1 + fNumColors; + // Number of color stripes drawn in total for the barber pole, the + // user-visible part is a "window" onto the complete pole. We need + // as many stripes as are visible, an extra one on the right side + // (will be partially visible, that's the + 1); and then a whole color + // cycle of strips extra which we scroll into until we loop. + // + // Example with 3 colors and a visible area of 2*fStripeWidth (which means + // that 2 will be fully visible, and a third one partially): + // ........ + // X___________v______v___ + // / 1 / 2 / 3 / 1 / 2 / 3 / + // ````````````````````````` + // Pole is scrolled to the right into the visible region, which is marked + // between the two 'v'. Once the left edge of the visible area reaches + // point X, we can jump back to the initial region position. Invalidate(); } +void +Activity::_ActiveColors() +{ + // Default colors, chosen from system color scheme + rgb_color defaultColors[2]; + rgb_color otherColor = tint_color(ui_color(B_STATUS_BAR_COLOR), 1.3); + otherColor.alpha = 50; + defaultColors[0] = otherColor; + defaultColors[1] = B_TRANSPARENT_COLOR; + SetColors(defaultColors, 2); + +} + + +void +Activity::_InactiveColors() +{ + // Default colors, chosen from system color scheme + rgb_color defaultColors[2]; + rgb_color otherColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.7); + otherColor.alpha = 50; + defaultColors[0] = otherColor; + defaultColors[1] = B_TRANSPARENT_COLOR; + SetColors(defaultColors, 2); +} diff --git a/src/add-ons/tracker/zipomatic/ZipOMaticActivity.h b/src/add-ons/tracker/zipomatic/ZipOMaticActivity.h index e199510a3c..d1d836dc1f 100644 --- a/src/add-ons/tracker/zipomatic/ZipOMaticActivity.h +++ b/src/add-ons/tracker/zipomatic/ZipOMaticActivity.h @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -23,16 +24,28 @@ public: virtual void Pulse(); virtual void Draw(BRect draw); virtual void FrameResized(float width, float height); + void SetColors(const rgb_color* colors, + uint32 numColors); private: void _CreateBitmap(); - void _LightenBitmapHighColor(rgb_color* color); void _DrawOnBitmap(bool running); + void _ActiveColors(); + void _InactiveColors(); bool fIsRunning; pattern fPattern; BBitmap* fBitmap; BView* fBitmapView; + + float fSpinSpeed; + const rgb_color* fColors; + uint32 fNumColors; + + float fScrollOffset; + BPolygon fStripe; + float fStripeWidth; + uint32 fNumStripes; }; #endif // _ACTIVITY_H_