1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #ifndef MYGUI_ITEM_BOX_H_
8 #define MYGUI_ITEM_BOX_H_
9 
10 #include "MyGUI_Prerequest.h"
11 #include "MyGUI_DDContainer.h"
12 #include "MyGUI_IBItemInfo.h"
13 #include "MyGUI_Any.h"
14 #include "MyGUI_EventPair.h"
15 #include "MyGUI_ScrollViewBase.h"
16 
17 namespace MyGUI
18 {
19 
20 	typedef delegates::CDelegate2<ItemBox*, Widget*> EventHandle_ItemBoxPtrWidgetPtr;
21 	typedef delegates::CDelegate3<ItemBox*, IntCoord&, bool> EventHandle_ItemBoxPtrIntCoordRefBool;
22 	typedef delegates::CDelegate3<ItemBox*, Widget*, const IBDrawItemInfo&> EventHandle_ItemBoxPtrWidgetPtrCIBCellDrawInfoRef;
23 	typedef delegates::CMultiDelegate2<ItemBox*, size_t> EventHandle_ItemBoxPtrSizeT;
24 	typedef delegates::CMultiDelegate2<ItemBox*, const IBNotifyItemData&> EventHandle_ItemBoxPtrCIBNotifyCellDataRef;
25 
26 	/** \brief @wpage{ItemBox}
27 		ItemBox widget description should be here.
28 	*/
29 	class MYGUI_EXPORT ItemBox :
30 		public DDContainer,
31 		protected ScrollViewBase,
32 		public MemberObsolete<ItemBox>
33 	{
34 		MYGUI_RTTI_DERIVED( ItemBox )
35 
36 	public:
37 		ItemBox();
38 
39 		//------------------------------------------------------------------------------//
40 		// манипуляции айтемами
41 
42 		//! Get number of items
43 		size_t getItemCount() const;
44 
45 		//! Insert an item into a array at a specified position
46 		void insertItemAt(size_t _index, Any _data = Any::Null, bool update = true);
47 
48 		//! Add an item to the end of a array
49 		void addItem(Any _data = Any::Null, bool update = true);
50 
51 		//! Remove item at a specified position
52 		void removeItemAt(size_t _index, bool update = true);
53 
54 		//! Remove all items
55 		void removeAllItems();
56 
57 		//! Redraw at a specified position
58 		void redrawItemAt(size_t _index);
59 
60 		//! Redraw all items
61 		void redrawAllItems();
62 
63 
64 		//------------------------------------------------------------------------------//
65 		// манипуляции выделениями
66 
67 		//! Get index of selected item (ITEM_NONE if none selected)
68 		size_t getIndexSelected() const;
69 
70 		//! Select specified _index
71 		void setIndexSelected(size_t _index);
72 
73 		//! Clear item selection
74 		void clearIndexSelected();
75 
76 
77 		//------------------------------------------------------------------------------//
78 		// манипуляции данными
79 
80 		//! Replace an item data at a specified position
81 		void setItemDataAt(size_t _index, Any _data);
82 
83 		//! Clear an item data at a specified position
84 		void clearItemDataAt(size_t _index);
85 
86 		//! Get item data from specified position
87 		template <typename ValueType>
88 		ValueType* getItemDataAt(size_t _index, bool _throw = true)
89 		{
90 			MYGUI_ASSERT_RANGE(_index, mItemsInfo.size(), "ItemBox::getItemDataAt");
91 			return mItemsInfo[_index].data.castType<ValueType>(_throw);
92 		}
93 
94 
95 		/** Set vertical alignment grid mode */
96 		void setVerticalAlignment(bool _value);
97 		/** Get vertical alignment grid mode flag */
98 		bool getVerticalAlignment() const;
99 
100 		/** Get item index by item Widget pointer */
101 		size_t getIndexByWidget(Widget* _widget);
102 
103 		/** Get widget created for drop */
104 		Widget* getWidgetDrag();
105 
106 		/** Get item Widget pointer by item index if it is visible
107 			@note returned widget can be deleted, so this pointer
108 			is valid only at time when you got it and can be invalid
109 			next frame
110 		*/
111 		Widget* getWidgetByIndex(size_t _index);
112 
113 		/** Interrupt drag as if widget was dropped into empty space */
114 		void resetDrag();
115 
116 		//! @copydoc Widget::setPosition(const IntPoint& _value)
117 		void setPosition(const IntPoint& _value) override;
118 		//! @copydoc Widget::setSize(const IntSize& _value)
119 		void setSize(const IntSize& _value) override;
120 		//! @copydoc Widget::setCoord(const IntCoord& _value)
121 		void setCoord(const IntCoord& _value) override;
122 
123 		using Widget::setPosition;
124 		using Widget::setSize;
125 		using Widget::setCoord;
126 
127 		/** Show VScroll when content size larger than view */
128 		void setVisibleVScroll(bool _value);
129 		/** Get Show VScroll flag */
130 		bool isVisibleVScroll() const;
131 
132 		/** Show HScroll when content size larger than view */
133 		void setVisibleHScroll(bool _value);
134 		/** Get Show HScroll flag */
135 		bool isVisibleHScroll() const;
136 
137 		/** Set view area offset. */
138 		void setViewOffset(const IntPoint& _value);
139 		/** Get view area offset. */
140 		IntPoint getViewOffset();
141 
142 		IntSize getViewSize() override;
143 
144 		/*events:*/
145 		/** Event : Request for creating new item.\n
146 			signature : void method(MyGUI::ItemBox* _sender, MyGUI::Widget* _item)
147 			@param _sender widget that called this event
148 			@param _item widget item pointer
149 		*/
150 		EventHandle_ItemBoxPtrWidgetPtr requestCreateWidgetItem;
151 
152 		/** Event : Request for item coordinate.\n
153 			signature : void method(MyGUI::ItemBox* _sender, MyGUI::IntCoord& _coord, bool _drag)
154 			@param _sender widget that called this event
155 			@param _coord write heer item coordinate
156 			@param _drag is this item dragging
157 		*/
158 		EventHandle_ItemBoxPtrIntCoordRefBool requestCoordItem;
159 
160 		/** Event : Request for item redraw.\n
161 			signature : void method(MyGUI::ItemBox* _sender, MyGUI::Widget* _item, const MyGUI::IBDrawItemInfo& _info)
162 			@param _sender widget that called this event
163 			@param _item widget item pointer
164 			@param _info item info
165 		*/
166 		EventHandle_ItemBoxPtrWidgetPtrCIBCellDrawInfoRef requestDrawItem;
167 
168 		/** Event : Doubleclick or enter pressed on item.\n
169 			signature : void method(MyGUI::ItemBox* _sender, size_t _index)
170 			@param _sender widget that called this event
171 			@param _index item index
172 		*/
173 		EventHandle_ItemBoxPtrSizeT eventSelectItemAccept;
174 
175 		/** Event : Position of selected item was changed.\n
176 			signature : void method(MyGUI::ItemBox* _sender, size_t _index)
177 			@param _sender widget that called this event
178 			@param _index item index
179 		*/
180 		EventHandle_ItemBoxPtrSizeT eventChangeItemPosition;
181 
182 		/** Event : Click on item.\n
183 			signature : void method(MyGUI::ItemBox* _sender, size_t _index)
184 			@param _sender widget that called this event
185 			@param _index item index
186 		*/
187 		EventHandle_ItemBoxPtrSizeT eventMouseItemActivate;
188 
189 		/** Event : Notify about event in item widget.\n
190 			signature : void method(MyGUI::ItemBox* _sender, const MyGUI::IBNotifyItemData& _info)
191 			@param _sender widget that called this event
192 			@param _info info about item notify
193 		*/
194 		EventHandle_ItemBoxPtrCIBNotifyCellDataRef eventNotifyItem;
195 
196 		/*internal:*/
197 		void _resetContainer(bool _update) override;
198 
199 	protected:
200 		void initialiseOverride() override;
201 		void shutdownOverride() override;
202 
203 		struct ItemDataInfo
204 		{
ItemDataInfoItemDataInfo205 			ItemDataInfo(Any _data) :
206 				data(_data) { }
207 			Any data;
208 		};
209 		typedef std::vector<ItemDataInfo> VectorItemInfo;
210 
211 		void onMouseButtonPressed(int _left, int _top, MouseButton _id) override;
212 		void onMouseButtonReleased(int _left, int _top, MouseButton _id) override;
213 		void onKeyButtonPressed(KeyCode _key, Char _char) override;
214 		void onKeyButtonReleased(KeyCode _key) override;
215 		void onMouseDrag(int _left, int _top, MouseButton _id) override;
216 
217 		void onMouseWheel(int _rel) override;
218 		void onKeyLostFocus(Widget* _new) override;
219 		void onKeySetFocus(Widget* _old) override;
220 
221 		void notifyKeyButtonPressed(Widget* _sender, KeyCode _key, Char _char);
222 		void notifyKeyButtonReleased(Widget* _sender, KeyCode _key);
223 		void notifyScrollChangePosition(ScrollBar* _sender, size_t _index);
224 		void notifyMouseWheel(Widget* _sender, int _rel);
225 		void notifyRootMouseChangeFocus(Widget* _sender, bool _focus);
226 		void notifyMouseButtonDoubleClick(Widget* _sender);
227 		size_t _getItemIndex(Widget* _item) override;
228 		void notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id);
229 		void notifyMouseButtonPressed(Widget* _sender, int _left, int _top, MouseButton _id);
230 		void notifyMouseButtonReleased(Widget* _sender, int _left, int _top, MouseButton _id);
231 
232 
233 		void removeDropItems() override;
234 		void updateDropItems() override;
235 		void updateDropItemsState(const DDWidgetState& _state) override;
236 
237 		// Обновляет данные о айтемах, при изменении размеров
238 		void updateMetrics();
239 
240 		// просто обновляет все виджеты что видны
241 		void _updateAllVisible(bool _redraw);
242 
243 		void updateFromResize();
244 
245 		// возвращает следующий айтем, если нет его, то создается
246 		// запросы только последовательно
247 		Widget* getItemWidget(size_t _index);
248 
249 		void _setContainerItemInfo(size_t _index, bool _set, bool _accept) override;
250 
251 		// сбрасываем старую подсветку
252 		void resetCurrentActiveItem();
253 		// ищет и устанавливает подсвеченный айтем
254 		void findCurrentActiveItem();
255 
256 		// запрашиваем у конейтера айтем по позиции мыши
257 		size_t _getContainerIndex(const IntPoint& _point) override;
258 
259 		void setPropertyOverride(const std::string& _key, const std::string& _value) override;
260 
261 	private:
262 		size_t calcIndexByWidget(Widget* _widget);
263 
264 		void requestItemSize();
265 
266 		IntSize getContentSize() override;
267 		IntPoint getContentPosition() override;
268 		void eraseContent() override;
269 		size_t getHScrollPage() override;
270 		size_t getVScrollPage() override;
271 		Align getContentAlign() override;
272 		void setContentPosition(const IntPoint& _point) override;
273 
274 	private:
275 		// наши дети в строках
276 		VectorWidgetPtr mVectorItems;
277 
278 		// размер одного айтема
279 		IntSize mSizeItem;
280 
281 		// размерность скролла в пикселях
282 		IntSize mContentSize;
283 		// позиция скролла п пикселях
284 		IntPoint mContentPosition;
285 
286 		// колличество айтемов в одной строке
287 		int mCountItemInLine;
288 		// колличество линий
289 		int mCountLines;
290 
291 		// самая верхняя строка
292 		int mFirstVisibleIndex;
293 		// текущее смещение верхнего элемента в пикселях
294 		// сколько его пикселей не видно сверху
295 		int mFirstOffsetIndex;
296 
297 		// текущий выделенный элемент или ITEM_NONE
298 		size_t mIndexSelect;
299 		// подсвеченный элемент или ITEM_NONE
300 		size_t mIndexActive;
301 		// индекс со свойством приема или ITEM_NONE
302 		size_t mIndexAccept;
303 		// индекс со свойством отказа или ITEM_NONE
304 		size_t mIndexRefuse;
305 
306 		// имеем ли мы фокус ввода
307 		bool mIsFocus;
308 
309 		// структура данных об айтеме
310 		VectorItemInfo mItemsInfo;
311 
312 		Widget* mItemDrag;
313 		IntPoint mPointDragOffset;
314 
315 		bool mAlignVert;
316 
317 		std::string mDragLayer;
318 	};
319 
320 } // namespace MyGUI
321 
322 #endif // MYGUI_ITEM_BOX_H_
323