1 #include "plat-sdl/platform.hpp"
7 volatile uint32_t autorepeat_first
= 10;
8 volatile uint32_t autorepeat_subsequent
= 4;
11 commandline_model::commandline_model() throw()
14 autorepeating_key
= SPECIAL_NOOP
;
17 overwrite_mode
= false;
20 std::string
commandline_model::key(uint32_t k
) throw(std::bad_alloc
)
27 history
.push_front(codepoints
);
39 //Set up autorepeat if needed.
40 if(k
& PRESSED_MASK
) {
41 autorepeating_key
= k
;
42 autorepeat_counter
= 0;
45 //These all are active on positive edge.
46 autorepeating_key
= SPECIAL_NOOP
;
47 autorepeat_counter
= 0;
52 switch(k
& ~PRESSED_MASK
) {
54 overwrite_mode
= !overwrite_mode
;
59 cursor_pos
= codepoints
.size();
67 scroll_history_down();
74 if(cursor_pos
< codepoints
.size())
77 case SPECIAL_BACKSPACE
:
81 delete_codepoint(cursor_pos
- 1);
85 if(cursor_pos
== codepoints
.size())
88 delete_codepoint(cursor_pos
);
91 //This can't be NOOP, ACK nor NAK because those were checked above, nor is it special. Therefore
94 if(!overwrite_mode
|| cursor_pos
== codepoints
.size()) {
95 codepoints
.resize(codepoints
.size() + 1);
96 for(size_t i
= codepoints
.size() - 1; i
> cursor_pos
; i
--)
97 codepoints
[i
] = codepoints
[i
- 1];
99 codepoints
[cursor_pos
++] = k
& ~PRESSED_MASK
;
104 void commandline_model::tick() throw(std::bad_alloc
)
106 if(autorepeat_phase
== 0 || !enabled_flag
)
108 if(autorepeat_phase
== 1) {
109 autorepeat_counter
++;
110 if(autorepeat_counter
>= autorepeat_first
) {
111 key(autorepeating_key
);
112 autorepeat_phase
= 2;
113 autorepeat_counter
= 0;
116 if(autorepeat_phase
== 2) {
117 autorepeat_counter
++;
118 if(autorepeat_counter
>= autorepeat_subsequent
) {
119 key(autorepeating_key
);
120 autorepeat_counter
= 0;
125 size_t commandline_model::cursor() throw()
127 return enabled_flag
? cursor_pos
: 0;
130 bool commandline_model::enabled() throw()
135 bool commandline_model::overwriting() throw()
137 return overwrite_mode
;
140 void commandline_model::enable() throw()
145 autorepeat_phase
= 0;
146 autorepeat_counter
= 0;
149 overwrite_mode
= false;
150 history_itr
= history
.end();
153 std::string
commandline_model::read_command() throw(std::bad_alloc
)
155 std::ostringstream o
;
156 for(auto i
: codepoints
) {
157 char buf
[5] = {0, 0, 0, 0, 0};
161 buf
[0] = 0xC0 | (i
>> 6);
162 buf
[1] = 0x80 | (i
& 63);
163 } else if(i
< 0x10000) {
164 buf
[0] = 0xE0 | (i
>> 12);
165 buf
[1] = 0x80 | ((i
>> 6) & 63);
166 buf
[2] = 0x80 | (i
& 63);
167 } else if(i
< 0x10FFFF) {
168 buf
[0] = 0xF0 | (i
>> 18);
169 buf
[1] = 0x80 | ((i
>> 12) & 63);
170 buf
[2] = 0x80 | ((i
>> 6) & 63);
171 buf
[3] = 0x80 | (i
& 63);
178 void commandline_model::handle_cow()
180 if(history_itr
== history
.end())
181 //Latched to end of history.
183 codepoints
= *history_itr
;
184 history_itr
= history
.end();
187 void commandline_model::scroll_history_up()
189 std::list
<std::vector
<uint32_t>>::iterator tmp
;
192 void commandline_model::scroll_history_down()
194 std::list
<std::vector
<uint32_t>>::iterator tmp
;
197 void commandline_model::delete_codepoint(size_t idx
)
200 for(size_t i
= idx
; i
< codepoints
.size() - 1; i
++)
201 codepoints
[i
] = codepoints
[i
+ 1];
202 codepoints
.resize(codepoints
.size() - 1);
205 void commandline_model::paint(SDL_Surface
* surf
, uint32_t x
, uint32_t y
, uint32_t maxwidth
, uint32_t color
,
206 bool box
, uint32_t boxcolor
) throw()
212 draw_box(surf
, x
, y
, maxwidth
, 16, boxcolor
);
214 draw_string(surf
, read_command(), x
, y
, maxwidth
, color
, overwrite_mode
? 2 : 1, cursor_pos
);
216 draw_string(surf
, "", x
, y
, maxwidth
, color
, 0, 0);