/* Public domain */ #ifndef _AGAR_GUI_EDITABLE_H_ #define _AGAR_GUI_EDITABLE_H_ #include #include #include #if AG_MODEL == AG_LARGE # define AG_EDITABLE_MAX 128 /* Built-in (default) buffer size */ #else # define AG_EDITABLE_MAX 64 #endif struct ag_window; struct ag_popup_menu; /* Working UCS-4 text buffer for internal use */ typedef struct ag_editable_buffer { AG_Variable *_Nullable var; /* Variable binding (if any) */ AG_Char *_Nullable s; /* Buffer contents */ AG_Size len; /* String length (chars) */ AG_Size maxLen; /* Available buffer size (bytes) */ int reallocable; /* Buffer can be realloc'd */ Uint32 _pad; } AG_EditableBuffer; /* Recorded modification for Undo/Redo */ typedef struct ag_editable_revision { Uint lenBuffer; /* Length of buffer (for Shared Access) */ Uint32 crc32; /* CRC32 of buffer (for Shared Access) */ int posStart; /* Start position (char index) */ int posEnd; /* End position (char index) */ int nCharsAdded; /* Number of characters added */ int nCharsRemoved; /* Number of characters removed */ AG_Char *_Nullable s; /* Original buffer contents */ } AG_EditableRevision; /* Internal clipboard for copy/paste and kill/yank */ typedef struct ag_editable_clipboard { _Nonnull_Mutex AG_Mutex lock; char encoding[32]; /* Character set encoding */ AG_Char *_Nullable s; /* Clipboard contents */ AG_Size len; /* Length in characters */ AG_SIZE_PADDING(_pad); } AG_EditableClipboard; /* Autocomplete context */ typedef struct ag_autocomplete { AG_Timer to; /* Timer for delay after key-up */ AG_Event *_Nonnull fn; /* Callback routine & arguments */ char winName[AG_OBJECT_NAME_MAX]; /* Name of expanded window (or "") */ Uint32 _pad; } AG_Autocomplete; typedef struct ag_editable { struct ag_widget wid; /* AG_Widget -> AG_Editable */ Uint flags; #define AG_EDITABLE_HFILL 0x0000001 #define AG_EDITABLE_VFILL 0x0000002 #define AG_EDITABLE_EXPAND (AG_EDITABLE_HFILL | AG_EDITABLE_VFILL) #define AG_EDITABLE_MULTILINE 0x0000004 /* Multiline edition */ #define AG_EDITABLE_BLINK_ON 0x0000008 /* Cursor blink state (internal) */ #define AG_EDITABLE_PASSWORD 0x0000010 /* Password (hidden) input */ #define AG_EDITABLE_ABANDON_FOCUS 0x0000020 /* Abandon focus on return */ #define AG_EDITABLE_INT_ONLY 0x0000040 /* Accepts only int input */ #define AG_EDITABLE_FLT_ONLY 0x0000080 /* Accepts only float input */ #define AG_EDITABLE_CATCH_TAB 0x0000100 /* Process tab key input */ #define AG_EDITABLE_CURSOR_MOVING 0x0000200 /* Cursor is being moved */ #define AG_EDITABLE_UPPERCASE 0x0000400 /* Render as uppercase */ #define AG_EDITABLE_KEEPVISCURSOR 0x0000800 /* Try to keep cursor visible */ #define AG_EDITABLE_LOWERCASE 0x0001000 /* Render as lowercase */ #define AG_EDITABLE_MARKPREF 0x0002000 /* Mark current cursor position */ #define AG_EDITABLE_EXCL 0x0004000 /* Exclusive Buffer Access */ #define AG_EDITABLE_NO_KILL_YANK 0x0008000 /* Disable [K]ill and [Y]ank functions */ #define AG_EDITABLE_RETURN_HELD 0x0010000 /* KEY_RETURN or KP_ENTER is held */ #define AG_EDITABLE_NO_ALT_LATIN1 0x0020000 /* Disable alt-key LATIN-1 mappings */ #define AG_EDITABLE_WORDWRAP 0x0040000 /* Word wrapping */ #define AG_EDITABLE_NOPOPUP 0x0080000 /* Disable popup menu */ #define AG_EDITABLE_WORDSELECT 0x0100000 /* Select whole words */ #define AG_EDITABLE_READONLY 0x0200000 /* Disable user input */ #define AG_EDITABLE_MULTILINGUAL 0x0400000 /* Multilingual edition */ #define AG_EDITABLE_SHIFT_SELECT 0x0800000 /* Keyboard (shift) selection mode */ #define AG_EDITABLE_NUMERICAL (AG_EDITABLE_INT_ONLY | AG_EDITABLE_FLT_ONLY) #define AG_EDITABLE_NO_CLIPPING 0x1000000 /* Allow overflow */ int lineScrollAmount; /* Lines to scroll per event */ const char *_Nonnull encoding; /* Character set (default "UTF-8") */ char text[AG_EDITABLE_MAX]; /* Small built-in text buffer */ int hPre; /* Vertical size hint (# of lines) */ int wPre; /* Horizontal size hint (px) */ int pos; /* Cursor position (char index) */ int selStart; /* Start of selection (char index) */ int selEnd; /* End of selection (char index) */ AG_Char compose; /* Last char entered in composition */ int xCurs, yCurs; /* Last cursor position */ int xSelStart, ySelStart; /* Last selection start position */ int xSelEnd, ySelEnd; /* Last selection end position */ int xCursPref; /* Requested cursor position */ int x; /* Horizontal offset (px) */ int xMax; /* Rightmost x of largest line (px) */ int y; /* Vertical offset (lines) */ int yMax; /* Lowest y (lines) */ int yVis; /* Maximum visible area (lines) */ int posKbdSel; /* Start of keyboard selection */ Uint32 _pad; AG_EditableBuffer sBuf; /* Working buffer (for Exclusive Access) */ AG_Rect r; /* Clipping rectangle */ AG_CursorArea *_Nullable ca; /* Text cursor-change area */ enum ag_language lang; /* Selected language (for AG_Text) */ int xScrollPx; /* Explicit scroll request in pixels */ struct ag_popup_menu *_Nullable pm; /* Right-click popup menu */ int *_Nullable xScrollTo; /* Scroll to that X-position */ int *_Nullable yScrollTo; /* Scroll to that Y-position */ AG_Autocomplete *_Nullable complete; /* Autocomplete context */ int fontMaxHeight; /* Maximum character height */ int lineSkip; /* Y-increment in multiline mode */ int suPlaceholder; /* Rendered "placeholder" text label */ int selDblClick; /* Position of last double click (char index) */ AG_Timer toRepeat; /* Key repeat timers (not direction keys) */ AG_Timer toCursorBlink; /* Cursor blink timer */ AG_Timer toDblClick; /* Double click timer */ AG_Timer toRepeatDirs[4]; /* Key repeat timers (UP DN R L) */ Uint nUndo; /* Undo stack size */ Uint nRedo; /* Redo stack size */ AG_EditableRevision *_Nonnull undo; /* Undo stack (History Buffer) */ AG_EditableRevision *_Nonnull redo; /* Redo stack */ } AG_Editable; #define AGEDITABLE(o) ((AG_Editable *)(o)) #define AGcEDITABLE(o) ((const AG_Editable *)(o)) #define AG_EDITABLE_ISA(o) (((AGOBJECT(o)->cid & 0xff000000) >> 24) == 0x0E) #define AG_EDITABLE_SELF() AGEDITABLE( AG_OBJECT(0, "AG_Widget:AG_Editable:*") ) #define AG_EDITABLE_PTR(n) AGEDITABLE( AG_OBJECT((n), "AG_Widget:AG_Editable:*") ) #define AG_EDITABLE_NAMED(n) AGEDITABLE( AG_OBJECT_NAMED((n),"AG_Widget:AG_Editable:*") ) #define AG_cEDITABLE_SELF() AGcEDITABLE( AG_cOBJECT(0, "AG_Widget:AG_Editable:*") ) #define AG_cEDITABLE_PTR(n) AGcEDITABLE( AG_cOBJECT((n), "AG_Widget:AG_Editable:*") ) #define AG_cEDITABLE_NAMED(n) AGcEDITABLE( AG_cOBJECT_NAMED((n) "AG_Widget:AG_Editable:*") ) #define AGEDITABLE_IS_READONLY(ed) (((ed)->flags & AG_EDITABLE_READONLY) || \ AG_WidgetDisabled(ed)) __BEGIN_DECLS extern AG_WidgetClass agEditableClass; extern AG_EditableClipboard agEditableClipbrd; extern AG_EditableClipboard agEditableKillring; AG_Editable *_Nonnull AG_EditableNew(void *_Nullable , Uint); void AG_EditableBindASCII(AG_Editable *_Nonnull, char *_Nonnull, AG_Size); #ifdef AG_UNICODE void AG_EditableBindUTF8(AG_Editable *_Nonnull, char *_Nonnull, AG_Size); void AG_EditableBindEncoded(AG_Editable *_Nonnull, const char *_Nonnull, char *_Nonnull, AG_Size); void AG_EditableBindText(AG_Editable *_Nonnull, AG_TextElement *_Nonnull); void AG_EditableSetLang(AG_Editable *_Nonnull, enum ag_language); #else # define AG_EditableBindUTF8(ed,b,s) AG_EditableBindASCII((ed),(b),(s)) #endif void AG_EditableAutocomplete(AG_Editable *_Nonnull, _Nullable AG_EventFn, const char *_Nullable, ...); void AG_EditableCloseAutocomplete(AG_Editable *_Nonnull); AG_EditableBuffer *_Nullable AG_EditableGetBuffer(AG_Editable *_Nonnull); void AG_EditableReleaseBuffer(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableClearBuffer(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); int AG_EditableGrowBuffer(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, AG_Char *_Nonnull, AG_Size); void AG_EditableClearHistory(AG_Editable *_Nonnull); AG_EditableRevision *AG_EditableBeginRevision(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableAbortRevision(AG_Editable *_Nonnull); void AG_EditableCommitRevision(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableRevert(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, AG_EditableRevision *_Nonnull, AG_EditableRevision *_Nonnull, Uint); void AG_EditableUndo(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableRedo(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); int AG_EditableCut(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, AG_EditableClipboard *_Nonnull, int); int AG_EditableCopy(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, AG_EditableClipboard *_Nonnull, int); void AG_EditableCopyChunk(AG_Editable *_Nonnull, AG_EditableClipboard *_Nonnull, AG_Char *_Nonnull, AG_Size); int AG_EditablePaste(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, AG_EditableClipboard *_Nonnull, int); int AG_EditableDelete(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableSelectAll(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull); void AG_EditableSizeHint(AG_Editable *_Nonnull, const char *_Nonnull); void AG_EditableSizeHintPixels(AG_Editable *_Nonnull, Uint,Uint); void AG_EditableSizeHintLines(AG_Editable *_Nonnull, Uint); void AG_EditableSetPassword(AG_Editable *_Nonnull, int); void AG_EditableSetWordWrap(AG_Editable *_Nonnull, int); void AG_EditableSetExcl(AG_Editable *_Nonnull, int); void AG_EditableSetString(AG_Editable *_Nonnull, const char *_Nullable); void AG_EditableClearString(AG_Editable *_Nonnull); void AG_EditablePrintf(AG_Editable *_Nonnull, const char *_Nullable, ...); char *_Nonnull AG_EditableDupString(AG_Editable *_Nonnull); AG_Size AG_EditableCopyString(AG_Editable *_Nonnull, char *_Nonnull, AG_Size); int AG_EditableCatString(AG_Editable *_Nonnull, const char *_Nonnull, ...); int AG_EditableCatStringS(AG_Editable *_Nonnull, const char *_Nonnull); int AG_EditableInt(AG_Editable *_Nonnull); void AG_EditableSetIntOnly(AG_Editable *_Nonnull, int); float AG_EditableFlt(AG_Editable *_Nonnull); double AG_EditableDbl(AG_Editable *_Nonnull); void AG_EditableSetFltOnly(AG_Editable *_Nonnull, int); void AG_EditableInitClipboards(void); void AG_EditableDestroyClipboards(void); int AG_EditableMapPosition(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, int,int, int *_Nonnull); void AG_EditableMoveCursor(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, int,int); int AG_EditableGetCursorPos(const AG_Editable *_Nonnull) _Pure_Attribute; int AG_EditableSetCursorPos(AG_Editable *_Nonnull, AG_EditableBuffer *_Nonnull, int); int AG_EditableReadOnly(AG_Editable *_Nonnull) _Pure_Attribute_If_Unthreaded; void AG_EditableValidateSelection(AG_Editable *_Nonnull, const AG_EditableBuffer *_Nonnull); #ifdef AG_LEGACY # define AG_EDITABLE_NOEMACS AG_EDITABLE_NO_KILL_YANK # define AG_EDITABLE_NOLATIN1 AG_EDITABLE_NO_ALT_LATIN1 # define AG_EditablePrescale(ed,s) AG_EditableSizeHint((ed),(s)) #endif __END_DECLS #include #endif /* _AGAR_GUI_EDITABLE_H_ */