2
/******************************************************************************
3
* MODULE : input_widget.cpp
4
* DESCRIPTION: Input of data by the user in textual form
5
* COPYRIGHT : (C) 1999 Joris van der Hoeven
6
*******************************************************************************
7
* This software falls under the GNU general public license and comes WITHOUT
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11
******************************************************************************/
13
#include "Widget/attribute_widget.hpp"
15
#include "Widget/layout.hpp"
17
/******************************************************************************
19
******************************************************************************/
21
class input_widget_rep: public attribute_widget_rep {
22
string s; // the string being entered
23
command call_back; // routine called on <return> or <escape>
24
SI dw, dh; // border width and height
25
int pos; // cursor position
26
SI scroll; // how much scrolled to the left
27
bool got_focus; // got keyboard focus
28
bool hilit; // hilit on keyboard focus
31
input_widget_rep (display dis, command call_back);
34
void handle_get_size (get_size_event ev);
35
void handle_repaint (repaint_event ev);
36
void handle_keypress (keypress_event ev);
37
void handle_mouse (mouse_event ev);
38
void handle_keyboard_focus (keyboard_focus_event ev);
40
void handle_set_string (set_string_event ev);
41
void handle_get_string (get_string_event ev);
44
/******************************************************************************
45
* Routines for input_widgets
46
******************************************************************************/
50
input_widget_rep::input_widget_rep (display dis, command call_back2):
51
attribute_widget_rep (dis, south_west), s (""), call_back (call_back2),
52
dw (2*PIXEL), dh (2*PIXEL), pos (N(s)), scroll (0),
53
got_focus (false), hilit (false) { dw*=SHRINK; dh*= SHRINK; }
55
input_widget_rep::operator tree () {
56
return tree (TUPLE, "input", s);
60
input_widget_rep::handle_get_size (get_size_event ev) {
61
font fn= dis->default_font ();
62
ev->h = (fn->y2- fn->y1+ 2*dh+ (SHRINK-1))/SHRINK;
63
abs_round (ev->w, ev->h);
67
input_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
69
font fn= dis->default_font ();
70
fn->var_get_extents (s, ex);
71
SI left= ex->x1, bottom= fn->y1, right= ex->x2;
72
fn->var_get_extents (s (0, pos), ex);
73
SI current= ex->x2- ex->x1;
75
SI text_width= right-left;
76
SI width= w*SHRINK- 2*dw, height= h*SHRINK;
78
if ((current-scroll) > (width-marge)) scroll= current+ marge- width;
79
if ((current-scroll) < marge) scroll= current- marge;
80
if (scroll > (text_width- width)) scroll= text_width- width;
81
if (scroll < 0) scroll= 0;
85
if (got_focus && hilit) {
86
layout_dark (win, 0, 0, w, h);
87
layout_lower (win, 0, 0, w, h);
89
else layout_default (win, 0, 0, w, h);
90
win->set_color (dis->black);
91
win->set_shrinking_factor (SHRINK);
92
fn ->var_draw (win, s, dw- left, dh- bottom);
94
SI pixel= SHRINK*PIXEL;
95
win->set_color (dis->red);
96
win->line (current+ dw, dh,
97
current+ dw, height- pixel- dh);
98
win->line (current+ dw- pixel, dh,
99
current+ dw+ pixel, dh);
100
win->line (current+ dw- pixel, height- pixel- dh,
101
current+ dw+ pixel, height- pixel- dh);
103
win->set_shrinking_factor (1);
107
input_widget_rep::handle_keypress (keypress_event ev) {
109
while ((N(key) >= 5) && (key(0,3) == "Mod") && (key[4] == '-') &&
110
(key[3] >= '1') && (key[3] <= '5')) key= key (5, N(key));
111
if (key == "space") key= " ";
113
if (key == "return") { s= "\"" * s * "\""; call_back (); }
114
else if ((key == "escape") || (key == "C-c") ||
115
(key == "C-g")) { s= "cancel"; call_back (); }
116
else if ((key == "left") || (key == "C-b")) { if (pos>0) pos--; }
117
else if ((key == "right") || (key == "C-f")) { if (pos<N(s)) pos++; }
118
else if ((key == "home") || (key == "C-a")) pos=0;
119
else if ((key == "end") || (key == "C-e")) pos=N(s);
120
else if (key == "C-k") s= s (0, pos);
121
else if ((key == "C-d") || (key == "delete")) {
122
if ((pos<N(s)) && (N(s)>0))
123
s= s (0, pos) * s (pos+1, N(s));
125
else if (key == "backspace") {
128
s= s (0, pos) * s (pos+1, N(s));
132
if (N(key)!=1) return;
134
if ((i>=0) && (i<32)) return;
135
s= s (0, pos) * key * s(pos, N(s));
138
this << emit_invalidate_all ();
142
input_widget_rep::handle_mouse (mouse_event ev) {
143
string type= ev->type;
145
font fn = dis->default_font ();
147
if (type == "press-left") {
150
for (pos=1; pos<=N(s); pos++) {
151
fn->var_get_extents (s (0, pos), ex);
152
if (((old+ ex->x2+ dw- ex->x1) >> 1) > (x*SHRINK+ scroll)) break;
153
old= ex->x2+ dw- ex->x1;
156
win->set_keyboard_focus (this);
157
this << emit_invalidate_all ();
160
if (type == "press-middle") {
161
tree t= copy (dis->get_selection (widget (this), "primary"));
162
if (is_tuple (t, "extern", 1)) {
163
string ins= as_string (t[1]);
164
s= s (0, pos) * ins * s(pos, N(s));
166
this << emit_invalidate_all ();
168
else if (is_tuple (t, "texmacs", 3));
173
input_widget_rep::handle_keyboard_focus (keyboard_focus_event ev) {
175
this << emit_invalidate_all ();
179
input_widget_rep::handle_set_string (set_string_event ev) {
180
if (ev->which == "input") {
183
if (attached ()) this << emit_invalidate_all ();
185
else attribute_widget_rep::handle_set_string (ev);
189
input_widget_rep::handle_get_string (get_string_event ev) {
190
if (ev->which == "input") ev->s= s;
191
else attribute_widget_rep::handle_get_string (ev);
194
/******************************************************************************
196
******************************************************************************/
199
set_input_string (string s) {
200
return set_string ("input", s);
204
get_input_string (string& s) {
205
return get_string ("input", s);
209
input_text_widget (command call_back) {
210
return new input_widget_rep (current_display (), call_back);