57 class Slider :
public Control
94 virtual void Disable(
bool b =
true);
111 static const T INVALID_PAGE_SIZE;
133 void SlideToImpl(T p,
bool signal);
138 SlidEcho(
const std::string& name);
139 void operator()(T pos, T min, T max);
148 unsigned int m_line_width;
149 unsigned int m_tab_width;
151 int m_tab_drag_offset;
158 const T Slider<T>::INVALID_PAGE_SIZE = std::numeric_limits<T>::max();
166 m_page_sz(INVALID_PAGE_SIZE),
170 m_line_style(RAISED),
171 m_tab_drag_offset(-1),
173 m_dragging_tab(false)
178 Clr color,
int unsigned tab_width,
int unsigned line_width,
184 m_page_sz(INVALID_PAGE_SIZE),
185 m_orientation(orientation),
186 m_line_width(line_width),
187 m_tab_width(tab_width),
189 m_tab_drag_offset(-1),
191 GetStyleFactory()->NewVSliderTabButton(X0, Y0, Width(),
Y(m_tab_width),
"", boost::shared_ptr<
Font>(), color) :
192 GetStyleFactory()->NewHSliderTabButton(X0, Y0,
X(m_tab_width), Height(),
"", boost::shared_ptr<
Font>(), color)),
193 m_dragging_tab(false)
200 if (INSTRUMENT_ALL_SIGNALS) {
209 Pt tab_min = m_tab->MinUsableSize();
210 return Pt(m_orientation ==
VERTICAL ? tab_min.
x : Size().x,
211 m_orientation ==
VERTICAL ? Size().y : tab_min.
y);
220 {
return std::pair<T, T>(m_range_min, m_range_max); }
224 {
return m_page_sz != INVALID_PAGE_SIZE ? m_page_sz : (m_range_max - m_range_min) / 10; }
228 {
return m_orientation; }
232 {
return m_tab_width; }
236 {
return m_line_width; }
240 {
return m_line_style; }
245 const Pt UL = UpperLeft();
246 const Pt LR = LowerRight();
248 int tab_width = m_orientation ==
VERTICAL ?
Value(m_tab->Height()) :
Value(m_tab->Width());
251 ul.
x = ((LR.
x + UL.
x) - static_cast<int>(m_line_width)) / 2;
252 lr.x = ul.x +
static_cast<int>(m_line_width);
253 ul.y = UL.
y + tab_width / 2;
254 lr.y = LR.
y - tab_width / 2;
256 ul.x = UL.
x + tab_width / 2;
257 lr.x = LR.
x - tab_width / 2;
258 ul.y = ((LR.
y + UL.
y) - static_cast<int>(m_line_width)) / 2;
259 lr.y = ul.y +
static_cast<int>(m_line_width);
261 switch (m_line_style) {
266 BeveledRectangle(ul, lr, color_to_use, color_to_use,
true, m_line_width / 2);
269 BeveledRectangle(ul, lr, color_to_use, color_to_use,
false, m_line_width / 2);
279 m_tab->SizeMove(
Pt(),
Pt(lr.
x - ul.
x,
Y(m_tab_width)));
281 m_tab->SizeMove(
Pt(),
Pt(
X(m_tab_width), lr.
y - ul.
y));
302 assert(m_range_min != m_range_max);
305 if (m_posn < m_range_min)
306 SlideToImpl(m_range_min,
false);
307 else if (m_range_max < m_posn)
308 SlideToImpl(m_range_max,
false);
315 { SizeSlider(m_range_min, max); }
319 { SizeSlider(min, m_range_max); }
323 { SlideToImpl(p,
false); }
327 { m_page_sz = size; }
331 { m_line_style = style; }
340 Pt ul = UpperLeft(), lr = LowerRight();
343 int pixel_nearest_to_pt_on_line = 0;
345 line_min =
Value(m_tab->Height() / 2);
346 line_max =
Value(Height() - (m_tab->Height() - m_tab->Height() / 2));
347 pixel_nearest_to_pt_on_line = std::max(line_min, std::min(
Value(lr.y - pt.
y), line_max));
349 line_min =
Value(m_tab->Width() / 2);
350 line_max =
Value(Width() - (m_tab->Width() - m_tab->Width() / 2));
351 pixel_nearest_to_pt_on_line = std::max(line_min, std::min(
Value(pt.
x - ul.
x), line_max));
353 double fractional_distance =
static_cast<double>(pixel_nearest_to_pt_on_line) / (line_max - line_min);
354 return m_range_min +
static_cast<T
>((m_range_max - m_range_min) * fractional_distance);
359 { SlideToImpl(m_posn < PtToPosn(pt) ? m_posn + PageSize() : m_posn - PageSize(),
true); }
367 SlideToImpl(m_range_min,
true);
370 SlideToImpl(m_range_max,
true);
374 SlideToImpl(m_posn + (0 < (m_range_max - m_range_min) ? 1 : -1),
true);
378 SlideToImpl(m_posn + (0 < (m_range_max - m_range_min) ? 1 : -1),
true);
382 SlideToImpl(m_posn - (0 < (m_range_max - m_range_min) ? 1 : -1),
true);
386 SlideToImpl(m_posn - (0 < (m_range_max - m_range_min) ? 1 : -1),
true);
390 SlideToImpl(m_posn + 1,
true);
394 SlideToImpl(m_posn - 1,
true);
409 switch (event.
Type()) {
410 case WndEvent::LDrag: {
412 Pt new_ul = m_tab->RelativeUpperLeft() +
event.DragMove();
414 new_ul.
x = m_tab->RelativeUpperLeft().x;
415 new_ul.
y = std::max(Y0, std::min(new_ul.
y, ClientHeight() - m_tab->Height()));
417 new_ul.
x = std::max(X0, std::min(new_ul.
x, ClientWidth() - m_tab->Width()));
418 new_ul.
y = m_tab->RelativeUpperLeft().y;
420 m_tab->MoveTo(new_ul);
425 case WndEvent::LButtonDown:
426 m_dragging_tab =
true;
428 case WndEvent::LButtonUp:
429 case WndEvent::LClick: {
431 SlidAndStoppedSignal(m_posn, m_range_min, m_range_max);
432 m_dragging_tab =
false;
435 case WndEvent::MouseLeave:
436 return m_dragging_tab;
447 assert(m_range_min <= m_posn && m_posn <= m_range_max ||
448 m_range_max <= m_posn && m_posn <= m_range_min);
449 double fractional_distance =
static_cast<double>(m_posn - m_range_min) / (m_range_max - m_range_min);
450 int tab_width = m_orientation ==
VERTICAL ?
Value(m_tab->Height()) :
Value(m_tab->Width());
451 int line_length = (m_orientation ==
VERTICAL ?
Value(Height()) :
Value(Width())) - tab_width;
452 int pixel_distance =
static_cast<int>(line_length * fractional_distance);
454 m_tab->MoveTo(
Pt(m_tab->RelativeUpperLeft().x, Height() - tab_width - pixel_distance));
456 m_tab->MoveTo(
Pt(
X(pixel_distance), m_tab->RelativeUpperLeft().y));
463 int line_length = m_orientation ==
VERTICAL ?
Value(Height() - m_tab->Height()) :
Value(Width() - m_tab->Width());
464 int tab_posn = (m_orientation ==
VERTICAL ?
Value(Height() - m_tab->RelativeLowerRight().y) :
Value(m_tab->RelativeUpperLeft().x));
465 double fractional_distance =
static_cast<double>(tab_posn) / line_length;
466 m_posn = m_range_min +
static_cast<T
>((m_range_max - m_range_min) * fractional_distance);
467 if (m_posn != old_posn)
468 SlidSignal(m_posn, m_range_min, m_range_max);
472 void Slider<T>::SlideToImpl(T p,
bool signal)
475 if (0 < (m_range_max - m_range_min) ? p < m_range_min : p > m_range_min)
476 m_posn = m_range_min;
477 else if (0 < (m_range_max - m_range_min) ? m_range_max < p : m_range_max > p)
478 m_posn = m_range_max;
482 if (signal && m_posn != old_posn) {
483 SlidSignal(m_posn, m_range_min, m_range_max);
484 SlidAndStoppedSignal(m_posn, m_range_min, m_range_max);
489 Slider<T>::SlidEcho::SlidEcho(
const std::string& name) :
494 void Slider<T>::SlidEcho::operator()(T pos, T min, T max)
496 std::cerr <<
"GG SIGNAL : " << m_name
497 <<
"(pos=" << pos <<
" min=" << min <<
" max=" << max <<
")\n";