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_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 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 = INT32_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_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 if (target->IsAlwaysOnTop()) 109 SetFeel(B_MODAL_ALL_WINDOW_FEEL); 110 } 111 112 113 SettingsWindow::~SettingsWindow() 114 { 115 } 116 117 118 void 119 SettingsWindow::MessageReceived(BMessage* message) 120 { 121 switch (message->what) { 122 case kMsgUpdateTimeInterval: 123 { 124 int32 level = 0; 125 if (message->FindInt32("be:value", &level) != B_OK) 126 break; 127 128 BMessage update(kMsgTimeIntervalUpdated); 129 update.AddInt64("interval", kUpdateIntervals[level] * 1000LL); 130 131 fTarget.SendMessage(&update); 132 break; 133 } 134 135 default: 136 BWindow::MessageReceived(message); 137 break; 138 } 139 } 140 141 142 bool 143 SettingsWindow::QuitRequested() 144 { 145 return true; 146 } 147 148 149 BRect 150 SettingsWindow::_RelativeTo(BWindow* window) 151 { 152 BRect frame = window->Frame(); 153 return BRect(frame.right - 150, frame.top + frame.Height() / 4, 154 frame.right + 200, frame.top + frame.Height() / 4 + 50); 155 } 156