1 /*
2  *  ppui/ListBox.h
3  *
4  *  Copyright 2009 Peter Barth
5  *
6  *  This file is part of Milkytracker.
7  *
8  *  Milkytracker is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  Milkytracker is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with Milkytracker.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 /////////////////////////////////////////////////////////////////
24 //
25 //	PPListBox control class
26 //
27 /////////////////////////////////////////////////////////////////
28 #ifndef LISTBOX__H
29 #define LISTBOX__H
30 
31 #include "BasicTypes.h"
32 #include "Control.h"
33 #include "Event.h"
34 #include "SimpleVector.h"
35 
36 // Forwards
37 class PPGraphicsAbstract;
38 class PPScrollbar;
39 class PPFont;
40 class PPButton;
41 
42 class PPListBox : public PPControl, public EventListenerInterface
43 {
44 private:
45 	bool border;
46 	const PPColor* borderColor;
47 	const PPColor* backGroundButtonColor;
48 	const PPColor* textColor;
49 
50 	bool editable;
51 	bool scrollable;
52 	bool autoHideVScroll;
53 	bool autoHideHScroll;
54 
55 	bool showIndex;
56 	pp_int32 indexBaseCount;
57 
58 	bool showSelectionAlways;
59 	bool selectionVisible;
60 	bool onlyShowIndexSelection;
61 	bool keepsFocus;
62 	bool showFocus;
63 	bool centerSelection;
64 	bool selectOnScroll;
65 	bool singleButtonClickEdit;
66 	bool allowDragSelection;
67 	bool rightButtonConfirm;
68 
69 	PPSimpleVector<PPString>* items;
70 	pp_int32 startIndex;
71 	pp_int32 startPos;
72 	pp_int32 selectionIndex;
73 	pp_int32 columnSelectionStart;
74 	pp_int32 columnSelectionEnd;
75 	pp_int32 maxEditSize;
76 	pp_int32 timerTicker;
77 	bool lastTimerState;
78 
79 	pp_int32 visibleHeight;
80 	pp_int32 visibleWidth;
81 
82 	PPButton* backgroundButton;
83 
84 	PPScrollbar* hScrollbar;
85 	PPScrollbar* vScrollbar;
86 
87 	PPControl* caughtControl;
88 	bool controlCaughtByLMouseButton, controlCaughtByRMouseButton;
89 	bool lMouseDown, rMouseDown;
90 
91 	PPFont* font;
92 
93 	// UNDO
94 	PPString* editCopy;
95 
96 	// hack
97 	pp_int32 lastStartIndex;
98 	pp_int32 lastStartPos;
99 	pp_int32 lastSelectionIndex;
100 	bool hadVScrollbar;
101 	bool hadHScrollbar;
102 
103 public:
104 	class ColorQueryListener
105 	{
106 	public:
107 		virtual PPColor getColor(pp_uint32 index, PPListBox& sender) = 0;
108 	};
109 
110 private:
111 	ColorQueryListener* colorQueryListener;
112 
113 public:
114 	PPListBox(pp_int32 id, PPScreen* parentScreen, EventListenerInterface* eventListener,
115 			  const PPPoint& location, const PPSize& size,
116 			  bool border = true,
117 			  bool editable = false,
118 			  bool scrollable = true,
119 			  bool showSelectionAlways = false);
120 
121 	virtual ~PPListBox();
122 
setFont(PPFont * font)123 	void setFont(PPFont* font) { this->font = font; }
getFont()124 	PPFont* getFont() const { return font; }
125 
setBorderColor(const PPColor & color)126 	void setBorderColor(const PPColor& color) { this->borderColor = &color; }
127 
setAutoHideVScroll(bool b)128 	void setAutoHideVScroll(bool b) { autoHideVScroll = b; }
setAutoHideHScroll(bool b)129 	void setAutoHideHScroll(bool b) { autoHideHScroll = b; }
130 
131 	void setShowIndex(bool showIndex);
132 
showSelection(bool b)133 	void showSelection(bool b) { selectionVisible = b; }
134 
setOnlyShowIndexSelection(bool b)135 	void setOnlyShowIndexSelection(bool b) { onlyShowIndexSelection = b; }
136 
setKeepsFocus(bool keepsFocus)137 	void setKeepsFocus(bool keepsFocus) { this->keepsFocus = keepsFocus; }
setShowFocus(bool showFocus)138 	void setShowFocus(bool showFocus) { this->showFocus = showFocus; }
139 
setCenterSelection(bool bCenter)140 	void setCenterSelection(bool bCenter) { centerSelection = bCenter; }
141 
setIndexBaseCount(pp_int32 indexBaseCount)142 	void setIndexBaseCount(pp_int32 indexBaseCount) { this->indexBaseCount = indexBaseCount; }
143 
setSelectOnScroll(bool b)144 	void setSelectOnScroll(bool b) { selectOnScroll = b; }
145 
setSingleButtonClickEdit(bool b)146 	void setSingleButtonClickEdit(bool b) { singleButtonClickEdit = b; }
setAllowDragSelection(bool b)147 	void setAllowDragSelection(bool b) { allowDragSelection = b; }
setRightButtonConfirm(bool b)148 	void setRightButtonConfirm(bool b) { rightButtonConfirm = b; }
149 
setMaxEditSize(pp_int32 max)150 	void setMaxEditSize(pp_int32 max) { maxEditSize = max; }
151 
152 	void addItem(const PPString& item);
153 	const PPString& getItem(pp_int32 index) const;
154 
155 	void updateItem(pp_int32 index, const PPString& item);
156 
getNumItems()157 	pp_int32 getNumItems() const { return items->size(); }
158 
159 	void clear();
160 
getSelectedIndex()161 	pp_uint32 getSelectedIndex() const { return selectionIndex; }
162 
163 	void setSelectedIndex(pp_int32 index, bool adjustStartIndex = true, bool assureCursor = true);
164 	void setSelectedIndexByItem(const PPString& item, bool adjustStartIndex = true);
165 
isLastEntry()166 	bool isLastEntry() const { return selectionIndex == getNumItems() - 1; }
isFirstEntry()167 	bool isFirstEntry() const { return selectionIndex == 0; }
168 
isEditing()169 	bool isEditing() const { return columnSelectionStart>=0; }
170 
171 	void placeCursorAtEnd();
172 	void placeCursorAtStart();
173 
174 	void saveState();
175 
176 	void restoreState(bool assureCursor = true);
177 
178 	// from PPControl
179 	virtual void paint(PPGraphicsAbstract* graphics);
180 
gainsFocus()181 	virtual bool gainsFocus() const { return keepsFocus; }
gainedFocusByMouse()182 	virtual bool gainedFocusByMouse() const { return keepsFocus && ((caughtControl == NULL) && (items->size() > 0)); }
183 
184 	virtual pp_int32 dispatchEvent(PPEvent* event);
185 
186 	virtual void setSize(const PPSize& size);
187 	virtual void setLocation(const PPPoint& location);
188 
189 	// from EventListenerInterface
190 	pp_int32 handleEvent(PPObject* sender, PPEvent* event);
191 
isListBox()192 	virtual bool isListBox() const { return true; }
193 
receiveTimerEvent()194 	virtual bool receiveTimerEvent() const { return true; }
195 
196 	void commitChanges();
197 	void discardChanges();
198 
setColorQueryListener(ColorQueryListener * listener)199 	void setColorQueryListener(ColorQueryListener* listener) { colorQueryListener = listener; }
200 
201 private:
202 	enum SelectReturnCodes
203 	{
204 		SelectReturnCodeDefault,
205 		SelectReturnCodeBreak,
206 		SelectReturnCodePlaceCursor
207 	};
208 
209 	SelectReturnCodes select(const PPPoint* p);
210 
211 	void initialize();
212 
213 	void calcVisible();
214 	void adjustScrollbarPositions();
215 	void adjustScrollbars();
216 
217 	void assureCursorVisible();
218 
219 	// new stuff
220 	PPRect getVisibleRect() const;
221 	pp_int32 getItemHeight() const;
222 	pp_int32 getNumVisibleItems() const;
223 	pp_uint32 getMaxWidth() const;
224 };
225 
226 #endif
227