1 /* Public domain */
2
3 #ifndef _AGAR_WIDGET_TLIST_H_
4 #define _AGAR_WIDGET_TLIST_H_
5
6 #include <agar/gui/scrollbar.h>
7 #include <agar/gui/menu.h>
8 #include <agar/gui/label.h>
9
10 #include <agar/gui/begin.h>
11
12 #define AG_TLIST_LABEL_MAX AG_LABEL_MAX
13 #define AG_TLIST_ARGS_MAX 8
14
15 typedef struct ag_tlist_popup {
16 const char *iclass; /* Apply to items of this class */
17 AG_Menu *menu;
18 AG_MenuItem *item;
19 AG_Window *panel;
20 AG_TAILQ_ENTRY(ag_tlist_popup) popups;
21 } AG_TlistPopup;
22
23 typedef struct ag_tlist_item {
24 int selected; /* Effective selection */
25 AG_Surface *iconsrc; /* Source icon (or NULL) */
26 int icon; /* Cached icon surface */
27 void *p1; /* User-supplied pointer */
28 const char *cat; /* User-supplied category */
29 char text[AG_TLIST_LABEL_MAX]; /* Label text */
30 int label; /* Cached label surface */
31 Uint depth; /* Indent in tree display */
32 Uint flags;
33 #define AG_TLIST_EXPANDED 0x01 /* Child items visible (tree) */
34 #define AG_TLIST_HAS_CHILDREN 0x02 /* Child items exist (tree) */
35 #define AG_TLIST_DYNICON 0x04 /* Use a copy of iconsrc */
36 #define AG_TLIST_NO_SELECT 0x08 /* Item is not selectable */
37 #define AG_TLIST_NO_POPUP 0x10 /* Disable popups for item */
38 #define AG_TLIST_VISIBLE_CHILDREN AG_TLIST_EXPANDED
39
40 AG_TAILQ_ENTRY(ag_tlist_item) items; /* Items in list */
41 AG_TAILQ_ENTRY(ag_tlist_item) selitems; /* Saved selection state */
42 } AG_TlistItem;
43
44 typedef AG_TAILQ_HEAD(ag_tlist_itemq, ag_tlist_item) AG_TlistItemQ;
45
46 typedef struct ag_tlist {
47 struct ag_widget wid;
48 Uint flags;
49 #define AG_TLIST_MULTI 0x001 /* Multiple selections (ctrl/shift) */
50 #define AG_TLIST_MULTITOGGLE 0x002 /* Multiple toggle-style selections */
51 #define AG_TLIST_POLL 0x004 /* Generate tlist-poll events */
52 #define AG_TLIST_TREE 0x010 /* Hack to display trees */
53 #define AG_TLIST_HFILL 0x020
54 #define AG_TLIST_VFILL 0x040
55 #define AG_TLIST_NOSELSTATE 0x100 /* Don't preserve sel state in poll */
56 #define AG_TLIST_SCROLLTOSEL 0x200 /* Scroll to initial selection */
57 #define AG_TLIST_REFRESH 0x400 /* Repopulate display (for polling) */
58 #define AG_TLIST_EXPAND (AG_TLIST_HFILL|AG_TLIST_VFILL)
59
60 void *selected; /* Default `selected' binding */
61 int wHint, hHint; /* Size hint */
62 int wSpace; /* Icon/text spacing */
63
64 int item_h; /* Item height */
65 int icon_w; /* Item icon width */
66 void *dblClicked; /* Used by double click */
67 AG_TlistItemQ items; /* Current Items */
68 AG_TlistItemQ selitems; /* Saved item state */
69 int nitems; /* Current item count */
70 int nvisitems; /* Visible item count */
71 AG_Scrollbar *sbar; /* Vertical scrollbar */
72 AG_TAILQ_HEAD_(ag_tlist_popup) popups; /* Popup menus */
73 int (*compare_fn)(const AG_TlistItem *, const AG_TlistItem *);
74 AG_Event *popupEv; /* Popup menu hook */
75 AG_Event *changedEv; /* Selection change hook */
76 AG_Event *dblClickEv; /* Double click hook */
77 AG_Timer moveTo; /* Timer for keyboard motion */
78 Uint32 wheelTicks; /* For wheel acceleration */
79 int wRow; /* Row width */
80 AG_Rect r; /* View area */
81 AG_Timer refreshTo; /* Timer for polled mode updates */
82 int rOffs; /* Row display offset */
83 AG_Timer dblClickTo; /* Timer for detecting double clicks */
84 int lastKeyDown; /* For key repeat */
85 } AG_Tlist;
86
87 #define AG_TLIST_FOREACH(it, tl) \
88 AG_TAILQ_FOREACH(it, &(tl)->items, items)
89
90 #define AG_TLIST_FOREACH_ITEM(p, tl, it, t) \
91 for((it) = AG_TAILQ_FIRST(&(tl)->items), \
92 (p) = (it)!=NULL ? (struct t *)(it)->p1 : NULL; \
93 (it) != AG_TAILQ_END(&(tl)->children) && (it)->p1 != NULL; \
94 (it) = AG_TAILQ_NEXT((it), cobjs), \
95 (p) = (it)!=NULL ? (struct t *)(it)->p1 : NULL)
96
97 #define AG_TLIST_ITEM(n) AG_TlistSelectedItemPtr(AG_PTR(n))
98
99 __BEGIN_DECLS
100 extern AG_WidgetClass agTlistClass;
101
102 AG_Tlist *AG_TlistNew(void *, Uint);
103 AG_Tlist *AG_TlistNewPolled(void *, Uint, AG_EventFn, const char *, ...);
104
105 void AG_TlistSizeHint(AG_Tlist *, const char *, int);
106 void AG_TlistSizeHintPixels(AG_Tlist *, int, int);
107 void AG_TlistSizeHintLargest(AG_Tlist *, int);
108 #define AG_TlistPrescale AG_TlistSizeHint
109
110 void AG_TlistSetItemHeight(AG_Tlist *, int);
111 void AG_TlistSetIconWidth(AG_Tlist *, int);
112 void AG_TlistSetIcon(AG_Tlist *, AG_TlistItem *, AG_Surface *);
113 void AG_TlistSetRefresh(AG_Tlist *, int);
114
115 void AG_TlistSetArgs(AG_TlistItem *, const char *, ...);
116 void AG_TlistDel(AG_Tlist *, AG_TlistItem *);
117 void AG_TlistUniq(AG_Tlist *);
118 void AG_TlistClear(AG_Tlist *);
119 void AG_TlistRestore(AG_Tlist *);
120 AG_TlistItem *AG_TlistAdd(AG_Tlist *, AG_Surface *, const char *, ...);
121 AG_TlistItem *AG_TlistAddS(AG_Tlist *, AG_Surface *, const char *);
122 AG_TlistItem *AG_TlistAddHead(AG_Tlist *, AG_Surface *, const char *, ...);
123 AG_TlistItem *AG_TlistAddHeadS(AG_Tlist *, AG_Surface *, const char *);
124 AG_TlistItem *AG_TlistAddPtr(AG_Tlist *, AG_Surface *, const char *, void *);
125 AG_TlistItem *AG_TlistAddPtrHead(AG_Tlist *, AG_Surface *, const char *,
126 void *);
127 void AG_TlistSelect(AG_Tlist *, AG_TlistItem *);
128 void AG_TlistDeselect(AG_Tlist *, AG_TlistItem *);
129 void AG_TlistSelectAll(AG_Tlist *);
130 AG_TlistItem *AG_TlistSelectPtr(AG_Tlist *, void *);
131 AG_TlistItem *AG_TlistSelectText(AG_Tlist *, const char *);
132 void AG_TlistDeselectAll(AG_Tlist *);
133 AG_TlistItem *AG_TlistFindByIndex(AG_Tlist *, int);
134 AG_TlistItem *AG_TlistSelectedItem(AG_Tlist *);
135 void *AG_TlistSelectedItemPtr(AG_Tlist *);
136 void *AG_TlistFindPtr(AG_Tlist *);
137 AG_TlistItem *AG_TlistFindText(AG_Tlist *, const char *);
138 AG_TlistItem *AG_TlistFirstItem(AG_Tlist *);
139 AG_TlistItem *AG_TlistLastItem(AG_Tlist *);
140 AG_MenuItem *AG_TlistSetPopup(AG_Tlist *, const char *);
141 void AG_TlistScrollToStart(AG_Tlist *);
142 void AG_TlistScrollToEnd(AG_Tlist *);
143
144 void AG_TlistSetDblClickFn(AG_Tlist *, AG_EventFn, const char *, ...);
145 void AG_TlistSetPopupFn(AG_Tlist *, AG_EventFn, const char *, ...);
146 void AG_TlistSetChangedFn(AG_Tlist *, AG_EventFn, const char *, ...);
147 void AG_TlistSetCompareFn(AG_Tlist *, int (*)(const AG_TlistItem *,
148 const AG_TlistItem *));
149 int AG_TlistCompareStrings(const AG_TlistItem *, const AG_TlistItem *);
150 int AG_TlistComparePtrs(const AG_TlistItem *, const AG_TlistItem *);
151 int AG_TlistComparePtrsAndClasses(const AG_TlistItem *, const AG_TlistItem *);
152 int AG_TlistSort(AG_Tlist *);
153
154 #define AG_TlistBegin AG_TlistClear
155 #define AG_TlistEnd AG_TlistRestore
156
157 static __inline__ int
AG_TlistVisibleChildren(AG_Tlist * tl,AG_TlistItem * cit)158 AG_TlistVisibleChildren(AG_Tlist *tl, AG_TlistItem *cit)
159 {
160 AG_TlistItem *sit;
161
162 AG_TAILQ_FOREACH(sit, &tl->selitems, selitems) {
163 if (tl->compare_fn(sit, cit))
164 break;
165 }
166 if (sit == NULL) {
167 return (0); /* TODO default setting */
168 }
169 return (sit->flags & AG_TLIST_VISIBLE_CHILDREN);
170 }
171
172 static __inline__ void
AG_TlistRefresh(AG_Tlist * tl)173 AG_TlistRefresh(AG_Tlist *tl)
174 {
175 AG_ObjectLock(tl);
176 tl->flags |= AG_TLIST_REFRESH;
177 AG_ObjectUnlock(tl);
178 }
179 __END_DECLS
180
181 #include <agar/gui/close.h>
182 #endif /* _AGAR_WIDGET_TLIST_H_ */
183