xref: /haiku/src/apps/activitymonitor/SettingsWindow.cpp (revision 1c09002cbee8e797a0f8bbfc5678dfadd39ee1a7)
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 <GridLayoutBuilder.h>
14 #include <GroupLayoutBuilder.h>
15 #include <Slider.h>
16 #include <String.h>
17 
18 #undef B_TRANSLATE_CONTEXT
19 #define B_TRANSLATE_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 
42 		if (message != NULL)
43 			SetModificationMessage(new BMessage(*message));
44 	}
45 
46 	void SetInterval(bigtime_t interval)
47 	{
48 		interval /= 1000;
49 
50 		// Find closest index
51 		int32 bestDiff = LONG_MAX;
52 		uint32 bestIndex = 0;
53 		for (uint32 i = 0; i < kNumUpdateIntervals; i++) {
54 			int32 diff = abs(kUpdateIntervals[i] - interval);
55 			if (diff < bestDiff) {
56 				bestDiff = diff;
57 				bestIndex = i;
58 			}
59 		}
60 
61 		SetValue(bestIndex);
62 	}
63 
64 	virtual const char* UpdateText() const
65 	{
66 		return _TextFor(Value());
67 	}
68 
69 private:
70 	const char* _TextFor(uint32 level) const
71 	{
72 		if (level >= kNumUpdateIntervals)
73 			return NULL;
74 
75 		bigtime_t interval = kUpdateIntervals[level];
76 		if ((interval % 1000) == 0)
77 			snprintf(fText, sizeof(fText), B_TRANSLATE("%lld sec."), interval / 1000);
78 		else
79 			snprintf(fText, sizeof(fText), B_TRANSLATE("%lld ms"), interval);
80 
81 		return fText;
82 	}
83 
84 	mutable char	fText[64];
85 };
86 
87 
88 //	#pragma mark -
89 
90 
91 SettingsWindow::SettingsWindow(ActivityWindow* target)
92 	: BWindow(_RelativeTo(target),
93 		B_TRANSLATE_WITH_CONTEXT("Settings", "ActivityWindow"), B_FLOATING_WINDOW,
94 	   	B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
95 	fTarget(target)
96 {
97 	SetLayout(new BGroupLayout(B_VERTICAL));
98 
99 	fIntervalSlider = new IntervalSlider(B_TRANSLATE("Update time interval:"),
100 		new BMessage(kMsgUpdateTimeInterval), kNumUpdateIntervals);
101 	fIntervalSlider->SetInterval(target->RefreshInterval());
102 
103 	// controls pane
104 	AddChild(BGroupLayoutBuilder(B_VERTICAL)
105 		.Add(fIntervalSlider)
106 		.SetInsets(10, 10, 10, 10)
107 	);
108 }
109 
110 
111 SettingsWindow::~SettingsWindow()
112 {
113 }
114 
115 
116 void
117 SettingsWindow::MessageReceived(BMessage* message)
118 {
119 	switch (message->what) {
120 		case kMsgUpdateTimeInterval:
121 		{
122 			int32 level = 0;
123 			if (message->FindInt32("be:value", &level) != B_OK)
124 				break;
125 
126 			BMessage update(kMsgTimeIntervalUpdated);
127 			update.AddInt64("interval", kUpdateIntervals[level] * 1000LL);
128 
129 			fTarget.SendMessage(&update);
130 			break;
131 		}
132 
133 		default:
134 			BWindow::MessageReceived(message);
135 			break;
136 	}
137 }
138 
139 
140 bool
141 SettingsWindow::QuitRequested()
142 {
143 	return true;
144 }
145 
146 
147 BRect
148 SettingsWindow::_RelativeTo(BWindow* window)
149 {
150 	BRect frame = window->Frame();
151 	return BRect(frame.right - 150, frame.top + frame.Height() / 4,
152 		frame.right + 200, frame.top + frame.Height() / 4 + 50);
153 }
154 
155