1// Aseprite UI Library
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2001-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef UI_ENTRY_H_INCLUDED
9#define UI_ENTRY_H_INCLUDED
10#pragma once
11
12#include "obs/signal.h"
13#include "ui/widget.h"
14
15#include <memory>
16
17namespace ui {
18
19 class MouseMessage;
20
21 class Entry : public Widget {
22 public:
23 struct Range {
24 int from = -1, to = -1;
25 Range() { }
26 Range(int from, int to) : from(from), to(to) { }
27 bool isEmpty() const { return from < 0; }
28 int size() const { return to - from; }
29 void reset() { from = to = -1; }
30 };
31
32 Entry(const int maxsize, const char *format, ...);
33 ~Entry();
34
35 void setMaxTextLength(const int maxsize);
36
37 bool isReadOnly() const;
38 void setReadOnly(bool state);
39
40 void showCaret();
41 void hideCaret();
42
43 int caretPos() const { return m_caret; }
44 int lastCaretPos() const;
45
46 void setCaretPos(int pos);
47 void setCaretToEnd();
48
49 void selectText(int from, int to);
50 void selectAllText();
51 void deselectText();
52 std::string selectedText() const;
53 Range selectedRange() const;
54
55 void setSuffix(const std::string& suffix);
56 std::string getSuffix();
57
58 void setTranslateDeadKeys(bool state);
59
60 // for themes
61 void getEntryThemeInfo(int* scroll, int* caret, int* state, Range* range) const;
62 gfx::Rect getEntryTextBounds() const;
63
64 static gfx::Size sizeHintWithText(Entry* entry,
65 const std::string& text);
66
67 // Signals
68 obs::signal<void()> Change;
69
70 protected:
71 // Events
72 bool onProcessMessage(Message* msg) override;
73 void onSizeHint(SizeHintEvent& ev) override;
74 void onPaint(PaintEvent& ev) override;
75 void onSetText() override;
76
77 // New Events
78 virtual void onChange();
79 virtual gfx::Rect onGetEntryTextBounds() const;
80
81 private:
82 enum class EntryCmd {
83 NoOp,
84 InsertChar,
85 ForwardChar,
86 ForwardWord,
87 BackwardChar,
88 BackwardWord,
89 BeginningOfLine,
90 EndOfLine,
91 DeleteForward,
92 DeleteBackward,
93 DeleteBackwardWord,
94 DeleteForwardToEndOfLine,
95 Cut,
96 Copy,
97 Paste,
98 SelectAll,
99 };
100
101 int getCaretFromMouse(MouseMessage* mousemsg);
102 void executeCmd(EntryCmd cmd, int ascii, bool shift_pressed);
103 void forwardWord();
104 void backwardWord();
105 Range wordRange(int pos);
106 bool isPosInSelection(int pos);
107 void showEditPopupMenu(const gfx::Point& pt);
108 void recalcCharBoxes(const std::string& text);
109 bool shouldStartTimer(const bool hasFocus);
110 void deleteRange(const Range& range, std::string& text);
111 void startTimer();
112 void stopTimer();
113
114 class CalcBoxesTextDelegate;
115
116 struct CharBox {
117 int codepoint;
118 int from, to;
119 int width;
120 CharBox() { codepoint = from = to = width = 0; }
121 };
122
123 using CharBoxes = std::vector<CharBox>;
124
125 CharBoxes m_boxes;
126 int m_maxsize;
127 int m_caret;
128 int m_scroll;
129 int m_select;
130 bool m_hidden : 1;
131 bool m_state : 1; // show or not the text caret
132 bool m_readonly : 1;
133 bool m_recent_focused : 1;
134 bool m_lock_selection : 1;
135 bool m_translate_dead_keys : 1;
136 Range m_selecting_words;
137 std::unique_ptr<std::string> m_suffix;
138 };
139
140} // namespace ui
141
142#endif
143