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 <ControlLook.h>
#include <stdio.h>
@@ -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);
}
@@ -5,6 +5,7 @@
#include <Box.h>
#include <Bitmap.h>
#include <Polygon.h>
#include <View.h>
#include <Window.h>
@@ -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_