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 22static const uint32 kMsgUpdateTimeInterval = 'upti'; 23 24static const bigtime_t kUpdateIntervals[] = { 25 25, 50, 75, 100, 250, 500, 1000, 2000 26}; 27static const size_t kNumUpdateIntervals 28 = sizeof(kUpdateIntervals) / sizeof(kUpdateIntervals[0]); 29 30 31class IntervalSlider : public BSlider { 32public: 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 70private: 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."), 79 (long long int)interval / 1000); 80 } else 81 snprintf(fText, sizeof(fText), B_TRANSLATE("%lld ms"), (long long int)interval); 82 83 return fText; 84 } 85 86 mutable char fText[64]; 87}; 88 89 90// #pragma mark - 91 92 93SettingsWindow::SettingsWindow(ActivityWindow* target) 94 : BWindow(_RelativeTo(target), 95 B_TRANSLATE_CONTEXT("Settings", "ActivityWindow"), B_FLOATING_WINDOW, 96 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), 97 fTarget(target) 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 BLayoutBuilder::Group<>(this, B_VERTICAL) 105 .Add(fIntervalSlider) 106 .SetInsets(B_USE_WINDOW_SPACING); 107 108 if (target->IsAlwaysOnTop()) 109 SetFeel(B_MODAL_ALL_WINDOW_FEEL); 110 111 MoveOnScreen(B_MOVE_IF_PARTIALLY_OFFSCREEN); 112} 113 114 115SettingsWindow::~SettingsWindow() 116{ 117} 118 119 120void 121SettingsWindow::MessageReceived(BMessage* message) 122{ 123 switch (message->what) { 124 case kMsgUpdateTimeInterval: 125 { 126 int32 level = 0; 127 if (message->FindInt32("be:value", &level) != B_OK) 128 break; 129 130 BMessage update(kMsgTimeIntervalUpdated); 131 update.AddInt64("interval", kUpdateIntervals[level] * 1000LL); 132 133 fTarget.SendMessage(&update); 134 break; 135 } 136 137 default: 138 BWindow::MessageReceived(message); 139 break; 140 } 141} 142 143 144bool 145SettingsWindow::QuitRequested() 146{ 147 return true; 148} 149 150 151BRect 152SettingsWindow::_RelativeTo(BWindow* window) 153{ 154 BRect frame = window->Frame(); 155 return BRect(frame.right - 150, frame.top + frame.Height() / 4, 156 frame.right + 200, frame.top + frame.Height() / 4 + 50); 157} 158