source: trunk/third/gtkhtml/src/htmlengine-edit-movement.c @ 16767

Revision 16767, 9.6 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16766, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/* This file is part of the GtkHTML library.
3   
4   Copyright (C) 2000 Helix Code, Inc.
5   
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Library General Public
8   License as published by the Free Software Foundation; either
9   version 2 of the License, or (at your option) any later version.
10   
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Library General Public License for more details.
15   
16   You should have received a copy of the GNU Library General Public License
17   along with this library; see the file COPYING.LIB.  If not, write to
18   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   Boston, MA 02111-1307, USA.
20*/
21
22#include <config.h>
23#include <ctype.h>
24
25#include "htmlengine-edit-cursor.h"
26#include "htmlengine-edit-selection-updater.h"
27#include "htmlengine-edit-movement.h"
28#include "htmlobject.h"
29
30
31void
32html_engine_update_selection_if_necessary (HTMLEngine *e)
33{
34        if (e->mark == NULL)
35                return;
36
37        html_engine_edit_selection_updater_schedule (e->selection_updater);
38}
39
40
41guint
42html_engine_move_cursor (HTMLEngine *e,
43                         HTMLEngineCursorMovement movement,
44                         guint count)
45{
46        gboolean (* movement_func) (HTMLCursor *, HTMLEngine *);
47        guint c;
48
49        g_return_val_if_fail (e != NULL, 0);
50        g_return_val_if_fail (HTML_IS_ENGINE (e), 0);
51
52        if (count == 0)
53                return 0;
54
55        switch (movement) {
56        case HTML_ENGINE_CURSOR_RIGHT:
57                movement_func = html_cursor_forward;
58                break;
59
60        case HTML_ENGINE_CURSOR_LEFT:
61                movement_func = html_cursor_backward;
62                break;
63
64        case HTML_ENGINE_CURSOR_UP:
65                movement_func = html_cursor_up;
66                break;
67
68        case HTML_ENGINE_CURSOR_DOWN:
69                movement_func = html_cursor_down;
70                break;
71
72        default:
73                g_warning ("Unsupported movement %d\n", (gint) movement);
74                return 0;
75        }
76
77        html_engine_hide_cursor (e);
78
79        for (c = 0; c < count; c++) {
80                if (! (* movement_func) (e->cursor, e))
81                        break;
82        }
83
84        html_engine_show_cursor (e);
85        html_engine_update_selection_if_necessary (e);
86
87        return c;
88}
89
90
91/**
92 * html_engine_jump_to_object:
93 * @e: An HTMLEngine object
94 * @object: Object to move the cursor to
95 * @offset: Cursor offset within @object
96 *
97 * Move the cursor to object @object, at the specified @offset.
98 * Notice that this does *not* modify the selection.
99 *
100 * Return value:
101 **/
102void
103html_engine_jump_to_object (HTMLEngine *e,
104                            HTMLObject *object,
105                            guint offset)
106{
107        g_return_if_fail (e != NULL);
108        g_return_if_fail (HTML_IS_ENGINE (e));
109        g_return_if_fail (object != NULL);
110
111        /* Delete the cursor in the original position.  */
112        html_engine_hide_cursor (e);
113
114        /* Jump to the specified position.  FIXME: Beep if it fails?  */
115        html_cursor_jump_to (e->cursor, e, object, offset);
116        html_cursor_normalize (e->cursor);
117
118        /* Draw the cursor in the new position.  */
119        html_engine_show_cursor (e);
120}
121
122/**
123 * html_engine_jump_at:
124 * @e: An HTMLEngine object
125 * @x: X coordinate
126 * @y: Y coordinate
127 *
128 * Make the cursor jump at the specified @x, @y pointer position.
129 **/
130void
131html_engine_jump_at (HTMLEngine *e,
132                     gint x, gint y)
133{
134        HTMLObject *obj;
135        guint offset;
136
137        g_return_if_fail (e != NULL);
138        g_return_if_fail (HTML_IS_ENGINE (e));
139
140        obj = html_engine_get_object_at (e, x, y, &offset, TRUE);
141        if (obj == NULL)
142                return;
143
144        /* printf ("jump to object type %d - %p\n", HTML_OBJECT_TYPE (obj), obj); */
145        html_engine_jump_to_object (e, obj, offset);
146        /* printf ("jumped to object type %d - %p\n", HTML_OBJECT_TYPE (e->cursor->object), e->cursor->object); */
147}
148
149
150void
151html_engine_beginning_of_document (HTMLEngine *engine)
152{
153        g_return_if_fail (engine != NULL);
154        g_return_if_fail (HTML_IS_ENGINE (engine));
155
156        html_engine_hide_cursor (engine);
157        html_cursor_beginning_of_document (engine->cursor, engine);
158        html_engine_show_cursor (engine);
159
160        html_engine_update_selection_if_necessary (engine);
161}
162
163void
164html_engine_end_of_document (HTMLEngine *engine)
165{
166        g_return_if_fail (engine != NULL);
167        g_return_if_fail (HTML_IS_ENGINE (engine));
168
169        html_engine_hide_cursor (engine);
170        html_cursor_end_of_document (engine->cursor, engine);
171        html_engine_show_cursor (engine);
172
173        html_engine_update_selection_if_necessary (engine);
174}
175
176
177gboolean
178html_engine_beginning_of_line (HTMLEngine *engine)
179{
180        gboolean retval;
181
182        g_return_val_if_fail (engine != NULL, FALSE);
183        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
184
185        html_engine_hide_cursor (engine);
186        retval = html_cursor_beginning_of_line (engine->cursor, engine);
187        html_engine_show_cursor (engine);
188
189        html_engine_update_selection_if_necessary (engine);
190
191        return retval;
192}
193
194gboolean
195html_engine_end_of_line (HTMLEngine *engine)
196{
197        gboolean retval;
198
199        g_return_val_if_fail (engine != NULL, FALSE);
200        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
201
202        html_engine_hide_cursor (engine);
203        retval = html_cursor_end_of_line (engine->cursor, engine);
204        html_engine_show_cursor (engine);
205
206        html_engine_update_selection_if_necessary (engine);
207
208        return retval;
209}
210
211gboolean
212html_engine_beginning_of_paragraph (HTMLEngine *engine)
213{
214        gboolean retval;
215
216        g_return_val_if_fail (engine != NULL, FALSE);
217        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
218
219        html_engine_hide_cursor (engine);
220        retval = html_cursor_beginning_of_paragraph (engine->cursor, engine);
221        html_engine_show_cursor (engine);
222
223        html_engine_update_selection_if_necessary (engine);
224
225        return retval;
226}
227
228gboolean
229html_engine_end_of_paragraph (HTMLEngine *engine)
230{
231        gboolean retval;
232
233        g_return_val_if_fail (engine != NULL, FALSE);
234        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
235
236        html_engine_hide_cursor (engine);
237        retval = html_cursor_end_of_paragraph (engine->cursor, engine);
238        html_engine_show_cursor (engine);
239
240        html_engine_update_selection_if_necessary (engine);
241
242        return retval;
243}
244
245
246gint
247html_engine_scroll_down (HTMLEngine *engine,
248                         gint amount)
249{
250        HTMLCursor *cursor;
251        HTMLCursor prev_cursor;
252        gint start_x, start_y;
253        gint x, y, new_y;
254
255        g_return_val_if_fail (engine != NULL, FALSE);
256        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
257
258        cursor = engine->cursor;
259
260        html_object_get_cursor_base (cursor->object, engine->painter, cursor->offset, &start_x, &start_y);
261
262        html_engine_hide_cursor (engine);
263
264        y = new_y = start_y;
265
266        while (1) {
267                html_cursor_copy (&prev_cursor, cursor);
268
269                new_y = html_cursor_down (cursor, engine);
270                html_object_get_cursor_base (cursor->object, engine->painter, cursor->offset, &x, &new_y);
271
272                /* FIXME html_cursor_down() is broken.  It should
273                   return FALSE and TRUE appropriately.  But I am lazy
274                   now.  */
275                if (new_y == y)
276                        break;
277
278                if (new_y < start_y)
279                        return 0;
280
281                if (new_y - start_y >= amount) {
282                        html_cursor_copy (cursor, &prev_cursor);
283                        break;
284                }
285
286                y = new_y;
287        }
288
289        html_engine_show_cursor (engine);
290
291        html_engine_update_selection_if_necessary (engine);
292
293        return new_y - start_y;
294}
295
296gint
297html_engine_scroll_up (HTMLEngine *engine,
298                       gint amount)
299{
300        HTMLCursor *cursor;
301        HTMLCursor prev_cursor;
302        gint start_x, start_y;
303        gint x, y, new_y;
304
305        g_return_val_if_fail (engine != NULL, FALSE);
306        g_return_val_if_fail (HTML_IS_ENGINE (engine), FALSE);
307
308        cursor = engine->cursor;
309
310        html_object_get_cursor_base (cursor->object, engine->painter, cursor->offset, &start_x, &start_y);
311
312        html_engine_hide_cursor (engine);
313
314        y = start_y;
315
316        while (1) {
317                html_cursor_copy (&prev_cursor, cursor);
318
319                html_cursor_up (cursor, engine);
320                html_object_get_cursor_base (cursor->object, engine->painter, cursor->offset, &x, &new_y);
321
322                /* FIXME html_cursor_down() is broken.  It should
323                   return FALSE and TRUE appropriately.  But I am lazy
324                   now.  */
325                if (new_y == y)
326                        break;
327
328                if (new_y > start_y) {
329                        html_engine_show_cursor (engine);
330                        return 0;
331                }
332
333                if (start_y - new_y >= amount) {
334                        html_cursor_copy (cursor, &prev_cursor);
335                        break;
336                }
337
338                y = new_y;
339        }
340
341        html_engine_show_cursor (engine);
342
343        html_engine_update_selection_if_necessary (engine);
344
345        return start_y - new_y;
346}
347
348
349gboolean
350html_engine_forward_word (HTMLEngine *e)
351{
352        gboolean rv = FALSE;
353
354        g_return_val_if_fail (e != NULL, FALSE);
355        g_return_val_if_fail (HTML_IS_ENGINE (e), FALSE);
356
357        html_engine_hide_cursor (e);
358        while (!g_unichar_isalnum (html_cursor_get_current_char (e->cursor)) && html_cursor_forward (e->cursor, e))
359                rv = TRUE;
360        while (g_unichar_isalnum (html_cursor_get_current_char (e->cursor)) && html_cursor_forward (e->cursor, e))
361                rv = TRUE;
362        html_engine_show_cursor (e);
363        html_engine_update_selection_if_necessary (e);
364
365        return rv;
366}
367
368gboolean
369html_engine_backward_word (HTMLEngine *e)
370{
371        gboolean rv = FALSE;
372
373        g_return_val_if_fail (e != NULL, FALSE);
374        g_return_val_if_fail (HTML_IS_ENGINE (e), FALSE);
375
376        html_engine_hide_cursor (e);
377        while (!g_unichar_isalnum (html_cursor_get_prev_char (e->cursor)) && html_cursor_backward (e->cursor, e))
378                rv = TRUE;
379        while (g_unichar_isalnum (html_cursor_get_prev_char (e->cursor)) && html_cursor_backward (e->cursor, e))
380                rv = TRUE;
381        html_engine_show_cursor (e);
382        html_engine_update_selection_if_necessary (e);
383
384        return rv;
385}
386
387void
388html_engine_edit_cursor_position_save (HTMLEngine *e)
389{
390        g_return_if_fail (e != NULL);
391        g_return_if_fail (HTML_IS_ENGINE (e));
392
393        e->cursor_position_stack = g_slist_prepend (e->cursor_position_stack, GINT_TO_POINTER (e->cursor->position));
394}
395
396void
397html_engine_edit_cursor_position_restore (HTMLEngine *e)
398{
399        g_return_if_fail (e != NULL);
400        g_return_if_fail (HTML_IS_ENGINE (e));
401
402        if (!e->cursor_position_stack)
403                return;
404
405        html_engine_hide_cursor (e);
406        html_cursor_jump_to_position (e->cursor, e, GPOINTER_TO_INT (e->cursor_position_stack->data));
407        e->cursor_position_stack = g_slist_remove_link (e->cursor_position_stack, e->cursor_position_stack);
408        html_engine_show_cursor (e);
409}
Note: See TracBrowser for help on using the repository browser.