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
This commit is contained in:
Janus
2017-11-28 14:07:02 +01:00
parent 0588dd3ae2
commit 1abde80b3b
2 changed files with 133 additions and 115 deletions
@@ -9,6 +9,8 @@
#include "ZipOMaticActivity.h" #include "ZipOMaticActivity.h"
#include <ControlLook.h>
#include <stdio.h> #include <stdio.h>
@@ -16,17 +18,15 @@ Activity::Activity(const char* name)
: :
BView(name, B_WILL_DRAW | B_FRAME_EVENTS), BView(name, B_WILL_DRAW | B_FRAME_EVENTS),
fIsRunning(false), 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; _InactiveColors();
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;
SetExplicitMinSize(BSize(17, 17)); SetExplicitMinSize(BSize(17, 17));
SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 17)); SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 17));
}; };
@@ -35,14 +35,15 @@ Activity::Activity(const char* name)
Activity::~Activity() Activity::~Activity()
{ {
delete fBitmap; delete fBitmap;
delete[] fColors;
} }
void void
Activity::AllAttached() Activity::AllAttached()
{ {
SetViewColor(B_TRANSPARENT_COLOR);
_CreateBitmap(); _CreateBitmap();
FrameResized(Bounds().Width(), Bounds().Height());
} }
@@ -50,6 +51,7 @@ void
Activity::Start() Activity::Start()
{ {
fIsRunning = true; fIsRunning = true;
_ActiveColors();
Window()->SetPulseRate(100000); Window()->SetPulseRate(100000);
SetFlags(Flags() | B_PULSE_NEEDED); SetFlags(Flags() | B_PULSE_NEEDED);
Invalidate(); Invalidate();
@@ -69,6 +71,7 @@ void
Activity::Stop() Activity::Stop()
{ {
fIsRunning = false; fIsRunning = false;
_InactiveColors();
Window()->SetPulseRate(500000); Window()->SetPulseRate(500000);
SetFlags(Flags() & (~B_PULSE_NEEDED)); SetFlags(Flags() & (~B_PULSE_NEEDED));
Invalidate(); Invalidate();
@@ -85,17 +88,28 @@ Activity::IsRunning()
void void
Activity::Pulse() Activity::Pulse()
{ {
uchar tmp = fPattern.data[7]; fScrollOffset += fStripeWidth / (1.0f / fSpinSpeed);
if (fScrollOffset >= fStripeWidth * fNumColors) {
for (int j = 7; j > 0; --j) // Cycle completed, jump back to where we started
fPattern.data[j] = fPattern.data[j - 1]; fScrollOffset = 0;
}
fPattern.data[0] = tmp;
Invalidate(); 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 void
Activity::Draw(BRect rect) Activity::Draw(BRect rect)
{ {
@@ -118,97 +132,43 @@ Activity::_DrawOnBitmap(bool running)
{ {
if (fBitmap->Lock()) if (fBitmap->Lock())
{ {
BRect rect = fBitmap->Bounds(); BRect bounds = fBitmap->Bounds();
fBitmapView->SetDrawingMode(B_OP_COPY); fBitmapView->SetDrawingMode(B_OP_COPY);
rgb_color color; // Draw color stripes
color.red = 0; float position = -fStripeWidth * (fNumColors + 0.5) + fScrollOffset;
color.green = 0; // Starting position: beginning of the second color cycle
color.blue = 0; // The + 0.5 is so we start out without a partially visible stripe
color.alpha = 255; // on the left side (makes it simpler to loop)
BRect innerFrame = bounds;
if (running) innerFrame.InsetBy(-2, -2);
color.blue = 200;
fBitmapView->SetHighColor(color);
// draw the pole be_control_look->DrawStatusBar(fBitmapView, innerFrame, innerFrame,
rect.InsetBy(2, 2); ui_color(B_PANEL_BACKGROUND_COLOR),
fBitmapView->FillRect(rect, fPattern); running ? ui_color(B_STATUS_BAR_COLOR)
: ui_color(B_PANEL_BACKGROUND_COLOR),
// draw frame 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 BRect stripeFrame = fStripe.Frame();
color.red = 150; fStripe.MapTo(stripeFrame,
color.green = 150; stripeFrame.OffsetToCopy(position, 0.0));
color.blue = 150; fBitmapView->FillPolygon(&fStripe);
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);
// top position += fStripeWidth;
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);
// right fBitmapView->SetDrawingMode(B_OP_COPY);
color.red = 255; // Draw box around it
color.green = 255; be_control_look->DrawTextControlBorder(fBitmapView, bounds, bounds,
color.blue = 255; ui_color(B_PANEL_BACKGROUND_COLOR), B_PLAIN_BORDER);
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->Sync(); fBitmapView->Sync();
fBitmap->Unlock(); 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 void
Activity::_CreateBitmap(void) Activity::_CreateBitmap(void)
{ {
BRect rect = Bounds(); 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); fBitmapView = new BView(Bounds(), "buffer", B_FOLLOW_NONE, 0);
fBitmap->AddChild(fBitmapView); fBitmap->AddChild(fBitmapView);
} }
@@ -242,6 +191,62 @@ Activity::FrameResized(float width, float height)
{ {
delete fBitmap; delete fBitmap;
_CreateBitmap(); _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(); 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);
}
@@ -5,6 +5,7 @@
#include <Box.h> #include <Box.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Polygon.h>
#include <View.h> #include <View.h>
#include <Window.h> #include <Window.h>
@@ -23,16 +24,28 @@ public:
virtual void Pulse(); virtual void Pulse();
virtual void Draw(BRect draw); virtual void Draw(BRect draw);
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
void SetColors(const rgb_color* colors,
uint32 numColors);
private: private:
void _CreateBitmap(); void _CreateBitmap();
void _LightenBitmapHighColor(rgb_color* color);
void _DrawOnBitmap(bool running); void _DrawOnBitmap(bool running);
void _ActiveColors();
void _InactiveColors();
bool fIsRunning; bool fIsRunning;
pattern fPattern; pattern fPattern;
BBitmap* fBitmap; BBitmap* fBitmap;
BView* fBitmapView; BView* fBitmapView;
float fSpinSpeed;
const rgb_color* fColors;
uint32 fNumColors;
float fScrollOffset;
BPolygon fStripe;
float fStripeWidth;
uint32 fNumStripes;
}; };
#endif // _ACTIVITY_H_ #endif // _ACTIVITY_H_