1 /*******************************************************************************
2 *                         Goggles Music Manager                                *
3 ********************************************************************************
4 *                        Icon List Widget (under LGPL3)                        *
5 *      Copyright (C) 1999,2009 by Jeroen van der Zijp. All Rights Reserved.    *
6 *                               ---                                            *
7 *                           Modifications                                      *
8 *           Copyright (C) 2006-2021 by Sander Jansen. All Rights Reserved      *
9 *                               ---                                            *
10 * This program is free software: you can redistribute it and/or modify         *
11 * it under the terms of the GNU General Public License as published by         *
12 * the Free Software Foundation, either version 3 of the License, or            *
13 * (at your option) any later version.                                          *
14 *                                                                              *
15 * This program is distributed in the hope that it will be useful,              *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of               *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                *
18 * GNU General Public License for more details.                                 *
19 *                                                                              *
20 * You should have received a copy of the GNU General Public License            *
21 * along with this program.  If not, see http://www.gnu.org/licenses.           *
22 ********************************************************************************/
23 #ifndef GMTRACKLIST_H
24 #define GMTRACKLIST_H
25 
26 enum {
27   COLUMN_JUSTIFY_NORMAL=0,
28   COLUMN_JUSTIFY_CENTER_RIGHT_ALIGNED,
29   COLUMN_JUSTIFY_LEFT_RIGHT_ALIGNED,
30   COLUMN_JUSTIFY_RIGHT,
31   };
32 
33 
34 /// Icon list styles
35 enum {
36   TRACKLIST_EXTENDEDSELECT = 0,                /// Extended selection mode
37   TRACKLIST_SINGLESELECT   = 0x00100000,       /// At most one selected item
38   TRACKLIST_BROWSESELECT   = 0x00200000,       /// Always exactly one selected item
39   TRACKLIST_MULTIPLESELECT = 0x00300000,       /// Multiple selection mode
40   TRACKLIST_NORMAL         = ICONLIST_EXTENDEDSELECT
41   };
42 
43 class GMTrackList;
44 class GMColumn;
45 
46 
47 class GMTrackItem {
48   friend class GMTrackList;
49 protected:
50   FXint   id = 0;
51   FXuchar state = 0;
52 protected:
getColumnData(FXint,FXString &,FXuint &,FXint &)53   virtual const FXString * getColumnData(FXint,FXString &,FXuint &,FXint &) const { return nullptr; }
getIcon()54   virtual FXIcon * getIcon() const { return nullptr; }
55 public:
56   enum {
57     SELECTED      = 0x01,  /// Selected
58     FOCUS         = 0x02,  /// Focus
59     DRAGGABLE     = 0x04,  /// Draggable
60     DONOTPLAY     = 0x08,  /// Playable
61     SHADED        = 0x10   /// Shaded
62     };
63 public:
GMTrackItem()64   GMTrackItem() {}
GMTrackItem(FXint tid)65   GMTrackItem(FXint tid) : id(tid),state(0) {}
66 
67   /// Return track item id
getId()68   FXint getId() const { return id; }
69 
70   /// Select item
71   virtual void setSelected(FXbool selected);
72 
73   /// Return true if this item is selected
isSelected()74   FXbool isSelected() const { return (state&SELECTED)!=0; }
75 
76   /// Make item draw as focused
77   virtual void setFocus(FXbool focus);
78 
79   /// Return true if item has focus
hasFocus()80   FXbool hasFocus() const { return (state&FOCUS)!=0; }
81 
82   /// Make item draggable
83   virtual void setDraggable(FXbool draggable);
84 
85   /// Return true if this item is draggable
isDraggable()86   FXbool isDraggable() const { return (state&DRAGGABLE)!=0; }
87 
88   /// Return true if this item is playable
canPlay()89   FXbool canPlay() const { return (state&DONOTPLAY)==0; }
90 
91   /// Return true if this item is shaded
isShaded()92   FXbool isShaded() const { return (state&SHADED)!=0; }
93 
94   /// Destructor
~GMTrackItem()95   virtual ~GMTrackItem() {}
96   };
97 
98 class GMDBTrackItem;
99 
100 
101 /// Icon item collate function
102 typedef FXint (*GMTrackListSortFunc)(const GMTrackItem*,const GMTrackItem*);
103 
104 class GMColumn {
105   public:
106   FXString            name;
107   FXint               type  = 0;
108   FXint               size  = 60;
109   FXint               index = 0;
110   GMTrackListSortFunc ascending = nullptr;
111   GMTrackListSortFunc descending = nullptr;
112   FXbool              show = false;
113   FXbool              default_show = false;
114   FXbool              default_browser_show = false;
115   FXObject*           target = nullptr;
116   FXSelector          message = 0;
GMColumn()117   GMColumn() {}
name(n)118   GMColumn(const FXchar * n,FXuint t,GMTrackListSortFunc a,GMTrackListSortFunc b,FXint sz=60,FXbool def_show=true,FXbool def_browser_show=true,FXint idx=0,FXObject* tgt=NULL,FXSelector sel=0) : name(n),type(t),size(sz),index(idx),ascending(a),descending(b),show(true),default_show(def_show),default_browser_show(def_browser_show),target(tgt),message(sel) {}
119   };
120 
121 typedef FXArray<GMColumn> GMColumnList;
122 
123 /// List of FXIconItem's
124 typedef FXArray<GMTrackItem*> GMTrackItemList;
125 
126 
127 class GMTrackList : public FXScrollArea {
128 FXDECLARE(GMTrackList)
129 friend class GMTrackItem;
130 protected:
131   FXHeader*          header;            // Header control
132   GMTrackItemList    items;             // Item List
133   FXint              anchor;            // Anchor item
134   FXint              current;           // Current item
135   FXint              extent;            // Extent item
136   FXint              cursor;            // Cursor item
137   FXint              viewable;          // Visible item
138   FXint              active;
139   FXFont            *font;              // Font
140   FXFont            *activeFont;
141   GMTrackListSortFunc sortfunc;         // Item sort function
142   FXColor            textColor;         // Text color
143   FXColor            selbackColor;      // Selected back color
144   FXColor            seltextColor;      // Selected text color
145   FXColor            rowColor;
146   FXColor            activeColor;
147   FXColor            activeTextColor;
148   FXColor            shadowColor;
149   FXint              lineHeight;        // Item height
150   FXint              anchorx;           // Rectangular selection
151   FXint              anchory;
152   FXint              currentx;
153   FXint              currenty;
154   FXint              ratingx;
155   FXint              ratingy;
156   FXint              ratingl;
157   FXint              grabx;             // Grab point x
158   FXint              graby;             // Grab point y
159   FXString           help;              // Help text
160   FXbool             state;             // State of item
161   FXint              sortMethod;
162   FXString           starset;
163   FXString           starunset;
164 protected:
165   GMTrackList();
166   void draw(FXDC& dc,FXEvent *event,FXint index,FXint x,FXint y,FXint w,FXint h,FXint dw) const;
167   void recompute();
168   virtual void moveContents(FXint x,FXint y);
169   void clearRating();
170 private:
171   GMTrackList(const GMTrackList&);
172   GMTrackList &operator=(const GMTrackList&);
173 public:
174   long onPaint(FXObject*,FXSelector,void*);
175   long onEnter(FXObject*,FXSelector,void*);
176   long onLeave(FXObject*,FXSelector,void*);
177   long onUngrabbed(FXObject*,FXSelector,void*);
178   long onKeyPress(FXObject*,FXSelector,void*);
179   long onKeyRelease(FXObject*,FXSelector,void*);
180   long onLeftBtnPress(FXObject*,FXSelector,void*);
181   long onLeftBtnRelease(FXObject*,FXSelector,void*);
182   long onRightBtnPress(FXObject*,FXSelector,void*);
183   long onRightBtnRelease(FXObject*,FXSelector,void*);
184   long onMotion(FXObject*,FXSelector,void*);
185   long onQueryTip(FXObject*,FXSelector,void*);
186   long onQueryHelp(FXObject*,FXSelector,void*);
187   long onTipTimer(FXObject*,FXSelector,void*);
188   long onCmdSelectAll(FXObject*,FXSelector,void*);
189   long onCmdDeselectAll(FXObject*,FXSelector,void*);
190   long onCmdSelectInverse(FXObject*,FXSelector,void*);
191   long onCmdArrangeByRows(FXObject*,FXSelector,void*);
192   long onUpdArrangeByRows(FXObject*,FXSelector,void*);
193   long onCmdArrangeByColumns(FXObject*,FXSelector,void*);
194   long onUpdArrangeByColumns(FXObject*,FXSelector,void*);
195   long onCmdShowDetails(FXObject*,FXSelector,void*);
196   long onUpdShowDetails(FXObject*,FXSelector,void*);
197   long onCmdShowBigIcons(FXObject*,FXSelector,void*);
198   long onUpdShowBigIcons(FXObject*,FXSelector,void*);
199   long onCmdShowMiniIcons(FXObject*,FXSelector,void*);
200   long onUpdShowMiniIcons(FXObject*,FXSelector,void*);
201   long onChgHeader(FXObject*,FXSelector,void*);
202   long onClkHeader(FXObject*,FXSelector,void*);
203   long onCmdHeader(FXObject*,FXSelector,void*);
204   long onUpdHeader(FXObject*,FXSelector,void*);
205   long onHeaderRightBtnRelease(FXObject*,FXSelector,void*);
206   long onFocusIn(FXObject*,FXSelector,void*);
207   long onFocusOut(FXObject*,FXSelector,void*);
208   long onClicked(FXObject*,FXSelector,void*);
209   long onDoubleClicked(FXObject*,FXSelector,void*);
210   long onTripleClicked(FXObject*,FXSelector,void*);
211   long onCommand(FXObject*,FXSelector,void*);
212   long onAutoScroll(FXObject*,FXSelector,void*);
213   long onLookupTimer(FXObject*,FXSelector,void*);
214   long onCmdSetValue(FXObject*,FXSelector,void*);
215   long onCmdGetIntValue(FXObject*,FXSelector,void*);
216   long onCmdSetIntValue(FXObject*,FXSelector,void*);
217   long onMouseLeave(FXObject*,FXSelector,void*);
218   long onWheelTimeout(FXObject*,FXSelector,void*);
219 public:
220   enum {
221     ID_HEADER=FXScrollArea::ID_LAST,
222     ID_SELECT_ALL,
223     ID_DESELECT_ALL,
224     ID_SELECT_INVERSE,
225     ID_WHEEL_TIMEOUT,
226     ID_LAST
227     };
228 public:
229   /// Construct icon list with no items in it initially
230   GMTrackList(FXComposite *p,FXObject* tgt=nullptr,FXSelector sel=0,FXuint opts=TRACKLIST_NORMAL,FXint x=0,FXint y=0,FXint w=0,FXint h=0);
231 
232   /// Find Item by Id
233   FXint findItemById(FXint id) const;
234 
235   /// Get the unique item id
getItemId(FXint index)236   FXint getItemId(FXint index) const { return items[index]->id; }
237 
238   /// Set the sort method
setSortMethod(FXint m)239   void setSortMethod(FXint m) { sortMethod=m; }
240 
241   /// Get the sort method
getSortMethod()242   FXint getSortMethod() const { return sortMethod; }
243 
244   /// Mark the list as unsorted
245   void markUnsorted();
246 
247   /// Create server-side resources
248   virtual void create();
249 
250   /// Detach server-side resources
251   virtual void detach();
252 
253   /// Recalculate layout
254   virtual void recalc();
255 
256   /// Perform layout
257   virtual void layout();
258 
259   /// Return visible area y position
260   virtual FXint getVisibleY() const;
261 
262   /// Return visible area height
263   virtual FXint getVisibleHeight() const;
264 
265   /// Compute and return content width
266   virtual FXint getContentWidth();
267 
268   /// Return content height
269   virtual FXint getContentHeight();
270 
271   /// Icon list can receive focus
272   virtual FXbool canFocus() const;
273 
274   /// Move the focus to this window
275   virtual void setFocus();
276 
277   /// Remove the focus from this window
278   virtual void killFocus();
279 
280   /// Return number of items
getNumItems()281   FXint getNumItems() const { return items.no(); }
282 
283   /// Return header control
getHeader()284   FXHeader* getHeader() const { return header; }
285 
286   /// Return the header data.
getHeaderData(FXint i)287   GMColumn * getHeaderData(FXint i) const { return static_cast<GMColumn*>(header->getItemData(i)); }
288 
289   /// Return the header type
getHeaderType(FXint i)290   FXuint getHeaderType(FXint i) const { return ( (i>=0 && i<header->getNumItems()) ? ((static_cast<GMColumn*>(header->getItemData(i)))->type) : -1); }
291 
292   /// Append header with given text, size and column data
293   void appendHeader(const FXString & label,FXint size,GMColumn * data);
294 
295   /// Remove header at index
296   void removeHeader(FXint index);
297 
298   /// Return number of headers
299   FXint getNumHeaders() const;
300 
301   /// Return index of given header type if displayed, otherwise -1
302   FXint getHeaderByType(FXuint type) const;
303 
304   /// Remove All Headers
305   void clearHeaders();
306 
307   /// Save Header Configuration
308   void saveHeaders();
309 
310   /// Return the item at the given index
311   GMTrackItem *getItem(FXint index) const;
312 
313   /// Replace the item with a [possibly subclassed] item
314   FXint setItem(FXint index,GMTrackItem* item,FXbool notify=false);
315 
316   /// Insert a new [possibly subclassed] item at the give index
317   FXint insertItem(FXint index,GMTrackItem* item,FXbool notify=false);
318 
319   /// Append a [possibly subclassed] item to the end of the list
320   FXint appendItem(GMTrackItem* item,FXbool notify=false);
321 
322   /// Prepend a [possibly subclassed] item to the end of the list
323   FXint prependItem(GMTrackItem* item,FXbool notify=false);
324 
325   /// Move item from oldindex to newindex
326   FXint moveItem(FXint newindex,FXint oldindex,FXbool notify=false);
327 
328   /// Extract item from list
329   GMTrackItem* extractItem(FXint index,FXbool notify=false);
330 
331   /// Remove item from list
332   void removeItem(FXint index,FXbool notify=false);
333 
334   /// Remove all items from list
335   void clearItems(FXbool notify=false);
336 
337   /// Return item height
getLineHeight()338   FXint getLineHeight() const { return lineHeight; }
339 
340   /// Return index of item at x,y, or -1 if none
341   virtual FXint getItemAt(FXint x,FXint y) const;
342 
343   /// Scroll to make item at index visible
344   virtual void makeItemVisible(FXint index);
345 
346   /// Return true if item at index is selected
347   FXbool isItemSelected(FXint index) const;
348 
349   /// Return true if item at index is current
350   FXbool isItemCurrent(FXint index) const;
351 
352   /// Return true if item at index is visible
353   FXbool isItemVisible(FXint index) const;
354 
355   /// Return true if item at index is enabled
356   FXbool isItemEnabled(FXint index) const;
357 
358   /// Check if item is Playable
359   FXbool isItemPlayable(FXint index) const;
360 
361   /// Return item hit code: 0 outside, 1 icon, 2 text
362   FXint hitItem(FXint index,FXint x,FXint y,FXint ww=1,FXint hh=1) const;
363 
364   /// Repaint item at index
365   void updateItem(FXint index) const;
366 
367   /// Select item at index
368   virtual FXbool selectItem(FXint index,FXbool notify=false);
369 
370   /// Deselect item at index
371   virtual FXbool deselectItem(FXint index,FXbool notify=false);
372 
373   /// Toggle item at index
374   virtual FXbool toggleItem(FXint index,FXbool notify=false);
375 
376   /// Select items in rectangle
377   virtual FXbool selectInRectangle(FXint x,FXint y,FXint w,FXint h,FXbool notify=false);
378 
379   /// Extend selection from anchor index to index
380   virtual FXbool extendSelection(FXint index,FXbool notify=false);
381 
382   /// Deselect all items
383   virtual FXbool killSelection(FXbool notify=false);
384 
385   /// Change current item index
386   virtual void setCurrentItem(FXint index,FXbool notify=false);
387 
388   /// Return current item index, or -1 if none
getCurrentItem()389   FXint getCurrentItem() const { return current; }
390 
391   /// Change anchor item index
392   void setAnchorItem(FXint index);
393 
394   /// Return anchor item index, or -1 if none
getAnchorItem()395   FXint getAnchorItem() const { return anchor; }
396 
397   /// Return index of item under cursor, or -1 if none
getCursorItem()398   FXint getCursorItem() const { return cursor; }
399 
400   /// Change active item index
401   void setActiveItem(FXint index);
402 
403   /// Return active item index, or -1 if none
getActiveItem()404   FXint getActiveItem() const { return active; }
405 
406   /// Sort items
407   void sortItems();
408 
409   /// Return sort function
getSortFunc()410   GMTrackListSortFunc getSortFunc() const { return sortfunc; }
411 
412   /// Change sort function
setSortFunc(GMTrackListSortFunc func)413   void setSortFunc(GMTrackListSortFunc func){ sortfunc=func; }
414 
415   /// Change text font
416   void setFont(FXFont* fnt);
417 
418   /// Return text font
getFont()419   FXFont* getFont() const { return font; }
420 
421   /// Change active text font
422   void setActiveFont(FXFont* fnt);
423 
424   /// Return active text font
getActiveFont()425   FXFont* getActiveFont() const { return activeFont; }
426 
427   /// Return normal text color
getTextColor()428   FXColor getTextColor() const { return textColor; }
429 
430   /// Change normal text color
431   void setTextColor(FXColor clr);
432 
433   /// Return selected text background
getSelBackColor()434   FXColor getSelBackColor() const { return selbackColor; }
435 
436   /// Change selected text background
437   void setSelBackColor(FXColor clr);
438 
439   /// Return selected text color
getSelTextColor()440   FXColor getSelTextColor() const { return seltextColor; }
441 
442   /// Change selected text color
443   void setSelTextColor(FXColor clr);
444 
445   /// Return active text color
getActiveTextColor()446   FXColor getActiveTextColor() const { return activeTextColor; }
447 
448   /// Change active text color
449   void setActiveTextColor(FXColor clr);
450 
451   /// Return row color
getRowColor()452   FXColor getRowColor() const { return rowColor; }
453 
454   /// Change the row color
455   void setRowColor(FXColor clr);
456 
457   /// Return active color
getActiveColor()458   FXColor getActiveColor() const { return activeColor; }
459 
460   /// Change the active color
461   void setActiveColor(FXColor clr);
462 
463   /// Change shadow color
464   void setShadowColor(FXColor clr);
465 
466   /// Get shadow color
getShadowColor()467   FXColor getShadowColor() const { return shadowColor; }
468 
469   /// Get the current icon list style
470   FXuint getListStyle() const;
471 
472   /// Set the current icon list style.
473   void setListStyle(FXuint style);
474 
475   /// Set the status line help text for this widget
476   void setHelpText(const FXString& text);
477 
478   /// Get the status line help text for this widget
getHelpText()479   const FXString& getHelpText() const { return help; }
480 
481   /// Save list to a stream
482   virtual void save(FXStream& store) const;
483 
484   /// Load list from a stream
485   virtual void load(FXStream& store);
486 
487   /// Destructor
488   virtual ~GMTrackList();
489   };
490 #endif
491