1 module pixelperfectengine.concrete.elements.checkbox;
2 
3 public import pixelperfectengine.concrete.elements.base;
4 
5 /**
6  * Implements a checkbox, that can take a binary choice option from the user.
7  */
8 public class CheckBox : WindowElement, ISmallButton {
9 	public string		iconChecked = "checkBoxB";		///Sets the icon for checked positions
10 	public string		iconUnchecked = "checkBoxA";	///Sets the icon for unchecked positions
11 	public EventDeleg 	onToggle;
12 	/**
13 	 * Creates an instance of a checkbox with a text object.
14 	 * Params:
15 	 *   text = The text to be displayed besides the button.
16 	 *   source = The source of the events emitted by this object.
17 	 *   position = Defines where the element should be drawn.
18 	 *   checked = Initial state of the button.
19 	 */
20 	public this(Text text, string source, Box position, bool checked = false) {
21 		this.position = position;
22 		this.text = text;
23 		this.source = source;
24 		isChecked = checked;
25 	}
26 	/**
27 	 * Creates an instance of a checkbox with a default formatted text.
28 	 * Params:
29 	 *   text = The text to be displayed besides the button.
30 	 *   source = The source of the events emitted by this object.
31 	 *   position = Defines where the element should be drawn.
32 	 *   checked = Initial state of the button.
33 	 */
34 	public this(dstring text, string source, Box position, bool checked = false) {
35 		this(new Text(text, getStyleSheet().getChrFormatting("checkBox")), source, position, checked);
36 	}
37 	/**
38 	 * Creates a small button version of the checkbox for windows, toolbars, etc.
39 	 * Params:
40 	 *   iconChecked = The icon when the button is checked.
41 	 *   iconUnchecked = The icon when the button is unchecked.
42 	 *   source = The source of the events emitted by this object.
43 	 *   position = Defines where the element should be drawn.
44 	 *   checked = Initial state of the button.
45 	 */
46 	public this(string iconChecked, string iconUnchecked, string source, Box position, bool checked = false) {
47 		this.position = position;
48 		this.iconChecked = iconChecked;
49 		this.iconUnchecked = iconUnchecked;
50 		this.source = source;
51 		isChecked = checked;
52 	}
53 	public override void draw() {
54 		parent.clearArea(position);
55 		StyleSheet ss = getStyleSheet;
56 		Bitmap8Bit icon = isChecked ? ss.getImage(iconChecked) : ss.getImage(iconUnchecked);
57 		
58 		parent.bitBLT(position.cornerUL, icon);
59 		
60 		if (text) {
61 			Coordinate textPos = position;
62 			textPos.left += ss.getImage(iconChecked).width + ss.drawParameters["TextSpacingSides"];
63 			parent.drawTextSL(textPos, text, Point(0, 0));
64 		}
65 		if (isFocused) {
66 			const int textPadding = ss.drawParameters["horizTextPadding"];
67 			parent.drawBoxPattern(position - textPadding, ss.pattern["blackDottedLine"]);
68 		}
69 		if (state == ElementState.Disabled) {
70 			parent.bitBLTPattern(Box(position.left, position.top, position.left + icon.width - 1, position.top + icon.height - 1
71 					), ss.getImage("ElementDisabledPtrn"));
72 		}
73 
74 		if (onDraw !is null) {
75 			onDraw();
76 		}
77 	}
78 	
79 	
80 	public override void passMCE(MouseEventCommons mec, MouseClickEvent mce) {
81 		if (state != ElementState.Enabled) return;
82 		mce.x -= position.left;
83 		mce.y -= position.top;
84 		const int width = getStyleSheet().getImage(iconChecked).width;
85 		if (mce.button == MouseButton.Left && mce.state == ButtonState.Pressed && mce.x < width) {
86 			if (isChecked) {
87 				unCheck;
88 			} else {
89 				check;
90 			}
91 			if (onToggle !is null) {
92 				onToggle(new Event(this, EventType.Toggle, SourceType.WindowElement));
93 			}
94 		}
95 		super.passMCE(mec, mce);
96 	}
97 	/**
98 	 * Sets the value of the checkbox to checked.
99 	 * Does not inwoke any events.
100 	 */
101 	public bool check() @trusted {
102 		flags |= IS_CHECKED;
103 		draw();
104 		return isChecked;
105 	}
106 	/**
107 	 * Sets the value of the checkbox to unchecked.
108 	 * Does not inwoke any events.
109 	 */
110 	public bool unCheck() @trusted {
111 		flags &= ~IS_CHECKED;
112 		draw();
113 		return isChecked;
114 	}
115 	/**
116 	 * Toggles the checkbox.
117 	 * Inwokes an `onToggle` event if delegate is set.
118 	 */
119 	public bool toggle() {
120 		if (isChecked) {
121 			unCheck;
122 		} else {
123 			check;
124 		}
125 		if (onToggle !is null) {
126 			onToggle(new Event(this, EventType.Toggle, SourceType.WindowElement));
127 		}
128 		return isChecked();
129 	}
130 	/**
131 	 * Toggles the checkbox to the given value.
132 	 * Inwokes an `onToggle` event if delegate is set.
133 	 */
134 	public bool toggle(bool val) {
135 		if (isChecked == val)
136 			return val;
137 		else
138 			return toggle();
139 	}
140 	///Returns true if the checkbox is a small button.
141 	public bool isSmallButtonHeight(int height) {
142 		if (text) return false;
143 		else if (position.width == height && position.height == height) return true;
144 		else return false;
145 	}
146 	///Returns true if left side justified, false otherwise.
147 	public bool isLeftSide() @nogc @safe pure nothrow const {
148 		return flags & IS_LHS ? true : false;
149 	}
150 	///Sets the small button to the left side if true.
151 	public bool isLeftSide(bool val) @nogc @safe pure nothrow {
152 		if (val) flags |= IS_LHS;
153 		else flags &= ~IS_LHS;
154 		return flags & IS_LHS ? true : false;
155 	}
156 }