1/*
2 * Copyright 2001-2008, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Rafael Romo
7 *		Stefano Ceccherini (burton666@libero.it)
8 *		Axel D��rfler, axeld@pinc-software.de
9 */
10
11
12#include "AlertView.h"
13#include "Constants.h"
14
15#include <Window.h>
16#include <Bitmap.h>
17#include <Button.h>
18#include <Catalog.h>
19#include <StringView.h>
20#include <String.h>
21
22#include <IconUtils.h>
23#include <FindDirectory.h>
24#include <Resources.h>
25#include <File.h>
26#include <Path.h>
27
28
29#undef B_TRANSLATION_CONTEXT
30#define B_TRANSLATION_CONTEXT "Screen"
31
32
33AlertView::AlertView(BRect frame, const char *name)
34	: BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED),
35	// we will wait 12 seconds until we send a message
36	fSeconds(12)
37{
38	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
39	fBitmap = InitIcon();
40
41	BRect rect(60, 8, 400, 36);
42	BStringView *stringView = new BStringView(rect, NULL,
43		B_TRANSLATE("Do you wish to keep these settings?"));
44	stringView->SetFont(be_bold_font);
45	stringView->ResizeToPreferred();
46	AddChild(stringView);
47
48	rect = stringView->Frame();
49	rect.OffsetBy(0, rect.Height());
50	fCountdownView = new BStringView(rect, "countdown", NULL);
51	UpdateCountdownView();
52	fCountdownView->ResizeToPreferred();
53	AddChild(fCountdownView);
54
55	BButton* keepButton = new BButton(rect, "keep", B_TRANSLATE("Keep"),
56		new BMessage(BUTTON_KEEP_MSG), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
57	keepButton->ResizeToPreferred();
58	AddChild(keepButton);
59
60	BButton* button = new BButton(rect, "undo", B_TRANSLATE("Undo"),
61		new BMessage(BUTTON_UNDO_MSG), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
62	button->ResizeToPreferred();
63	AddChild(button);
64
65	// we're resizing ourselves to the right size
66	// (but we're not implementing GetPreferredSize(), bad style!)
67	float width = stringView->Frame().right;
68	if (fCountdownView->Frame().right > width)
69		width = fCountdownView->Frame().right;
70	if (width < Bounds().Width())
71		width = Bounds().Width();
72
73	float height
74		= fCountdownView->Frame().bottom + 24 + button->Bounds().Height();
75	ResizeTo(width, height);
76
77	keepButton->MoveTo(Bounds().Width() - 8 - keepButton->Bounds().Width(),
78		Bounds().Height() - 8 - keepButton->Bounds().Height());
79	button->MoveTo(keepButton->Frame().left - button->Bounds().Width() - 8,
80		keepButton->Frame().top);
81
82	keepButton->MakeDefault(true);
83}
84
85
86void
87AlertView::AttachedToWindow()
88{
89	// the view displays a decrementing counter
90	// (until the user must take action)
91	Window()->SetPulseRate(1000000);
92		// every second
93
94	SetEventMask(B_KEYBOARD_EVENTS);
95}
96
97
98void
99AlertView::Draw(BRect updateRect)
100{
101	rgb_color dark = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
102		B_DARKEN_1_TINT);
103	SetHighColor(dark);
104
105	FillRect(BRect(0.0, 0.0, 30.0, Bounds().bottom));
106
107	if (fBitmap != NULL) {
108		SetDrawingMode(B_OP_ALPHA);
109		DrawBitmap(fBitmap, BPoint(18.0, 6.0));
110		SetDrawingMode(B_OP_COPY);
111	}
112}
113
114
115void
116AlertView::Pulse()
117{
118	if (--fSeconds == 0)
119		Window()->PostMessage(BUTTON_UNDO_MSG);
120	else
121		UpdateCountdownView();
122}
123
124
125void
126AlertView::KeyDown(const char* bytes, int32 numBytes)
127{
128	if (numBytes == 1 && bytes[0] == B_ESCAPE)
129		Window()->PostMessage(BUTTON_UNDO_MSG);
130}
131
132
133void
134AlertView::UpdateCountdownView()
135{
136	BString string;
137	string = B_TRANSLATE("Settings will revert in %seconds seconds.");
138	string.ReplaceFirst("%seconds", BString() << fSeconds);
139	fCountdownView->SetText(string.String());
140}
141
142
143BBitmap*
144AlertView::InitIcon()
145{
146	// This is how BAlert gets to its icon
147	BBitmap* icon = NULL;
148	BPath path;
149	if (find_directory(B_BEOS_SERVERS_DIRECTORY, &path) == B_OK) {
150		path.Append("app_server");
151		BResources resources;
152		BFile file;
153		if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK
154			&& resources.SetTo(&file) == B_OK) {
155			size_t size;
156			const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE,
157				"warn", &size);
158			if (data) {
159				icon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
160				if (BIconUtils::GetVectorIcon((const uint8*)data, size, icon)
161						!= B_OK) {
162					delete icon;
163					icon = NULL;
164				}
165			}
166		}
167	}
168
169	return icon;
170}
171