00001 #ifndef CANVAS_IMPLEMENTATION_FILE
00002 #define CANVAS_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "argument_list.h"
00019 #include "box.h"
00020 #include "canvas.h"
00021 #include "drawable.h"
00022 #include "picture.h"
00023 #include "wp_implementation.h"
00024
00025 #include <basis/function.h>
00026 #include <basis/guards.h>
00027 #include <geometric/warper.cpp>
00028
00029 #ifdef __XWINDOWS__
00030 #include <Xm/DrawingA.h>
00031 #elif defined(MS_WINDOWS)
00032 #elif defined(OS_2)
00033 #endif
00034
00035 canvas::canvas(manager &root, const c_rectangle &position,
00036 const c_rectangle &initial_world, const color &foreground,
00037 const color &background, origin_vertex world_corner)
00038 : worker(root, position, create_canvas_handle(root, position.vertex_1()),
00039 foreground, background),
00040 c_rectangle_warper(position, initial_world, root.universe_corner(),
00041 world_corner),
00042 _details(root.self()),
00043 contents(c_point(0, 0))
00044 {
00045 FUNCDEF("constructor");
00046 #ifdef __XWINDOWS__
00047 dimensions(position);
00048 LOG("before creating XOR gc");
00049
00050 LOG("after creating XOR gc");
00051 XtAddCallback
00052 (self(), XmNresizeCallback, XtCallbackProc(resizer), XtPointer(this));
00053 XtAddCallback
00054 (self(), XmNexposeCallback, XtCallbackProc(exposer), XtPointer(this));
00055 XtAddCallback
00056 (self(), XmNinputCallback, XtCallbackProc(inputer), XtPointer(this));
00057 LOG("after adding callbacks");
00058 #elif defined(MS_WINDOWS)
00059 #elif defined(OS_2)
00060 #endif
00061 }
00062
00063 canvas::~canvas()
00064 {
00065 #ifdef __XWINDOWS__
00066 XtRemoveCallback
00067 (self(), XmNresizeCallback, XtCallbackProc(resizer), XtPointer(this));
00068 XtRemoveCallback
00069 (self(), XmNexposeCallback, XtCallbackProc(exposer), XtPointer(this));
00070 XtRemoveCallback
00071 (self(), XmNinputCallback, XtCallbackProc(inputer), XtPointer(this));
00072 #elif defined(MS_WINDOWS)
00073 #elif defined(OS_2)
00074 #endif
00075 }
00076
00077 c_rectangle canvas::world() const { return system_2(); }
00078
00079 c_rectangle canvas::universe() const { return system_1(); }
00080
00081 void canvas::redraw() { redraw_part(system_1()); }
00082
00083 int canvas::elements() { return contents.elements(); }
00084
00085 void canvas::add(drawable *to_add) { contents.add(to_add); }
00086
00087 void canvas::remove(drawable *to_add) { contents.remove(to_add); }
00088
00089 void canvas::update() { contents.update(); }
00090
00091 resources &canvas::details() { return _details; }
00092
00093 void canvas::redraw_part(const c_rectangle &to_redraw)
00094 { contents.draw_intersecting(to_redraw); }
00095
00096 c_point canvas::world_to_device(const c_point &in_world) const
00097 { return world_to_device(c_rectangle(in_world, in_world)).vertex_1(); }
00098
00099 c_point canvas::device_to_world(const c_point &in_device) const
00100 { return device_to_world(c_rectangle(in_device, in_device)).vertex_1(); }
00101
00102 window_handle canvas::create_canvas_handle(manager &root, const c_point &origin)
00103 {
00104 argument_list wargs;
00105 add_origin(wargs, root.universe_to_device(origin));
00106 return XtCreateManagedWidget
00107 ("canvas", xmDrawingAreaWidgetClass, root.self(),
00108 wargs.generate(), wargs.number());
00109 }
00110
00111 void canvas::exposer(window_handle, canvas *me, XmAnyCallbackStruct *parms)
00112 {
00113 FUNCDEF("exposer");
00114 XExposeEvent *event = (XExposeEvent *)parms->event;
00115 c_rectangle dev_to_redraw(event->x, event->y, event->x + event->width,
00116 event->y + event->height);
00117 c_rectangle to_redraw(me->device_to_world(dev_to_redraw));
00118 LOG(istring("<expose> on dev ") + dev_to_redraw.text_form() + " and world " + to_redraw.text_form() + ".");
00119 me->redraw_part(to_redraw);
00120 }
00121
00122 void canvas::inputer(window_handle, canvas *formal(me), XmAnyCallbackStruct *formal(parms))
00123 {
00124 FUNCDEF("inputer");
00125 LOG("<inputer>");
00126 }
00127
00128 void canvas::resizer(window_handle, canvas *me, XmAnyCallbackStruct *formal(parms))
00129 {
00130 FUNCDEF("resizer");
00131 LOG("<resizer>");
00132 argument_list wargs;
00133 int width, height, x, y;
00134 wargs.add(XtNx, XtArgVal(&x));
00135 wargs.add(XtNy, XtArgVal(&y));
00136 wargs.add(XtNwidth, XtArgVal(&width));
00137 wargs.add(XtNheight, XtArgVal(&height));
00138 XtGetValues(me->self(), wargs.generate(), wargs.number());
00139
00140 c_rectangle new_position
00141 (me->root().device_to_view(c_rectangle(x, y, x+width, y+height)));
00142 me->dimensions(new_position);
00143
00144 me->redraw();
00145 }
00146
00147 c_rectangle canvas::world_to_device(const c_rectangle &in_world) const
00148 {
00149 c_rectangle in_univ(to_system_1(in_world));
00150 c_rectangle in_dev(root().universe_to_device(in_univ));
00151 c_rectangle relative
00152 (in_dev - root().universe_to_device(dimensions()).vertex_1());
00153 return relative;
00154 }
00155
00156 c_rectangle canvas::device_to_world(const c_rectangle &in_device) const
00157 {
00158 c_rectangle relative
00159 (in_device + root().universe_to_device(dimensions()).vertex_1());
00160 c_rectangle in_univ(root().device_to_universe(relative));
00161 c_rectangle in_world(to_system_2(in_univ));
00162 return in_world;
00163 }
00164
00165
00166 #endif //CANVAS_IMPLEMENTATION_FILE
00167