Mercurial > projects > dynamin
view dynamin/gui/scroll_bar.d @ 104:5c8c1c2e12c0
Change from real to double.
double is not dependant on the platform, and it uses less space.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Fri, 06 Jul 2012 18:39:45 -0500 |
parents | 73060bc3f004 |
children | acdbb30fee7e |
line wrap: on
line source
/* * Copyright Jordan Miner * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * */ module dynamin.gui.scroll_bar; import dynamin.all_core; import dynamin.all_gui; import dynamin.all_painting; import tango.io.Stdout; enum ArrowDirection { Left, Right, Up, Down } class ArrowButton : Button { ArrowDirection _direction; ArrowDirection direction() { return _direction; } void direction(ArrowDirection dir) { _direction = dir; } override void whenPainting(PaintingEventArgs e) { Theme.current.ArrowButton_paint(this, e.graphics); } } class ScrollBarTrack : Button { override void whenPainting(PaintingEventArgs e) { Theme.current.ScrollBarTrack_paint(this, e.graphics); } } class ScrollBarThumb : Button { override void whenMouseDown(MouseEventArgs e) { } override void whenMouseDragged(MouseEventArgs e) { } override void whenPainting(PaintingEventArgs e) { Theme.current.ScrollBarThumb_paint(this, e.graphics); } } //debug=ScrollBar; /// abstract class ScrollBar : Container { protected: ScrollBarTrack _track1, _track2; ScrollBarThumb _thumb; ArrowButton _button1, _button2; int _value = 0, _maxValue = 100; double _visibleValue = 0.5; double _thumbDragLoc = -1; // stores the location of the thumb as a percentage of the track double _thumbPos; this() { valueChanged.setUp(&whenValueChanged); _track1 = new ScrollBarTrack; _track2 = new ScrollBarTrack; _thumb = new ScrollBarThumb; _button1 = new ArrowButton; _button2 = new ArrowButton; _track1.mouseDown += &whenTrack1MouseDown; _track2.mouseDown += &whenTrack2MouseDown; _thumb.mouseDown += &whenThumbMouseDown; _thumb.mouseUp += &whenThumbMouseUp; _thumb.mouseDragged += &whenThumbMouseDragged; _button1.mouseDown += &whenButton1MouseDown; _button2.mouseDown += &whenButton2MouseDown; add(_track1); add(_track2); add(_thumb); add(_button1); add(_button2); size = _size; } void whenThumbMouseDown(MouseEventArgs e); void whenThumbMouseDragged(MouseEventArgs e); void whenThumbMouseUp(MouseEventArgs e) { // This gives the behavior of the thumb jumping when MaxValue // is smaller than the track to exactly represent where // Value is, as jEdit and some of Windows' controls do. _thumbPos = 0; updateControls(); } void whenTrack1MouseDown(MouseEventArgs e) { value = value - 100; } void whenTrack2MouseDown(MouseEventArgs e) { value = value + 100; } void whenButton1MouseDown(MouseEventArgs e) { value = value - 10; } void whenButton2MouseDown(MouseEventArgs e) { value = value + 10; } void putControl(Control c, double location, double size); double breadth(); double length(); override void whenResized(EventArgs e) { updateControls(); } void layoutControls(Control[] controls, double[] sizes) { assert(controls.length == sizes.length); double loc = 0; for(int i = 0; i < controls.length; ++i) { putControl(controls[i], loc, sizes[i]); loc += sizes[i]; } } // updates controls based on what value, visible value, and max value are void updateControls() { if(breadth*2 > length) { return; // no track or thumb } // if thumbPos does not represent the current value if(cast(int)(_thumbPos * _maxValue) != _value) _thumbPos = _value / cast(double)_maxValue; auto totalSz = length; auto buttonSz = breadth; auto totalTrackSz = totalSz - buttonSz*2; auto thumbSz = round(totalTrackSz*_visibleValue); auto thumbLoc = buttonSz+(totalTrackSz-thumbSz)*_thumbPos; if(thumbSz < 8) thumbSz = 8; auto track1Sz = thumbLoc-buttonSz; auto track2Sz = totalTrackSz-track1Sz-thumbSz; if(track1Sz < 0) track1Sz = 0; if(track2Sz < 0) track2Sz = 0; debug(ScrollBar) { Stdout.format("value={}", value).newline; Stdout.format("visibleValue={}", visibleValue).newline; Stdout.format("maxValue={}", maxValue).newline; Stdout.format("totalSz={}", totalSz).newline; Stdout.format("buttonSz={}", buttonSz).newline; Stdout.format("totalTrackSz={}", totalTrackSz).newline; Stdout.format("thumbSz={}", thumbSz).newline; Stdout.format("track1Sz={}", track1Sz).newline; Stdout.format("track2Sz={}", track2Sz).newline; Stdout("********").newline; assert(2*buttonSz+track1Sz+thumbSz+track2Sz <= totalSz + 0.01); } layoutControls([cast(Control) _button1, _track1, _thumb, _track2, _button2], [buttonSz, track1Sz, thumbSz, track2Sz, buttonSz]); } public: /// Override this method in a subclass to handle the ValueChanged event. protected void whenValueChanged(EventArgs e) { } /// This event occurs after Value has been changed. Event!(whenValueChanged) valueChanged; override Size bestSize() { if(cast(VScrollBar)this) return Size(Theme.current.ScrollBar_size(), 100); else return Size(100, Theme.current.ScrollBar_size()); } /// double thumbLocation(); /// ditto void thumbLocation(double loc) { // TODO: return if no thumb (too small for one) if(loc < trackStart) loc = trackStart; if(loc > trackEnd - thumbSize) loc = trackEnd - thumbSize; if(floatsEqual(loc, thumbLocation, 0.1)) return; _thumbPos = (loc - trackStart) / (trackSize - thumbSize); value = cast(int)(_thumbPos * _maxValue); updateControls(); } /// double thumbSize(); /// double trackStart(); /// double trackEnd(); /// double trackSize() { return trackEnd-trackStart; } /// int value() { return _value; } /// ditto void value(int val) { if(val < 0) val = 0; else if(val > _maxValue) val = _maxValue; if(val == _value) return; _value = val; updateControls(); valueChanged(new EventArgs); } /// int maxValue() { return _maxValue; } /// ditto void maxValue(int val) { if(val < 1) val = 1; if(val == _maxValue) return; _maxValue = val; if(_value > _maxValue) _value = _maxValue; if(_visibleValue > _maxValue) _visibleValue = _maxValue; updateControls(); } /** * A floating-point number between 0 and 1 that specifies how large the * thumb should be compared to the track. A value of 0 makes the thumb its * minimum size, and a value of 1 makes the thumb take up all of the track. * The default is 0.5. */ double visibleValue() { return _visibleValue; } /// ditto void visibleValue(double val) { if(val < 0) val = 0; else if(val > 1) val = 1; if(val == _visibleValue) return; _visibleValue = val; updateControls(); } } /// class HScrollBar : ScrollBar { this() { _button1.direction = ArrowDirection.Left; _button2.direction = ArrowDirection.Right; } protected: void whenThumbMouseDown(MouseEventArgs e) { _thumbDragLoc = e.location.x; } void whenThumbMouseDragged(MouseEventArgs e) { _thumb.state = ButtonState.Pressed; thumbLocation = e.location.x + _thumb.location.x - _thumbDragLoc; } void putControl(Control c, double location, double size) { c.location = [location, 0.0]; c.size = [size, height]; } double breadth() { return height; } double length() { return width; } alias ScrollBar.thumbLocation thumbLocation; double thumbLocation() { return _thumb.x; } double thumbSize() { return _thumb.width; } double trackStart() { return _track1.x; } double trackEnd() { return _track2.x+_track2.width; } } /// class VScrollBar : ScrollBar { this() { _button1.direction = ArrowDirection.Up; _button2.direction = ArrowDirection.Down; } protected: void whenThumbMouseDown(MouseEventArgs e) { _thumbDragLoc = e.location.y; } void whenThumbMouseDragged(MouseEventArgs e) { _thumb.state = ButtonState.Pressed; thumbLocation = e.location.y + _thumb.location.y - _thumbDragLoc; } void putControl(Control c, double location, double size) { c.location = [0.0, location]; c.size = [width, size]; } double breadth() { return width; } double length() { return height; } alias ScrollBar.thumbLocation thumbLocation; double thumbLocation() { return _thumb.y; } double thumbSize() { return _thumb.height; } double trackStart() { return _track1.y; } double trackEnd() { return _track2.y+_track2.height; } }