1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
15 #pragma implementation
19 #ifndef USE_FL_SCROLLBAR
24 #include "support/lstrings.h"
25 #include "BufferView.h"
29 FL_OBJECT * figinset_canvas;
31 // need to make the c++ compiler fint the correct version of abs.
32 // This is at least true for g++.
38 XSync(fl_get_display(), 0);
42 // Just a bunch of C wrappers around static members of WorkArea
43 #ifndef USE_FL_SCROLLBAR
44 void C_WorkArea_up_cb(FL_OBJECT * ob, long buf)
46 WorkArea::up_cb(ob, buf);
49 void C_WorkArea_down_cb(FL_OBJECT * ob, long buf)
51 WorkArea::down_cb(ob, buf);
54 void C_WorkArea_scroll_cb(FL_OBJECT * ob, long buf)
56 WorkArea::scroll_cb(ob, buf);
59 int C_WorkArea_work_area_handler(FL_OBJECT * ob, int event,
63 return WorkArea::work_area_handler(ob, event,
70 WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height)
71 : owner(o), workareapixmap(0), painter_(*this)
73 fl_freeze_all_forms();
77 if (lyxerr.debugging())
78 lyxerr << "Creating work area: +"
79 << xpos << '+' << ypos << ' '
80 << width << 'x' << height << endl;
83 const int bw = int(abs(float(fl_get_border_width())));
85 // We really want to get rid of figinset_canvas.
86 ::figinset_canvas = figinset_canvas = obj =
87 fl_add_canvas(FL_NORMAL_CANVAS,
88 xpos + 1, ypos + 1, 1, 1, "");
89 fl_set_object_boxtype(obj, FL_NO_BOX);
90 fl_set_object_resize(obj, FL_RESIZE_ALL);
91 fl_set_object_gravity(obj, NorthWestGravity, NorthWestGravity);
94 if (lyxerr.debugging())
95 lyxerr << "\tbackground box: +"
96 << xpos << '+' << ypos << ' '
97 << width - 15 << 'x' << height << endl;
98 backgroundbox = obj = fl_add_box(FL_BORDER_BOX,
102 fl_set_object_resize(obj, FL_RESIZE_ALL);
103 fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
109 #ifdef USE_FL_SCROLLBAR
110 scrollbar = obj = fl_add_scrollbar(FL_VERT_SCROLLBAR,
112 ypos, 17, height, "");
113 fl_set_object_boxtype(obj, FL_UP_BOX);
114 //fl_set_object_color(obj, FL_MCOL, FL_BLUE);
115 fl_set_object_resize(obj, FL_RESIZE_ALL);
116 fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity);
118 fl_set_object_callback(obj, C_WorkArea_scroll_cb, 0);
120 // up - scrollbar button
121 fl_set_border_width(-1);
123 if (lyxerr.debugging())
124 lyxerr << "\tup button: +"
125 << xpos + width - 15 << '+' << ypos << ' '
126 << 15 << 'x' << 15 << endl;
127 button_up = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
131 fl_set_object_boxtype(obj,FL_UP_BOX);
132 fl_set_object_color(obj,FL_MCOL,FL_BLUE);
133 fl_set_object_resize(obj, FL_RESIZE_ALL);
134 fl_set_object_gravity(obj,NorthEastGravity, NorthEastGravity);
136 fl_set_object_callback(obj,C_WorkArea_up_cb, 0);
137 fl_set_pixmapbutton_data(obj, const_cast<char**>(up_xpm));
139 // Remove the blue feedback rectangle
140 fl_set_pixmapbutton_focus_outline(obj,0);
142 // the scrollbar slider
143 fl_set_border_width(-bw);
145 if (lyxerr.debugging())
146 lyxerr << "\tscrollbar slider: +"
147 << xpos + width - 15 << '+' << ypos + 15 << ' '
148 << 15 << 'x' << height - 30 << endl;
149 scrollbar = obj = fl_add_slider(FL_VERT_SLIDER,
152 15, height - 30, "");
153 fl_set_object_color(obj,FL_COL1,FL_MCOL);
154 fl_set_object_boxtype(obj, FL_UP_BOX);
155 fl_set_object_resize(obj, FL_RESIZE_ALL);
156 fl_set_object_gravity(obj, NorthEastGravity, SouthEastGravity);
158 fl_set_object_callback(obj, C_WorkArea_scroll_cb, 0);
159 fl_set_slider_precision(obj, 0);
161 // down - scrollbar button
162 fl_set_border_width(-1);
164 if (lyxerr.debugging())
165 lyxerr << "\tdown button: +"
166 << xpos + width - 15 << '+'
167 << ypos + height - 15 << ' '
168 << 15 << 'x' << 15 << endl;
169 button_down = obj = fl_add_pixmapbutton(FL_TOUCH_BUTTON,
173 fl_set_object_boxtype(obj,FL_UP_BOX);
174 fl_set_object_color(obj,FL_MCOL,FL_BLUE);
175 fl_set_object_resize(obj, FL_RESIZE_ALL);
176 fl_set_object_gravity(obj, SouthEastGravity, SouthEastGravity);
178 fl_set_object_callback(obj, C_WorkArea_down_cb, 0);
179 fl_set_pixmapbutton_data(obj, const_cast<char**>(down_xpm));
181 fl_set_border_width(-bw);
182 // Remove the blue feedback rectangle
183 fl_set_pixmapbutton_focus_outline(obj,0);
189 // Create the workarea pixmap
190 createPixmap(width - 15 - 2 * bw, height - 2 * bw);
193 //painter_.setDisplay(fl_display);
195 // We add this object as late as possible to avoit problems
197 if (lyxerr.debugging())
198 lyxerr << "\tfree object: +"
199 << xpos + bw << '+' << ypos + bw << ' '
200 << width - 15 - 2 * bw << 'x'
201 << height - 2 * bw << endl;
203 work_area = obj = fl_add_free(FL_INPUT_FREE,
204 xpos + bw, ypos + bw,
205 width - 15 - 2 * bw, // scrollbarwidth
207 C_WorkArea_work_area_handler);
208 obj->wantkey = FL_KEY_TAB;
209 obj->u_vdata = this; /* This is how we pass the WorkArea
210 to the work_area_handler. */
211 fl_set_object_boxtype(obj,FL_DOWN_BOX);
212 fl_set_object_resize(obj, FL_RESIZE_ALL);
213 fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
215 fl_unfreeze_all_forms();
219 WorkArea::~WorkArea()
222 XFreePixmap(fl_display, workareapixmap);
226 bool WorkArea::belowMouse() const
230 fl_get_mouse(&x, &y, &button);
231 FL_Coord ulx = work_area->form->x + work_area->x;
232 FL_Coord uly = work_area->form->y + work_area->y;
233 FL_Coord w = work_area->w;
234 FL_Coord h = work_area->h;
235 if (x > ulx && y > uly && x < ulx + h && y < uly + w)
240 //lyxerr << "Mouse: (" << x << ", " << y <<") button = " << button << endl;
241 //lyxerr << "Workarea: (" << work_area->x + work_area->form->x << ", " << work_area->y + work_area->form->y << ", " << work_area->w << ", " << work_area->h << ")" << endl;
242 //lyxerr << "Below mouse: " << work_area->belowmouse << endl;
243 //return work_area->belowmouse;
247 void WorkArea::resize(int xpos, int ypos, int width, int height)
249 fl_freeze_all_forms();
251 const int bw = int(abs(float(fl_get_border_width())));
254 fl_set_object_geometry(backgroundbox, xpos, ypos, width - 15, height);
259 #ifdef USE_FL_SCROLLBAR
260 fl_set_object_geometry(scrollbar, xpos + width - 15,
263 // up - scrollbar button
264 fl_set_object_geometry(button_up, xpos + width - 15,
267 // the scrollbar slider
268 fl_set_object_geometry(scrollbar, xpos + width - 15,
271 // down - scrollbar button
272 fl_set_object_geometry(button_down, xpos + width - 15,
276 // Create the workarea pixmap
277 createPixmap(width - 15 - 2 * bw, height - 2 * bw);
280 fl_set_object_geometry(work_area, xpos + bw, ypos + bw,
284 fl_unfreeze_all_forms();
289 void WorkArea::createPixmap(int width, int height)
291 static int cur_width = -1;
292 static int cur_height = -1;
294 if (cur_width == width && cur_height == height && workareapixmap)
301 XFreePixmap(fl_display, workareapixmap);
303 if (lyxerr.debugging())
304 lyxerr << "Creating pixmap ("
305 << width << 'x' << height << ")" << endl;
307 workareapixmap = XCreatePixmap(fl_display,
308 RootWindow(fl_display, 0),
311 fl_get_visual_depth());
312 if (lyxerr.debugging())
313 lyxerr << "\tpixmap=" << workareapixmap << endl;
317 void WorkArea::greyOut() const
319 fl_winset(FL_ObjWin(work_area));
320 fl_rectangle(1, work_area->x, work_area->y,
321 work_area->w, work_area->h, FL_GRAY63);
325 void WorkArea::setFocus() const
327 fl_set_focus_object(work_area->form, work_area);
331 void WorkArea::setScrollbar(double pos, double length_fraction) const
333 #ifdef USE_FL_SCROLLBAR
334 fl_set_scrollbar_value(scrollbar, pos);
335 fl_set_scrollbar_size(scrollbar, scrollbar->h * length_fraction);
337 fl_set_slider_value(scrollbar, pos);
338 fl_set_slider_size(scrollbar, scrollbar->h * length_fraction);
343 void WorkArea::setScrollbarBounds(double l1, double l2) const
345 #ifdef USE_FL_SCROLLBAR
346 fl_set_scrollbar_bounds(scrollbar, l1, l2);
348 fl_set_slider_bounds(scrollbar, l1, l2);
353 void WorkArea::setScrollbarIncrements(double inc) const
355 #ifdef USE_FL_SCROLLBAR
356 fl_set_scrollbar_increment(scrollbar, work_area->h - inc, inc);
358 fl_set_slider_increment(scrollbar, work_area->h - inc, inc);
362 #ifndef USE_FL_SCROLLBAR
363 void WorkArea::up_cb(FL_OBJECT * ob, long)
365 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
366 XEvent const * ev2 = fl_last_event();
367 static long time = 0;
368 ev2 = fl_last_event();
369 if (ev2->type == ButtonPress || ev2->type == ButtonRelease)
371 area->owner->upCB(time++, fl_get_button_numb(ob));
375 void WorkArea::down_cb(FL_OBJECT * ob, long)
377 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
378 XEvent const * ev2 = fl_last_event();
379 static long time = 0;
380 if (ev2->type == ButtonPress || ev2->type == ButtonRelease)
382 area->owner->downCB(time++, fl_get_button_numb(ob));
387 // Callback for scrollbar slider
388 void WorkArea::scroll_cb(FL_OBJECT * ob, long)
390 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
391 #ifdef USE_FL_SCROLLBAR
392 // If we really want the accellerating scroll we can do that
393 // from here. IMHO that is a waste of effort since we already
394 // have other ways to move fast around in the document. (Lgb)
395 area->owner->scrollCB(fl_get_scrollbar_value(ob));
397 area->owner->scrollCB(fl_get_slider_value(ob));
402 bool Lgb_bug_find_hack = false;
404 int WorkArea::work_area_handler(FL_OBJECT * ob, int event,
406 int /*key*/, void * xev)
408 static int x_old = -1;
409 static int y_old = -1;
410 static long scrollbar_value_old = -1;
412 XEvent * ev = static_cast<XEvent*>(xev);
413 WorkArea * area = static_cast<WorkArea*>(ob->u_vdata);
419 if (!area->work_area ||
420 !area->work_area->form->visible)
422 lyxerr.debug() << "Workarea event: DRAW" << endl;
423 area->createPixmap(area->workWidth(), area->height());
424 Lgb_bug_find_hack = true;
425 area->owner->workAreaExpose();
426 Lgb_bug_find_hack = false;
430 // Should really have used xbutton.state
431 lyxerr.debug() << "Workarea event: PUSH" << endl;
432 area->owner->workAreaButtonPress(ev->xbutton.x - ob->x,
433 ev->xbutton.y - ob->y,
438 // Should really have used xbutton.state
439 lyxerr.debug() << "Workarea event: RELEASE" << endl;
440 area->owner->workAreaButtonRelease(ev->xbutton.x - ob->x,
441 ev->xbutton.y - ob->y,
445 if (!ev || ! area->scrollbar) break;
446 if (ev->xmotion.x != x_old ||
447 ev->xmotion.y != y_old ||
448 #ifdef USE_FL_SCROLLBAR
449 fl_get_scrollbar_value(area->scrollbar) != scrollbar_value_old
451 fl_get_slider_value(area->scrollbar) != scrollbar_value_old
454 lyxerr.debug() << "Workarea event: MOUSE" << endl;
455 area->owner->workAreaMotionNotify(ev->xmotion.x - ob->x,
456 ev->xmotion.y - ob->y,
460 // Done by the raw callback:
461 // case FL_KEYBOARD: WorkAreaKeyPress(ob, 0,0,0,ev,0); break;
463 lyxerr.debug() << "Workarea event: FOCUS" << endl;
466 lyxerr.debug() << "Workarea event: UNFOCUS" << endl;
469 lyxerr.debug() << "Workarea event: ENTER" << endl;
470 area->owner->enterView();
473 lyxerr.debug() << "Workarea event: LEAVE" << endl;
474 area->owner->leaveView();
478 lyxerr.debug() << "Workarea event: DBLCLICK" << endl;
479 area->owner->doubleClick(ev->xbutton.x - ob->x,
480 ev->xbutton.y - ob->y,
485 lyxerr.debug() << "Workarea event: TRPLCLICK" << endl;
486 area->owner->tripleClick(ev->xbutton.x - ob->x,
487 ev->xbutton.y - ob->y,
492 if (ev->type == SelectionNotify) {
493 lyxerr.debug() << "Workarea event: SELECTION" << endl;
494 area->owner->workAreaSelectionNotify(area->work_area->form->window, ev);
496 lyxerr.debug() << "Workarea event: OTHER" << endl;