forked from smcameron/space-nerds-in-space
-
Notifications
You must be signed in to change notification settings - Fork 0
/
snis_text_input.c
195 lines (171 loc) · 4.18 KB
/
snis_text_input.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "snis_font.h"
#include "snis_typeface.h"
#include "snis_graph.h"
#define DEFINE_SNIS_TEXT_INPUT_GLOBALS
#include "snis_text_input.h"
struct snis_text_input_box {
int x, y;
int color, font;
char *buffer;
int buflen;
snis_text_input_box_callback callback, return_function;
void *cookie;
int cursor_pos;
volatile int *timer;
int height, width;
int has_focus;
};
struct snis_text_input_box *snis_text_input_box_init(int x, int y,
int height, int width,
int color, int font,
char *buffer, int buflen,
volatile int *timer,
snis_text_input_box_callback callback,
void *cookie)
{
struct snis_text_input_box *t;
t = malloc(sizeof(*t));
t->x = x;
t->y = y;
t->color = color;
t->font = font;
t->buffer = buffer;
t->buflen = buflen - 1;
t->cursor_pos = strlen(t->buffer);
t->timer = timer;
t->callback = callback;
t->return_function = NULL;
t->cookie = cookie;
t->height = height;
t->width = width;
t->has_focus = 0;
return t;
}
void snis_text_input_box_draw(GtkWidget *w, GdkGC *gc, struct snis_text_input_box *t)
{
int cursor_on = t->has_focus && (*t->timer & 0x04);
sng_set_foreground(t->color);
sng_current_draw_rectangle(w->window, gc, 0, t->x, t->y, t->width, t->height);
if (t->has_focus)
sng_current_draw_rectangle(w->window, gc, 0, t->x - 1, t->y - 1,
t->width + 2, t->height + 2);
sng_abs_xy_draw_string_with_cursor(w, gc, t->buffer, t->font,
t->x + 4, t->y + font_lineheight[t->font],
t->cursor_pos, cursor_on);
}
void snis_text_input_box_set_focus(struct snis_text_input_box *t, int has_focus)
{
t->has_focus = has_focus;
}
int snis_text_input_box_button_press(struct snis_text_input_box *t, int x, int y)
{
int hit;
if (x < t->x || x > t->x + t->width ||
y < t->y || y > t->y + t->height)
hit = 0;
else
hit = 1;
/* put stuff for cursor positioning here. */
return hit;
}
static void do_backspace(struct snis_text_input_box *t)
{
int i;
int len = strlen(t->buffer);
if (t->cursor_pos == 0)
return;
if (t->cursor_pos == len && len > 0) {
t->buffer[len - 1] = '\0';
t->cursor_pos--;
return;
}
for (i = t->cursor_pos - 1; i < len; i++)
t->buffer[i] = t->buffer[i + 1];
t->cursor_pos--;
}
static void do_delete(struct snis_text_input_box *t)
{
int i;
int len = strlen(t->buffer);
if (t->cursor_pos == len) {
do_backspace(t);
return;
}
for (i = t->cursor_pos; i < len; i++)
t->buffer[i] = t->buffer[i + 1];
}
static void do_rightarrow(struct snis_text_input_box *t)
{
if (t->cursor_pos < t->buflen && t->cursor_pos < strlen(t->buffer))
t->cursor_pos++;
}
static void do_leftarrow(struct snis_text_input_box *t)
{
if (t->cursor_pos > 0)
t->cursor_pos--;
}
int snis_text_input_box_keypress(struct snis_text_input_box *t, GdkEventKey *event)
{
char c;
int currentlen;
if (event->type != GDK_KEY_PRESS)
return 0;
if ((event->keyval & ~0x7f) != 0) {
#include "snis_fixup_gnome_key_screwups.h"
switch (event->keyval) {
case GDK_KEY_BackSpace:
do_backspace(t);
break;
case GDK_KEY_Delete:
do_delete(t);
break;
case GDK_KEY_Right:
do_rightarrow(t);
break;
case GDK_KEY_Left:
do_leftarrow(t);
break;
case GDK_KEY_Return:
if (t->return_function)
t->return_function(t->cookie);
break;
default:
break;
}
return 0;
}
c = (event->keyval & 0x7f);
currentlen = strlen(t->buffer);
if (currentlen == t->cursor_pos) {
t->buffer[t->cursor_pos + 1] = '\0';
t->buffer[t->cursor_pos] = c;
if (t->cursor_pos < t->buflen - 1)
t->cursor_pos++;
} else {
if (currentlen < t->buflen - 2) {
memmove(&t->buffer[t->cursor_pos + 1], &t->buffer[t->cursor_pos],
currentlen - t->cursor_pos);
t->buffer[t->cursor_pos] = c;
t->cursor_pos++;
}
}
return 0;
}
int snis_text_input_box_keyrelease(struct snis_text_input_box *t, GdkEventKey *event)
{
return 0;
}
void snis_text_input_box_zero(struct snis_text_input_box *t)
{
t->cursor_pos = 0;
memset(t->buffer, 0, t->buflen);
}
void snis_text_input_box_set_return(struct snis_text_input_box *t,
snis_text_input_box_callback return_function)
{
t->return_function = return_function;
}