1/*
2 * Copyright 2009 Vincent Duvert, vincent.duvert@free.fr
3 * Copyright 2014 Haiku, Inc. All rights reserved.
4 *
5 * Distributed under the terms of the MIT License.
6 *
7 * Authors:
8 *		Vincent Duvert, vincent.duvert@free.fr
9 *		John Scipione, jscipione@gmail.com
10 */
11
12
13#include "IconDisplay.h"
14
15#include <stdlib.h>
16
17#include <Bitmap.h>
18#include <IconUtils.h>
19#include <View.h>
20
21#include "VectorIcon.h"
22
23
24#define RAND_BETWEEN(a, b) ((rand() % ((b) - (a) + 1) + (a)))
25#define SHOW_TICKS_MIN 20
26#define SHOW_TICKS_MAX 50
27#define STAY_TICKS_MIN 50
28#define STAY_TICKS_MAX 100
29#define HIDE_TICKS_MIN 20
30#define HIDE_TICKS_MAX 50
31
32
33IconDisplay::IconDisplay()
34	:
35	fIsRunning(false),
36	fBitmap(NULL)
37{
38}
39
40
41IconDisplay::~IconDisplay()
42{
43	delete fBitmap;
44}
45
46
47void
48IconDisplay::Run(vector_icon* icon, BRect frame)
49{
50	delete fBitmap;
51
52	fBitmap = new BBitmap(BRect(0, 0, frame.Width(), frame.Height()), 0,
53		B_RGBA32);
54	if (BIconUtils::GetVectorIcon(icon->data, icon->size, fBitmap) != B_OK)
55		return;
56
57	fState = 0;
58	fTicks = 0;
59	fDelay = RAND_BETWEEN(SHOW_TICKS_MIN, SHOW_TICKS_MAX);
60	fFrame = frame;
61
62	fIsRunning = true;
63}
64
65
66void
67IconDisplay::ClearOn(BView* view)
68{
69	if (!fIsRunning || fState == 2)
70		return;
71
72	view->FillRect(fFrame);
73}
74
75
76void
77IconDisplay::DrawOn(BView* view, uint32 delta)
78{
79	if (!fIsRunning)
80		return;
81
82	fTicks += delta;
83
84	rgb_color backColor = view->HighColor();
85
86	switch (fState) {
87		case 0:
88			// progressive showing
89			if (fTicks < fDelay)
90				backColor.alpha = (fTicks * 255) / fDelay;
91			else
92				fState++;
93
94			break;
95
96		case 1:
97			// completed showing
98			backColor.alpha = 255;
99			fTicks = 0;
100			fDelay = RAND_BETWEEN(STAY_TICKS_MIN, STAY_TICKS_MAX);
101			fState++;
102			break;
103
104		case 2:
105			// waiting
106			if (fTicks < fDelay)
107				return;
108
109			fTicks = 0;
110			backColor.alpha = 255;
111			fDelay = RAND_BETWEEN(HIDE_TICKS_MIN, HIDE_TICKS_MAX);
112			fState++;
113			return;
114			break;
115
116		case 3:
117			// progressive hiding
118			if (fTicks < fDelay) {
119				backColor.alpha = 255 - (fTicks * 255) / fDelay;
120			} else {
121				backColor.alpha = 0;
122				fState++;
123			}
124			break;
125
126		default:
127			// finished
128			fIsRunning = false;
129			return;
130			break;
131	};
132
133	view->SetHighColor(backColor);
134	view->DrawBitmap(fBitmap, BPoint(fFrame.left, fFrame.top));
135	backColor.alpha = 255;
136	view->SetHighColor(backColor);
137}
138