Mercurial > projects > dynamin
diff dynamin/gui/scroll_bar.d @ 0:aa4efef0f0b1
Initial commit of code.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Mon, 15 Jun 2009 22:10:48 -0500 |
parents | |
children | b621b528823d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dynamin/gui/scroll_bar.d Mon Jun 15 22:10:48 2009 -0500 @@ -0,0 +1,301 @@ +// Written in the D programming language +// www.digitalmars.com/d/ + +/* + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Dynamin library. + * + * The Initial Developer of the Original Code is Jordan Miner. + * Portions created by the Initial Developer are Copyright (C) 2007-2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jordan Miner <jminer7@gmail.com> + * + */ + +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; + real _visibleValue = 0.5; + real _thumbDragLoc = -1; + // stores the location of the thumb as a percentage of the track + real _thumbPos; + this() { + valueChanged = new Event!()(&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, real location, real size); + real breadth(); + real length(); + override void whenResized(EventArgs e) { + updateControls(); + } + void layoutControls(Control[] controls, real[] sizes) { + assert(controls.length == sizes.length); + real 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(real)_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: + /// This event occurs after Value has been changed. + Event!() valueChanged; + /// Override this method in a subclass to handle the ValueChanged event. + protected void whenValueChanged(EventArgs e) { } + + override Size bestSize() { + if(cast(VScrollBar)this) + return Size(Theme.current.ScrollBar_size(), 100); + else + return Size(100, Theme.current.ScrollBar_size()); + } + /// + real thumbLocation(); + /// ditto + void thumbLocation(real 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(); + } + /// + real thumbSize(); + /// + real trackStart(); + /// + real trackEnd(); + /// + real 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. + */ + real visibleValue() { return _visibleValue; } + /// ditto + void visibleValue(real 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, real location, real size) { + c.location = [location, 0.0]; + c.size = [size, height]; + } + real breadth() { return height; } + real length() { return width; } + alias ScrollBar.thumbLocation thumbLocation; + real thumbLocation() { return _thumb.x; } + real thumbSize() { return _thumb.width; } + real trackStart() { return _track1.x; } + real 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, real location, real size) { + c.location = [0.0, location]; + c.size = [width, size]; + } + real breadth() { return width; } + real length() { return height; } + alias ScrollBar.thumbLocation thumbLocation; + real thumbLocation() { return _thumb.y; } + real thumbSize() { return _thumb.height; } + real trackStart() { return _track1.y; } + real trackEnd() { return _track2.y+_track2.height; } +} +