xref: /haiku/src/apps/activitymonitor/SettingsWindow.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 /*
2  * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "SettingsWindow.h"
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 #include <Catalog.h>
13 #include <LayoutBuilder.h>
14 #include <GroupLayoutBuilder.h>
15 #include <Slider.h>
16 #include <String.h>
17 
18 #undef B_TRANSLATION_CONTEXT
19 #define B_TRANSLATION_CONTEXT "SettingsWindow"
20 
21 
22 static const uint32 kMsgUpdateTimeInterval = 'upti';
23 
24 static const bigtime_t kUpdateIntervals[] = {
25 	25, 50, 75, 100, 250, 500, 1000, 2000
26 };
27 static const size_t kNumUpdateIntervals
28 	= sizeof(kUpdateIntervals) / sizeof(kUpdateIntervals[0]);
29 
30 
31 class IntervalSlider : public BSlider {
32 public:
33 	IntervalSlider(const char* label, BMessage* message, uint32 levels)
34 		: BSlider("intervalSlider", label, message, 0, levels - 1, B_HORIZONTAL)
35 	{
36 		BString min(_TextFor(0));
37 		BString max(_TextFor(levels - 1));
38 		SetLimitLabels(min.String(), max.String());
39 		SetHashMarks(B_HASH_MARKS_BOTTOM);
40 		SetHashMarkCount(levels);
41 		SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
42 
43 		if (message != NULL)
44 			SetModificationMessage(new BMessage(*message));
45 	}
46 
47 	void SetInterval(bigtime_t interval)
48 	{
49 		interval /= 1000;
50 
51 		// Find closest index
52 		int32 bestDiff = INT32_MAX;
53 		uint32 bestIndex = 0;
54 		for (uint32 i = 0; i < kNumUpdateIntervals; i++) {
55 			int32 diff = abs(kUpdateIntervals[i] - interval);
56 			if (diff < bestDiff) {
57 				bestDiff = diff;
58 				bestIndex = i;
59 			}
60 		}
61 
62 		SetValue(bestIndex);
63 	}
64 
65 	virtual const char* UpdateText() const
66 	{
67 		return _TextFor(Value());
68 	}
69 
70 private:
71 	const char* _TextFor(uint32 level) const
72 	{
73 		if (level >= kNumUpdateIntervals)
74 			return NULL;
75 
76 		bigtime_t interval = kUpdateIntervals[level];
77 		if ((interval % 1000) == 0)
78 			snprintf(fText, sizeof(fText), B_TRANSLATE("%lld sec."), interval / 1000);
79 		else
80 			snprintf(fText, sizeof(fText), B_TRANSLATE("%lld ms"), interval);
81 
82 		return fText;
83 	}
84 
85 	mutable char	fText[64];
86 };
87 
88 
89 //	#pragma mark -
90 
91 
92 SettingsWindow::SettingsWindow(ActivityWindow* target)
93 	: BWindow(_RelativeTo(target),
94 		B_TRANSLATE_CONTEXT("Settings", "ActivityWindow"), B_FLOATING_WINDOW,
95 	   	B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
96 	fTarget(target)
97 {
98 	fIntervalSlider = new IntervalSlider(B_TRANSLATE("Update time interval:"),
99 		new BMessage(kMsgUpdateTimeInterval), kNumUpdateIntervals);
100 	fIntervalSlider->SetInterval(target->RefreshInterval());
101 
102 	// controls pane
103 	BLayoutBuilder::Group<>(this, B_VERTICAL)
104 		.Add(fIntervalSlider)
105 		.SetInsets(B_USE_WINDOW_SPACING);
106 
107 	if (target->IsAlwaysOnTop())
108 		SetFeel(B_MODAL_ALL_WINDOW_FEEL);
109 
110 	MoveOnScreen(B_MOVE_IF_PARTIALLY_OFFSCREEN);
111 }
112 
113 
114 SettingsWindow::~SettingsWindow()
115 {
116 }
117 
118 
119 void
120 SettingsWindow::MessageReceived(BMessage* message)
121 {
122 	switch (message->what) {
123 		case kMsgUpdateTimeInterval:
124 		{
125 			int32 level = 0;
126 			if (message->FindInt32("be:value", &level) != B_OK)
127 				break;
128 
129 			BMessage update(kMsgTimeIntervalUpdated);
130 			update.AddInt64("interval", kUpdateIntervals[level] * 1000LL);
131 
132 			fTarget.SendMessage(&update);
133 			break;
134 		}
135 
136 		default:
137 			BWindow::MessageReceived(message);
138 			break;
139 	}
140 }
141 
142 
143 bool
144 SettingsWindow::QuitRequested()
145 {
146 	return true;
147 }
148 
149 
150 BRect
151 SettingsWindow::_RelativeTo(BWindow* window)
152 {
153 	BRect frame = window->Frame();
154 	return BRect(frame.right - 150, frame.top + frame.Height() / 4,
155 		frame.right + 200, frame.top + frame.Height() / 4 + 50);
156 }
157