~ubuntu-branches/ubuntu/hardy/texmacs/hardy

« back to all changes in this revision

Viewing changes to src/Window/Widget/Input/input_widget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ralf Treinen
  • Date: 2004-04-19 20:34:00 UTC
  • Revision ID: james.westby@ubuntu.com-20040419203400-g4e34ih0315wcn8v
Tags: upstream-1.0.3-R2
ImportĀ upstreamĀ versionĀ 1.0.3-R2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
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
******************************************************************************/
 
12
 
 
13
#include "Widget/attribute_widget.hpp"
 
14
#include "font.hpp"
 
15
#include "Widget/layout.hpp"
 
16
 
 
17
/******************************************************************************
 
18
* Input widgets
 
19
******************************************************************************/
 
20
 
 
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
 
29
 
 
30
public:
 
31
  input_widget_rep (display dis, command call_back);
 
32
  operator tree ();
 
33
 
 
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);
 
39
 
 
40
  void handle_set_string (set_string_event ev);
 
41
  void handle_get_string (get_string_event ev);
 
42
};
 
43
 
 
44
/******************************************************************************
 
45
* Routines for input_widgets
 
46
******************************************************************************/
 
47
 
 
48
#define SHRINK 3
 
49
 
 
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; }
 
54
 
 
55
input_widget_rep::operator tree () {
 
56
  return tree (TUPLE, "input", s);
 
57
}
 
58
 
 
59
void
 
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);
 
64
}
 
65
 
 
66
void
 
67
input_widget_rep::handle_repaint (repaint_event ev) { (void) ev;
 
68
  text_extents ex;
 
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;
 
74
 
 
75
  SI text_width= right-left;
 
76
  SI width= w*SHRINK- 2*dw, height= h*SHRINK;
 
77
  SI marge= width>>2;
 
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;
 
82
  left    += scroll;
 
83
  current -= scroll;
 
84
 
 
85
  if (got_focus && hilit) {
 
86
    layout_dark (win, 0, 0, w, h);
 
87
    layout_lower (win, 0, 0, w, h);
 
88
  }
 
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);
 
93
  if (got_focus) {
 
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);
 
102
  }
 
103
  win->set_shrinking_factor (1);
 
104
}
 
105
 
 
106
void
 
107
input_widget_rep::handle_keypress (keypress_event ev) {
 
108
  string key= ev->key;
 
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= " ";
 
112
 
 
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));
 
124
  }
 
125
  else if (key == "backspace") {
 
126
    if (pos>0) {
 
127
      pos--;
 
128
      s= s (0, pos) * s (pos+1, N(s));
 
129
    }
 
130
  }
 
131
  else {
 
132
    if (N(key)!=1) return;
 
133
    int i (key[0]);
 
134
    if ((i>=0) && (i<32)) return;
 
135
    s= s (0, pos) * key * s(pos, N(s));
 
136
    pos += N(key);
 
137
  }
 
138
  this << emit_invalidate_all ();
 
139
}
 
140
 
 
141
void
 
142
input_widget_rep::handle_mouse (mouse_event ev) {
 
143
  string type= ev->type;
 
144
  SI     x   = ev->x;
 
145
  font   fn  = dis->default_font ();
 
146
 
 
147
  if (type == "press-left") {
 
148
    text_extents ex;
 
149
    SI old= 0;
 
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;
 
154
    }
 
155
    pos--;
 
156
    win->set_keyboard_focus (this);
 
157
    this << emit_invalidate_all ();
 
158
  }
 
159
 
 
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));
 
165
      pos += N(ins);
 
166
      this << emit_invalidate_all ();
 
167
    }
 
168
    else if (is_tuple (t, "texmacs", 3));
 
169
  }
 
170
}
 
171
 
 
172
void
 
173
input_widget_rep::handle_keyboard_focus (keyboard_focus_event ev) {
 
174
  got_focus= ev->flag;
 
175
  this << emit_invalidate_all ();
 
176
}
 
177
 
 
178
void
 
179
input_widget_rep::handle_set_string (set_string_event ev) {
 
180
  if (ev->which == "input") {
 
181
    s= copy (ev->s);
 
182
    pos= N(s);
 
183
    if (attached ()) this << emit_invalidate_all ();
 
184
  }
 
185
  else attribute_widget_rep::handle_set_string (ev);
 
186
}
 
187
 
 
188
void
 
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);
 
192
}
 
193
 
 
194
/******************************************************************************
 
195
* Interface
 
196
******************************************************************************/
 
197
 
 
198
event
 
199
set_input_string (string s) {
 
200
  return set_string ("input", s);
 
201
}
 
202
 
 
203
event
 
204
get_input_string (string& s) {
 
205
  return get_string ("input", s);
 
206
}
 
207
 
 
208
widget
 
209
input_text_widget (command call_back) {
 
210
  return new input_widget_rep (current_display (), call_back);
 
211
}