1 /* Public domain */
2
3 #ifndef _AGAR_GUI_EDITABLE_H_
4 #define _AGAR_GUI_EDITABLE_H_
5
6 #include <agar/gui/widget.h>
7 #include <agar/gui/text.h>
8
9 #include <agar/gui/begin.h>
10
11 struct ag_popup_menu;
12
13 /* Working UCS-4 text buffer for internal use */
14 typedef struct ag_editable_buffer {
15 AG_Variable *var; /* Variable binding (if any) */
16 Uint32 *s; /* String buffer (UCS-4 encoding) */
17 size_t len; /* String length (chars) */
18 size_t maxLen; /* Available buffer size (bytes) */
19 int reallocable; /* Buffer can be realloc'd */
20 } AG_EditableBuffer;
21
22 /* Internal clipboard for copy/paste and kill/yank */
23 typedef struct ag_editable_clipboard {
24 AG_Mutex lock;
25 char encoding[32]; /* Character set encoding */
26 Uint32 *s; /* UCS-4 buffer */
27 size_t len; /* Length in characters */
28 } AG_EditableClipboard;
29
30 typedef struct ag_editable {
31 struct ag_widget wid;
32
33 Uint flags;
34 #define AG_EDITABLE_HFILL 0x000001
35 #define AG_EDITABLE_VFILL 0x000002
36 #define AG_EDITABLE_EXPAND (AG_EDITABLE_HFILL|AG_EDITABLE_VFILL)
37 #define AG_EDITABLE_MULTILINE 0x000004 /* Multiline edition */
38 #define AG_EDITABLE_BLINK_ON 0x000008 /* Cursor blink state (internal) */
39 #define AG_EDITABLE_PASSWORD 0x000010 /* Password (hidden) input */
40 #define AG_EDITABLE_ABANDON_FOCUS 0x000020 /* Abandon focus on return */
41 #define AG_EDITABLE_INT_ONLY 0x000040 /* Accepts only int input */
42 #define AG_EDITABLE_FLT_ONLY 0x000080 /* Accepts only float input */
43 #define AG_EDITABLE_CATCH_TAB 0x000100 /* Process tab key input */
44 #define AG_EDITABLE_CURSOR_MOVING 0x000200 /* Cursor is being moved */
45 #define AG_EDITABLE_KEEPVISCURSOR 0x000800 /* Try to keep cursor visible */
46 #define AG_EDITABLE_MARKPREF 0x002000 /* Mark current cursor position */
47 #define AG_EDITABLE_EXCL 0x004000 /* Exclusive access to buffer */
48 #define AG_EDITABLE_NOEMACS 0x008000 /* Disable emacs-style fn keys */
49 #define AG_EDITABLE_NOLATIN1 0x020000 /* Disable LATIN-1 combinations */
50 #define AG_EDITABLE_WORDWRAP 0x040000 /* Word wrapping */
51 #define AG_EDITABLE_NOPOPUP 0x080000 /* Disable popup menu */
52 #define AG_EDITABLE_WORDSELECT 0x100000 /* Select whole words */
53 #define AG_EDITABLE_READONLY 0x200000 /* Disable user input */
54 #define AG_EDITABLE_MULTILINGUAL 0x400000 /* Multilingual edition */
55
56 const char *encoding; /* Character set (default "UTF-8") */
57 AG_Text *text; /* Default binding */
58 int wPre, hPre; /* Size hint */
59 int pos; /* Cursor position */
60 int sel; /* Selection offset / range */
61 int selDblClick; /* Double click position */
62 Uint32 compose; /* For input composition */
63 int xCurs, yCurs; /* Last cursor position */
64 int xSelStart, ySelStart; /* Last selection start position */
65 int xSelEnd, ySelEnd; /* Last selection end position */
66 int xCursPref; /* Requested cursor position */
67 int x; /* Horizontal offset (px) */
68 int xMax; /* Rightmost x of largest line (px) */
69 int y; /* Vertical offset (lines) */
70 int yMax; /* Lowest y (lines) */
71 int yVis; /* Maximum visible area (lines) */
72 Uint32 wheelTicks; /* For wheel acceleration */
73 AG_EditableBuffer sBuf; /* Working buffer (for STATIC) */
74 AG_Rect r; /* View area */
75 AG_CursorArea *ca; /* Text cursor-change area */
76 int fontMaxHeight; /* Maximum character height */
77 int lineSkip; /* Y-increment in multiline mode */
78 struct ag_popup_menu *pm; /* Right-click popup menu */
79 enum ag_language lang; /* Selected language (for AG_Text) */
80 int xScrollPx; /* Explicit scroll request in pixels */
81 int *xScrollTo, *yScrollTo; /* Scroll to specified position */
82 AG_Timer toRepeat; /* Key repeat timer */
83 AG_Timer toCursorBlink; /* Cursor blink timer */
84 AG_Timer toDblClick; /* Double click timer */
85 } AG_Editable;
86
87 #define AGEDITABLE(p) ((AG_Editable *)(p))
88 #ifdef _AGAR_INTERNAL
89 #define EDITABLE(p) AGEDITABLE(p)
90 #endif
91
92 __BEGIN_DECLS
93 extern AG_WidgetClass agEditableClass;
94 extern AG_EditableClipboard agEditableClipbrd;
95 extern AG_EditableClipboard agEditableKillring;
96
97 AG_Editable *AG_EditableNew(void *, Uint);
98 void AG_EditableBindUTF8(AG_Editable *, char *, size_t);
99 void AG_EditableBindASCII(AG_Editable *, char *, size_t);
100 void AG_EditableBindEncoded(AG_Editable *, const char *, char *, size_t);
101 void AG_EditableBindText(AG_Editable *, AG_Text *);
102 void AG_EditableSetLang(AG_Editable *, enum ag_language);
103
104 AG_EditableBuffer *AG_EditableGetBuffer(AG_Editable *);
105 void AG_EditableReleaseBuffer(AG_Editable *, AG_EditableBuffer *);
106 void AG_EditableClearBuffer(AG_Editable *, AG_EditableBuffer *);
107 int AG_EditableGrowBuffer(AG_Editable *, AG_EditableBuffer *,
108 Uint32 *, size_t);
109
110 int AG_EditableCut(AG_Editable *, AG_EditableBuffer *, AG_EditableClipboard *);
111 int AG_EditableCopy(AG_Editable *, AG_EditableBuffer *, AG_EditableClipboard *);
112 void AG_EditableCopyChunk(AG_Editable *, AG_EditableClipboard *, Uint32 *,
113 size_t);
114 int AG_EditablePaste(AG_Editable *, AG_EditableBuffer *, AG_EditableClipboard *);
115 int AG_EditableDelete(AG_Editable *, AG_EditableBuffer *);
116 void AG_EditableSelectAll(AG_Editable *, AG_EditableBuffer *);
117
118 void AG_EditableSizeHint(AG_Editable *, const char *);
119 void AG_EditableSizeHintPixels(AG_Editable *, Uint, Uint);
120 void AG_EditableSizeHintLines(AG_Editable *, Uint);
121 #define AG_EditablePrescale AG_EditableSizeHint
122 void AG_EditableSetPassword(AG_Editable *, int);
123 void AG_EditableSetWordWrap(AG_Editable *, int);
124 void AG_EditableSetExcl(AG_Editable *, int);
125 void AG_EditableSetFltOnly(AG_Editable *, int);
126 void AG_EditableSetIntOnly(AG_Editable *, int);
127
128 void AG_EditableSetString(AG_Editable *, const char *);
129 #define AG_EditableClearString(tb) AG_EditableSetString((tb),NULL)
130 void AG_EditablePrintf(void *, const char *, ...);
131 char *AG_EditableDupString(AG_Editable *);
132 size_t AG_EditableCopyString(AG_Editable *, char *, size_t)
133 BOUNDED_ATTRIBUTE(__string__, 2, 3);
134 int AG_EditableInt(AG_Editable *);
135 float AG_EditableFlt(AG_Editable *);
136 double AG_EditableDbl(AG_Editable *);
137
138 void AG_EditableInitClipboards(void);
139 void AG_EditableDestroyClipboards(void);
140
141 int AG_EditableMapPosition(AG_Editable *, AG_EditableBuffer *, int, int, int *);
142 void AG_EditableMoveCursor(AG_Editable *, AG_EditableBuffer *, int, int);
143 int AG_EditableSetCursorPos(AG_Editable *, AG_EditableBuffer *, int);
144
145 /* Return current cursor position in text. */
146 static __inline__ int
AG_EditableGetCursorPos(AG_Editable * ed)147 AG_EditableGetCursorPos(AG_Editable *ed)
148 {
149 int rv;
150 AG_ObjectLock(ed);
151 rv = ed->pos;
152 AG_ObjectUnlock(ed);
153 return (rv);
154 }
155
156 /* Return 1 if the Editable is effectively read-only. */
157 static __inline__ int
AG_EditableReadOnly(AG_Editable * ed)158 AG_EditableReadOnly(AG_Editable *ed)
159 {
160 return (ed->flags & AG_EDITABLE_READONLY) || AG_WidgetDisabled(ed);
161 }
162
163 /*
164 * Ensure that the selection range is valid. The Editable and buffer
165 * must both be locked.
166 */
167 static __inline__ void
AG_EditableValidateSelection(AG_Editable * ed,AG_EditableBuffer * buf)168 AG_EditableValidateSelection(AG_Editable *ed, AG_EditableBuffer *buf)
169 {
170 if ((Uint)ed->pos > buf->len) {
171 ed->pos = (int)buf->len;
172 ed->sel = 0;
173 }
174 if (ed->sel != 0) {
175 int ep = ed->pos + ed->sel;
176 if (ep < 0) {
177 ed->pos = 0;
178 ed->sel = 0;
179 } else if ((Uint)ep > buf->len) {
180 ed->pos = (int)buf->len;
181 ed->sel = 0;
182 }
183 }
184 }
185
186 #ifdef AG_LEGACY
187 # define AG_EditableSetFont AG_SetFont
188 # define AG_EditableSetStatic AG_EditableSetExcl
189 # define AG_EDITABLE_STATIC AG_EDITABLE_EXCL
190 # define AG_EDITABLE_NOWORDSEEK 0
191 # define AG_EditableSetWriteable(tb,flag) do { \
192 if (flag) { \
193 AG_WidgetEnable(tb); \
194 } else { \
195 AG_WidgetDisable(tb); \
196 } \
197 } while (0)
198 #endif /* AG_LEGACY */
199
200 __END_DECLS
201
202 #include <agar/gui/close.h>
203 #endif /* _AGAR_GUI_EDITABLE_H_ */
204