1//****************************************************************************************
2//
3//	File:		DeskbarPulseView.cpp
4//
5//	Written by:	Daniel Switkin
6//
7//	Copyright 1999, Be Incorporated
8//
9//****************************************************************************************
10
11
12#include "DeskbarPulseView.h"
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include <Alert.h>
19#include <Application.h>
20#include <Catalog.h>
21#include <Deskbar.h>
22#include <Roster.h>
23
24#include "Common.h"
25#include "Prefs.h"
26#include "PulseApp.h"
27
28#undef B_TRANSLATION_CONTEXT
29#define B_TRANSLATION_CONTEXT "DeskbarPulseView"
30
31
32DeskbarPulseView::DeskbarPulseView(BRect rect)
33	: MiniPulseView(rect, "DeskbarPulseView")
34{
35	messagerunner = NULL;
36	prefs = NULL;
37}
38
39
40DeskbarPulseView::DeskbarPulseView(BMessage *message)
41	: MiniPulseView(message)
42{
43	mode1->SetLabel(B_TRANSLATE("Normal mode"));
44	mode1->SetMessage(new BMessage(PV_NORMAL_MODE));
45	mode2->SetLabel(B_TRANSLATE("Mini mode"));
46	mode2->SetMessage(new BMessage(PV_MINI_MODE));
47	quit = new BMenuItem(B_TRANSLATE("Quit"), new BMessage(PV_QUIT), 0, 0);
48	popupmenu->AddSeparatorItem();
49	popupmenu->AddItem(quit);
50
51	SetViewColor(B_TRANSPARENT_COLOR);
52
53	prefs = new Prefs();
54	active_color.red = (prefs->deskbar_active_color & 0xff000000) >> 24;
55	active_color.green = (prefs->deskbar_active_color & 0x00ff0000) >> 16;
56	active_color.blue = (prefs->deskbar_active_color & 0x0000ff00) >> 8;
57
58	idle_color.red = (prefs->deskbar_idle_color & 0xff000000) >> 24;
59	idle_color.green = (prefs->deskbar_idle_color & 0x00ff0000) >> 16;
60	idle_color.blue = (prefs->deskbar_idle_color & 0x0000ff00) >> 8;
61
62	frame_color.red = (prefs->deskbar_frame_color & 0xff000000) >> 24;
63	frame_color.green = (prefs->deskbar_frame_color & 0x00ff0000) >> 16;
64	frame_color.blue = (prefs->deskbar_frame_color & 0x0000ff00) >> 8;
65	SetViewColor(idle_color);
66
67	messagerunner = NULL;
68}
69
70
71void
72DeskbarPulseView::AttachedToWindow()
73{
74	BMessenger messenger(this);
75	mode1->SetTarget(messenger);
76	mode2->SetTarget(messenger);
77	preferences->SetTarget(messenger);
78	about->SetTarget(messenger);
79	quit->SetTarget(messenger);
80
81	system_info sys_info;
82	get_system_info(&sys_info);
83	if (sys_info.cpu_count >= 2) {
84		for (unsigned int x = 0; x < sys_info.cpu_count; x++)
85			cpu_menu_items[x]->SetTarget(messenger);
86	}
87
88	// Use a BMessageRunner to deliver periodic messsages instead
89	// of Pulse() events from the Deskbar - this is to avoid changing
90	// the current pulse rate and affecting other replicants
91	messagerunner = new BMessageRunner(messenger, new BMessage(PV_REPLICANT_PULSE),
92		200000, -1);
93}
94
95
96void
97DeskbarPulseView::MouseDown(BPoint point)
98{
99	BPoint cursor;
100	uint32 buttons;
101	MakeFocus(true);
102	GetMouse(&cursor, &buttons, true);
103
104	if (buttons & B_PRIMARY_MOUSE_BUTTON) {
105		BMessage *message = Window()->CurrentMessage();
106		int32 clicks = message->FindInt32("clicks");
107		if (clicks >= 2) {
108			BMessenger messenger(this);
109			BMessage *m = new BMessage(PV_NORMAL_MODE);
110			messenger.SendMessage(m);
111		}
112	} else MiniPulseView::MouseDown(point);
113}
114
115
116void
117DeskbarPulseView::Pulse()
118{
119	// Override and do nothing here
120}
121
122
123void
124DeskbarPulseView::MessageReceived(BMessage *message)
125{
126	switch (message->what) {
127		case PV_NORMAL_MODE:
128			SetMode(true);
129			Remove();
130			break;
131		case PV_MINI_MODE:
132			SetMode(false);
133			Remove();
134			break;
135		case PV_PREFERENCES:
136		{
137			message->AddMessenger("settingsListener", this);
138			// Spawn the app and open the window there, not in DeskBar process.
139			be_roster->Launch(APP_SIGNATURE, message);
140			break;
141		}
142		case PV_ABOUT:
143		{
144			BMessage aboutRequest(B_ABOUT_REQUESTED);
145			be_roster->Launch(APP_SIGNATURE, &aboutRequest);
146			break;
147		}
148		case PV_QUIT:
149			Remove();
150			break;
151		case PRV_DESKBAR_CHANGE_COLOR:
152			UpdateColors(message);
153			break;
154		case PRV_DESKBAR_ICON_WIDTH: {
155			int width = message->FindInt32("width");
156			ResizeTo(width - 1, Bounds().Height());
157			Draw(Bounds());
158			break;
159		}
160		case PV_REPLICANT_PULSE:
161			Update();
162			Draw(Bounds());
163			break;
164		case PV_CPU_MENU_ITEM:
165			ChangeCPUState(message);
166			break;
167		default:
168			BView::MessageReceived(message);
169			break;
170	}
171}
172
173
174DeskbarPulseView *
175DeskbarPulseView::Instantiate(BMessage *data)
176{
177	if (!validate_instantiation(data, "DeskbarPulseView"))
178		return NULL;
179	return new DeskbarPulseView(data);
180}
181
182status_t
183DeskbarPulseView::Archive(BMessage *data, bool deep) const
184{
185	PulseView::Archive(data, deep);
186	data->AddString("add_on", APP_SIGNATURE);
187	data->AddString("class", "DeskbarPulseView");
188	return B_OK;
189}
190
191
192void
193DeskbarPulseView::Remove()
194{
195	// Remove ourselves from the deskbar by name
196	BDeskbar *deskbar = new BDeskbar();
197	status_t err = deskbar->RemoveItem("DeskbarPulseView");
198	if (err != B_OK) {
199		BString str;
200		snprintf(str.LockBuffer(512), 512,
201			B_TRANSLATE("Removing from Deskbar failed.\n%s"), strerror(err));
202		str.UnlockBuffer();
203		BAlert *alert = new BAlert(B_TRANSLATE("Info"), str.String(),
204			B_TRANSLATE("OK"));
205		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
206		alert->Go(NULL);
207	}
208	delete deskbar;
209}
210
211
212void
213DeskbarPulseView::SetMode(bool normal)
214{
215	if (normal) prefs->window_mode = NORMAL_WINDOW_MODE;
216	else prefs->window_mode = MINI_WINDOW_MODE;
217	prefs->Save();
218	be_roster->Launch(APP_SIGNATURE);
219}
220
221
222DeskbarPulseView::~DeskbarPulseView()
223{
224	if (messagerunner != NULL) delete messagerunner;
225	if (prefs != NULL) delete prefs;
226}
227