2 /**************************************************************************
3 ** (c) Copyright 1998, Andromeda Technology & Automation
4 ***************************************************************************
5 ** MODULE INFORMATION *
6 ***********************
7 ** FILE NAME : edit.cpp
8 ** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation
9 ** VERSION NUMBER : $Revision: 1.1 $
11 ** DESCRIPTION : Implementation of text editor classes
16 ***************************************************************************
17 ** ADMINISTRATIVE INFORMATION *
18 ********************************
19 ** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
20 ** CREATION DATE : Mar 13, 1998
21 ** LAST UPDATE : Jun 18, 1998
23 **************************************************************************/
25 /*****************************
27 Revision 1.1 2002-07-25 08:01:26 arjen
28 First checkin, AXE release 0.2
30 *****************************/
32 static const char *RCSID = "$Id: edit.cpp,v 1.1 2002-07-25 08:01:26 arjen Exp $";
35 #include <X11/keysym.h>
39 /*=========================================================================
51 ** LAST MODIFIED : May 21, 1998
52 **=========================================================================
55 int edit::EV_KeyPress(XKeyEvent ev)
61 Size(w, h); // The size of the window
64 key = XLookupKeysym(&ev, ev.state & 1);
66 // If text is selected, remove it first.
73 if (cursor_position > 0)
80 if (cursor_position < ~text)
87 if (cursor_position > 0)
90 text(cursor_position, 1) = "";
95 text(cursor_position, 1) = "";
104 if (key >= 0x20 && key <= 0x7e)
106 text(cursor_position, 0) = String((char)key);
112 if (cursor_position != 0)
113 x_cursor = fixed.TextWidth(text,cursor_position) + text_position;
115 x_cursor = text_position;
119 text_position += w/4;
121 else if ((unsigned)x_cursor > w)
123 text_position -= w / 4;
125 redraw(); // Recreates the cursor.
130 /*=========================================================================
131 ** NAME : EV_ButtonPress - Handle press of mouse button
136 ** DESCRIPTION : Buttonpress of the left mouse button puts the text
137 ** cursor at the mouse's position and sets the focus to
139 ** The X server will send a FocusIn event as a result of
146 ** LAST MODIFIED : May 22, 1998
147 **=========================================================================
151 int edit::EV_ButtonPress(XButtonEvent ev)
153 if (selected_until != -1)
163 if (focus_state != No_Focus)
165 // The cursor is visible; hide it from its old position
169 cursor_position = map_to_textposition(ev.x);
170 if (cursor_position > ~text)
171 cursor_position = ~text;
175 if (focus_state != No_Focus)
177 // If we already have the focus, show the cursor on its new
178 // position, else the FocusIn event will take care of this.
183 else if (ev.button == 2)
185 // Middle mouse button, paste the cut buffer
190 paste_text = XFetchBytes(stddpy, &nbytes);
193 printf(" Pasting %s\n", paste_text);
194 text(cursor_position, 0) = paste_text;
201 /*=========================================================================
202 ** NAME : EV_FocusIn - Handle FocusIn event
207 ** DESCRIPTION : Four event handling functions work together to track
208 ** the keyboard focus. The events involved are FocusIn,
209 ** FocusOut, EnterNotify and LeaveNotify
215 ** LAST MODIFIED : May 21, 1998
216 **=========================================================================
219 int edit::EV_FocusIn(XFocusChangeEvent ev)
221 if (focus_state == No_Focus)
223 focus_state = Explicit_Focus;
227 int edit::EV_FocusOut(XFocusChangeEvent ev)
229 focus_state = No_Focus;
233 int edit::EV_EnterNotify(XCrossingEvent ev)
235 if (ev.focus && focus_state == No_Focus)
237 focus_state = Implicit_Focus;
243 int edit::EV_LeaveNotify(XCrossingEvent ev)
245 if (ev.focus && focus_state == Implicit_Focus)
247 focus_state = No_Focus;
254 /*=========================================================================
255 ** NAME : EV_MotionNotify - handle motion event.
266 ** LAST MODIFIED : May 22, 1998
267 **=========================================================================
270 int edit::EV_MotionNotify(XMotionEvent ev)
272 selected_until = map_to_textposition(ev.x);
279 int edit::EV_ButtonRelease(XButtonEvent ev)
281 String selected_text;
282 int selection_length;
284 if (ev.button == 1 && selected_until != -1)
286 selected_until = map_to_textposition(ev.x);
288 if (selected_until >= cursor_position)
290 selection_length = selected_until - cursor_position;
291 selected_text = text(cursor_position, selection_length);
295 selection_length = cursor_position - selected_until;
296 selected_text = text(selected_until, selection_length);
300 printf("%d chars selected: %s\n", selection_length,(char *)selected_text);
302 XStoreBytes(stddpy, selected_text, selection_length);
306 printf("Nothing selected\n");
313 int edit::map_to_textposition(int x)
316 return (x - text_position) / 6;
319 int edit::map_to_pixelposition(int tp)
321 return fixed.TextWidth(text, tp) + text_position;
324 /*=========================================================================
325 ** NAME : toggle_cursor
336 ** LAST MODIFIED : Mar 17, 1998
337 **=========================================================================
340 void edit::toggle_cursor(void)
344 if (cursor_position != 0)
345 x_cursor = fixed.TextWidth(text,cursor_position) + text_position;
349 DrawLine(edit_cursor_gc, x_cursor, 1, x_cursor, 13);
352 /*=========================================================================
353 ** NAME : redraw - Draw the edit object (again)
358 ** DESCRIPTION : Clear the window and redraw the edited text.
359 ** If part of the text is selected, draw this part
360 ** in a different color.
361 ** Draw a text cursor if we have the focus.
367 ** LAST MODIFIED : May 22, 1998
368 **=========================================================================
371 void edit::redraw(void)
373 int selection_length;
374 String selected_text;
377 /* Redraw the entire text */
380 DrawString(text_normal_gc, text_position, 12, text);
382 /* If part of the text is selected, highlight this part */
384 if (selected_until != -1)
386 if (selected_until >= cursor_position)
388 selection_length = selected_until - cursor_position;
389 x_start = map_to_pixelposition(cursor_position);
390 x_end = map_to_pixelposition(selected_until);
391 selected_text = text(cursor_position, selection_length);
395 selection_length = cursor_position - selected_until;
396 x_start = map_to_pixelposition(selected_until);
397 x_end = map_to_pixelposition(cursor_position);
398 selected_text = text(selected_until, selection_length);
401 XFillRectangle(stddpy, ID(), inside_3D_gc, x_start, 1, x_end-x_start, 14);
402 DrawString(text_normal_gc, x_start, 12, selected_text);
405 /* If we have the focus, draw the text cursor */
407 if (focus_state != No_Focus)
413 void edit::enter(void)
415 ParentMessage(EDIT_ENTERED);
418 void edit::focuslost(void)
420 ParentMessage(EDIT_FOCUSLOST);
424 /*=========================================================================
425 ** NAME : DeleteSelection - Delete any selected text
428 ** RETURN VALUE : The number of characters deleted.
431 ** Make sure the cursor stays within the text. If the
432 ** selection is 'right-to-left', i.e. from selected_until
433 ** to cursor_position, the cursor is moved to the beginning
434 ** of the selected text.
440 ** LAST MODIFIED : Jun 18, 1998
441 **=========================================================================
444 int edit::DeleteSelection(void)
446 int selection_length;
448 selection_length = 0;
450 if (selected_until != -1)
453 if (selected_until >= cursor_position)
455 selection_length = selected_until - cursor_position;
456 text(cursor_position, selection_length) = "";
460 selection_length = cursor_position - selected_until;
461 text(selected_until, selection_length) = "";
462 cursor_position = selected_until;
465 selected_until = -1; // Nothing selected
467 return selection_length;
470 /*=========================================================================
471 ** NAME : ClearSelection
482 ** LAST MODIFIED : Jun 18, 1998
483 **=========================================================================
486 int edit::ClearSelection(void)
488 if (selected_until != -1)
497 /*=========================================================================
509 ** LAST MODIFIED : Jun 18, 1998
510 **=========================================================================
513 void edit::SelectAll(void)
516 selected_until = ~text - 1;