home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: wx_canvs.cc
- * Purpose: wxCanvas implementation
- *
- * wxWindows 1.40
- * Copyright (c) 1993 Artificial Intelligence Applications Institute,
- * The University of Edinburgh
- *
- * Author: Julian Smart
- * Date: 18-4-93
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice, author statement and this permission
- * notice appear in all copies of this software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
- * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
- * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
- * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <windows.h>
- #include <math.h>
- #include "common.h"
- #include "wx_frame.h"
- #include "wx_dc.h"
- #include "wx_canvs.h"
- #include "wx_event.h"
- #include "wx_utils.h"
- #include "wx_privt.h"
-
- #ifdef wx_motif
- #include "wx_main.h"
-
- #include <Xm/DrawingA.h>
- #include <Xm/ScrolledW.h>
- #include <Xm/ScrollBar.h>
-
- #define SCROLL_MARGIN 4
- void wxCanvasRepaintProc(Widget, XtPointer, XmDrawingAreaCallbackStruct *cbs);
- void wxCanvasKeyEvent(Widget, XKeyEvent *);
- void wxCanvasInputEvent(Widget, XButtonEvent *event);
- #endif
-
- #ifdef wx_xview
- #include <xview/screen.h>
- extern Xv_Server xview_server;
- void wxCanvasRepaintProc(Canvas canvas, Xv_Window paint_window,
- Display *dpy, Window xwin, Xv_xrectlist *xrects);
- void wxCanvasResizeProc(Canvas canvas, int width, int height);
- void wxCanvasEventProc(Xv_Window window, Event *event, Notify_arg arg);
-
- #endif
-
- wxCanvas::wxCanvas(wxFrame *frame, int x, int y, int width, int height, int style)
- {
- is_retained = ((style & wxRETAINED) == wxRETAINED);
-
- #ifdef wx_motif
- hScroll = FALSE;
- vScroll = FALSE;
- hScrollBar = NULL;
- vScrollBar = NULL;
- allowRepainting = TRUE;
- hScrollingEnabled = TRUE;
- vScrollingEnabled = TRUE;
- // Can't rely on Xt to return these values, so must store.
- canvasWidth = 0;
- canvasHeight = 0;
- canvasX = 0;
- canvasY = 0;
- backingPixmap = 0;
- pixmapWidth = 0;
- pixmapHeight = 0;
- hExtent = 0;
- vExtent = 0;
- button1Pressed = FALSE;
- button2Pressed = FALSE;
- button3Pressed = FALSE;
- pixmapOffsetX = 0;
- pixmapOffsetY = 0;
-
- // New translations for getting mouse motion feedback - duh!
- String translations =
- "<Btn1Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
- <Btn2Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
- <Btn3Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
- <Btn1Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
- <Btn2Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
- <Btn3Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
- <Btn1Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
- <Btn2Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
- <Btn3Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
- <Key>: wxCanvasKeyEvent()";
-
- XtActionsRec actions[2];
- actions[0].string = "wxCanvasInputEvent";
- actions[0].proc = (XtActionProc)wxCanvasInputEvent;
- actions[1].string = "wxCanvasKeyEvent";
- actions[1].proc = (XtActionProc)wxCanvasKeyEvent;
- XtAppAddActions(wxTheApp->appContext, &actions, 2);
-
- Widget parentWidget = frame->workArea;
- scrolledWindow = XtVaCreateManagedWidget("scrolled_window",
- xmScrolledWindowWidgetClass, parentWidget,
- XmNscrollingPolicy, XmAPPLICATION_DEFINED,
- NULL);
-
- Widget drawingArea = XtVaCreateManagedWidget("drawing_area",
- xmDrawingAreaWidgetClass, scrolledWindow,
- XmNunitType, XmPIXELS,
- XmNresizePolicy, XmRESIZE_ANY,
- XmNtranslations, XtParseTranslationTable(translations),
- NULL);
-
- handle = (char *)drawingArea;
-
- wxWidgetHashTable->Put((long)drawingArea, this);
- wxWidgetHashTable->Put((long)scrolledWindow, this);
-
- XtOverrideTranslations(drawingArea,
- XtParseTranslationTable("<Configure>: resize()"));
-
- XtAddCallback(drawingArea, XmNexposeCallback, wxCanvasRepaintProc, this);
-
- if (x > -1)
- {
- canvasX = x;
- XtVaSetValues(scrolledWindow,
- XmNleftAttachment, XmATTACH_SELF,
- XmNx, x,
- NULL);
- }
- if (y > -1)
- {
- canvasY = y;
- XtVaSetValues(scrolledWindow,
- XmNtopAttachment, XmATTACH_SELF,
- XmNy, y,
- NULL);
- }
- if (width > -1)
- {
- canvasWidth = width;
- XtVaSetValues(scrolledWindow, XmNwidth, width, NULL);
- if (!hScroll)
- XtVaSetValues(drawingArea, XmNwidth, width - SCROLL_MARGIN, NULL);
- }
- if (height > -1)
- {
- canvasHeight = height;
- XtVaSetValues(scrolledWindow, XmNheight, height, NULL);
- if (!vScroll)
- XtVaSetValues(drawingArea, XmNheight, height - SCROLL_MARGIN, NULL);
- }
-
- XtRealizeWidget(scrolledWindow);
- XtRealizeWidget(drawingArea);
-
- if (!hScroll)
- {
- Widget hWidget;
- XtVaGetValues(scrolledWindow, XmNhorizontalScrollBar, &hWidget, NULL);
- }
- if (!vScroll)
- {
- Widget vWidget;
- XtVaGetValues(scrolledWindow, XmNverticalScrollBar, &vWidget, NULL);
- }
-
- display = XtDisplay(scrolledWindow);
- xwindow = XtWindow(drawingArea);
- // SetSize(x, y, width, height);
- #endif
- #ifdef wx_xview
- repaint_countdown = 0;
-
- // Since I have found that it's difficult to keep up with
- // all XView drag events, this counts down to zero before sending
- // an OnEvent message. If you want more sensitivity, reduce this value
- // and recompile wxWindows.
- DRAG_MAX = 0;
-
- int real_y = frame->y_offset;
- if (y > -1)
- real_y = y + frame->y_offset; // Allow for possible menu bar
-
- Frame x_frame = (Frame)frame->handle;
- Canvas x_canvas = (Canvas)xv_create(x_frame, CANVAS,
- // CANVAS_REPAINT_PROC, wxCanvasRepaintProc,
- // CANVAS_RESIZE_PROC, wxCanvasResizeProc,
- CANVAS_X_PAINT_WINDOW, TRUE,
- WIN_CLIENT_DATA, (char *)this,
- CANVAS_RETAINED, is_retained,
- XV_SHOW, FALSE,
- NULL);
-
- xv_set(canvas_paint_window(x_canvas), WIN_EVENT_PROC, wxCanvasEventProc,
- WIN_CONSUME_EVENTS,
- WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
- LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
- NULL,
- WIN_CLIENT_DATA, (char *)this, NULL);
- handle = (char *)x_canvas;
-
-
- xv_set(x_canvas, XV_SHOW, TRUE, NULL);
-
- horiz_scroll = NULL;
- vert_scroll = NULL;
-
- Xv_Screen screen = xv_get(xview_server, SERVER_NTH_SCREEN, 0);
- Xv_Window root_window = xv_get(screen, XV_ROOT);
- xwindow = (Window)xv_get(canvas_paint_window(x_canvas), XV_XID);
-
- display = (Display *)xv_get(root_window, XV_DISPLAY);
-
- drag_count = DRAG_MAX;
- xrects = NULL;
- #endif
- #ifdef wx_msw
- wxWinType = wxTYPE_XWND;
- is_retained = FALSE;
- clipping = FALSE;
- wxWnd *cparent = NULL;
- if (frame)
- cparent = (wxWnd *)frame->handle;
-
- DWORD msflags = 0;
- if (style & wxBORDER)
- msflags |= WS_BORDER;
- msflags |= WS_CHILD | WS_VISIBLE;
-
- wxCanvasWnd *wnd = new wxCanvasWnd(cparent, this, x, y, width, height, msflags);
- wnd->background_brush = GetStockObject(WHITE_BRUSH);
- handle = (char *)wnd;
- #endif
-
- if (frame) frame->AddChild(this);
- window_parent = frame;
-
- horiz_units = 0;
- vert_units = 0;
-
- wx_dc = new wxDC(this);
- context = wx_dc;
-
- #ifdef wx_xview
- xv_set(x_canvas,
- CANVAS_REPAINT_PROC, wxCanvasRepaintProc,
- CANVAS_RESIZE_PROC, wxCanvasResizeProc, NULL);
- if (x > -1)
- xv_set(x_canvas, XV_X, x, NULL);
- if (y > -1)
- xv_set(x_canvas, XV_Y, real_y, NULL);
- if (width > -1)
- xv_set(x_canvas, XV_WIDTH, width, NULL);
- if (height > -1)
- xv_set(x_canvas, XV_HEIGHT, height, NULL);
-
- #endif
- }
-
- wxCanvas::~wxCanvas(void)
- {
- #ifdef wx_motif
- if (backingPixmap)
- XFreePixmap(XtDisplay((Widget)handle), backingPixmap);
- #endif
- #ifdef wx_xview
- Canvas x_canvas = (Canvas)handle;
- Xv_window pw = canvas_paint_window(x_canvas);
- (void)xv_set(pw, WIN_CLIENT_DATA, NULL, NULL);
- xv_set(x_canvas,
- CANVAS_X_PAINT_WINDOW, FALSE, NULL);
-
- if (horiz_scroll)
- xv_destroy_safe((Xv_opaque)horiz_scroll);
- if (vert_scroll)
- xv_destroy_safe((Xv_opaque)vert_scroll);
- if (wx_dc)
- delete wx_dc;
- #endif
- }
-
- #ifdef wx_motif
- void wxCanvas::PreResize(void)
- {
- // cout << "Canvas PreResize\n";
- // OnPaint();
- }
- #endif
-
- #ifdef wx_msw
- void wxCanvas::PreDelete(HDC dc)
- {
- wx_dc->SelectOldObjects(dc);
- delete wx_dc;
- }
- #endif
-
- void wxCanvas::SetClippingRegion(float cx, float cy, float cw, float ch)
- {
- wx_dc->SetClippingRegion(cx, cy, cw, ch);
- }
-
- void wxCanvas::DestroyClippingRegion(void)
- {
- wx_dc->DestroyClippingRegion();
- }
-
- wxDC *wxCanvas::GetDC(void)
- {
- return context;
- }
-
- void wxCanvas::SetClientSize(int w, int h)
- {
- #ifdef wx_motif
- Widget drawingArea = (Widget)handle;
-
- if (w > -1)
- {
- canvasWidth = w;
- XtVaSetValues(scrolledWindow, XmNwidth, w, NULL);
- if (!hScroll)
- XtVaSetValues(drawingArea, XmNwidth, w - SCROLL_MARGIN, NULL);
- }
- if (h > -1)
- {
- canvasHeight = h;
- XtVaSetValues(scrolledWindow, XmNheight, h, NULL);
- if (!vScroll)
- XtVaSetValues(drawingArea, XmNheight, h - SCROLL_MARGIN, NULL);
- }
- allowRepainting = FALSE;
-
- XSync(XtDisplay(drawingArea), FALSE);
- XEvent event;
- while (XtAppPending(wxTheApp->appContext))
- {
- XFlush(XtDisplay(drawingArea));
- XtAppNextEvent(wxTheApp->appContext, &event);
- XtDispatchEvent(&event);
- }
- allowRepainting = TRUE;
- Refresh();
- OnSize(w, h);
- #else
- wxWindow::SetClientSize(w, h);
- #endif
- }
-
- void wxCanvas::GetClientSize(int *w, int *h)
- {
- #ifdef wx_motif
- // Doesn't return the right value!
- // XtVaGetValues(scrolledWindow, XmNwidth, w, XmNheight, h, NULL);
- *w = canvasWidth;
- *h = canvasHeight;
- #else
- wxWindow::GetClientSize(w, h);
- #endif
- }
-
- void wxCanvas::SetSize(int x, int y, int w, int h)
- {
- #ifdef wx_motif
- Widget drawingArea = (Widget)handle;
- if (x > -1)
- {
- canvasX = x;
- XtVaSetValues(scrolledWindow,
- XmNleftAttachment, XmATTACH_SELF,
- XmNx, x, NULL);
- }
-
- if (y > -1)
- {
- canvasY = y;
- XtVaSetValues(scrolledWindow,
- XmNtopAttachment, XmATTACH_SELF,
- XmNy, y, NULL);
- }
-
- if (w > -1)
- {
- canvasWidth = w;
- XtVaSetValues(scrolledWindow, XmNwidth, w, NULL);
- if (!hScroll)
- XtVaSetValues(drawingArea, XmNwidth, w - SCROLL_MARGIN, NULL);
- }
- if (h > -1)
- {
- canvasHeight = h;
- XtVaSetValues(scrolledWindow, XmNheight, h, NULL);
- if (!vScroll)
- XtVaSetValues(drawingArea, XmNheight, h - SCROLL_MARGIN, NULL);
- }
-
- allowRepainting = FALSE;
-
- XSync(XtDisplay(drawingArea), FALSE);
- XEvent event;
- while (XtAppPending(wxTheApp->appContext))
- {
- XFlush(XtDisplay(drawingArea));
- XtAppNextEvent(wxTheApp->appContext, &event);
- XtDispatchEvent(&event);
- }
- allowRepainting = TRUE;
- Refresh();
- #endif
- #ifdef wx_xview
- int real_y = y;
-
- if (window_parent)
- real_y += ((wxFrame *)window_parent)->y_offset; // Allow for possible menu bar
-
- Xv_opaque object = (Xv_opaque)handle;
- (void)xv_set(object, XV_X, x, XV_Y, real_y, XV_WIDTH, w, XV_HEIGHT, h, NULL);
- #endif
- #ifdef wx_msw
- int currentX, currentY;
- GetPosition(¤tX, ¤tY);
- if (x == -1)
- x = currentX;
- if (y == -1)
- y = currentY;
-
- wxWnd *wnd = (wxWnd *)handle;
- if (wnd)
- MoveWindow(wnd->handle, x, y, w, h, TRUE);
- #endif
- OnSize(w, h);
- }
-
- void wxCanvas::GetSize(int *w, int *h)
- {
- #ifdef wx_motif
- // XtVaGetValues(scrolledWindow, XmNwidth, w, XmNheight, h, NULL);
- *w = canvasWidth;
- *h = canvasHeight;
- #else
- wxWindow::GetSize(w, h);
- #endif
- }
-
- void wxCanvas::GetPosition(int *x, int *y)
- {
- #ifdef wx_motif
- // XtVaGetValues(scrolledWindow, XmNx, x, XmNy, y, NULL);
- *x = canvasX;
- *y = canvasY;
- #else
- wxWindow::GetPosition(x, y);
- #endif
- }
-
- #ifdef wx_motif
- /* Calls OnPaint or uses retained pixmap,
- * as necessary
- */
- void wxCanvas::Refresh(void)
- {
- Dimension canvasWidth2, canvasHeight2;
- XtVaGetValues(scrolledWindow, XmNwidth, &canvasWidth2, XmNheight, &canvasHeight2, NULL);
- int canvasWidth1 = max(canvasWidth, canvasWidth2);
- int canvasHeight1 = max(canvasHeight, canvasHeight2);
-
- if (hScroll)
- {
- XtVaSetValues(hScrollBar, XmNsliderSize,
- (int)(max(min(canvasWidth1/horiz_units, hExtent/horiz_units), 1)), NULL);
- }
- if (vScroll)
- {
- XtVaSetValues(vScrollBar, XmNsliderSize,
- (int)(max(min(canvasHeight1/vert_units, vExtent/vert_units), 1)), NULL);
- }
- int x, y;
- ViewStart(&x, &y);
- if (is_retained && backingPixmap)
- {
- Widget drawingArea = (Widget)handle;
- XCopyArea(XtDisplay(drawingArea), backingPixmap, XtWindow(drawingArea), GetDC()->gc,
- pixmapOffsetX, pixmapOffsetY,
- pixmapWidth, pixmapHeight,
- 0, 0);
- }
- else
- {
- OnPaint();
- }
- }
-
- void wxScrollCallback(Widget scrollbar, int orientation, XmScrollBarCallbackStruct *cbs)
- {
- Widget scrolledWindow = XtParent(scrollbar);
- wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)scrolledWindow);
- if (canvas)
- {
- if (orientation == XmHORIZONTAL)
- {
- if (canvas->hScrollingEnabled && !canvas->is_retained)
- canvas->Clear();
-
- if (canvas->GetDC())
- canvas->GetDC()->device_origin_x = -(cbs->value * canvas->horiz_units);
- if (canvas->is_retained)
- canvas->pixmapOffsetX = (cbs->value * canvas->horiz_units);
- }
- else
- {
- if (canvas->vScrollingEnabled && !canvas->is_retained)
- canvas->Clear();
-
- if (canvas->GetDC())
- canvas->GetDC()->device_origin_y = -(cbs->value * canvas->vert_units);
- if (canvas->is_retained)
- canvas->pixmapOffsetY = (cbs->value * canvas->vert_units);
- }
- canvas->Refresh();
- }
- }
- #endif
-
- /*
- * horizontal/vertical: number of pixels per unit (e.g. pixels per text line)
- * x/y_length: : no. units per scrollbar
- * x/y_page: : no. units per page scrolled
- */
- void wxCanvas::SetScrollbars(int horizontal, int vertical,
- int x_length, int y_length,
- int x_page, int y_page)
- {
- horiz_units = horizontal;
- vert_units = vertical;
-
- #ifdef wx_motif
- Bool scrollingInitialized = (hScrollBar || vScrollBar);
- Dimension canvasWidth2, canvasHeight2;
- XtVaGetValues(scrolledWindow, XmNwidth, &canvasWidth2, XmNheight, &canvasHeight2, NULL);
- int canvasWidth1 = max(canvasWidth, canvasWidth2);
- int canvasHeight1 = max(canvasHeight, canvasHeight2);
-
- Widget drawingArea = (Widget)handle;
- if (horizontal > 0)
- {
- hExtent = horizontal*x_length;
-
- if (!hScroll)
- {
- hScrollBar = XtVaCreateManagedWidget("hsb",
- xmScrollBarWidgetClass, scrolledWindow,
- XmNorientation, XmHORIZONTAL,
- NULL);
- XtAddCallback(hScrollBar, XmNvalueChangedCallback, wxScrollCallback, XmHORIZONTAL);
- XtAddCallback(hScrollBar, XmNdragCallback, wxScrollCallback, XmHORIZONTAL);
- }
-
- XtVaSetValues(hScrollBar,
- XmNincrement, 1,
- XmNpageIncrement, x_page,
- XmNmaximum, x_length,
- XmNvalue, 0,
- XmNsliderSize, (int)(max(min(canvasWidth1/horizontal, x_length), 1)),
- NULL);
-
- if (GetDC())
- GetDC()->device_origin_x = 0;
- if (is_retained)
- pixmapOffsetX = 0;
-
- hScroll = TRUE;
- }
- else
- {
- hExtent = 0;
- hScroll = FALSE;
- }
- if (vertical > 0)
- {
- vExtent = vertical*y_length;
-
- if (!vScroll)
- {
- vScrollBar = XtVaCreateManagedWidget("vsb",
- xmScrollBarWidgetClass, scrolledWindow,
- XmNorientation, XmVERTICAL,
- NULL);
- XtAddCallback(vScrollBar, XmNvalueChangedCallback, wxScrollCallback, XmVERTICAL);
- XtAddCallback(vScrollBar, XmNdragCallback, wxScrollCallback, XmVERTICAL);
- }
-
- XtVaSetValues(vScrollBar,
- XmNincrement, 1,
- XmNpageIncrement, y_page,
- XmNmaximum, y_length,
- XmNvalue, 0,
- XmNsliderSize, (int)(max(min(canvasHeight1/vertical, y_length), 1)),
- NULL);
-
- if (GetDC())
- GetDC()->device_origin_y = 0;
- if (is_retained)
- pixmapOffsetY = 0;
-
- vScroll = TRUE;
- }
- else
- {
- vExtent = 0;
- vScroll = FALSE;
- }
-
- if (!scrollingInitialized)
- {
- XmScrolledWindowSetAreas(scrolledWindow, hScrollBar, vScrollBar, drawingArea);
- if (hScrollBar)
- XtRealizeWidget(hScrollBar);
- if (vScrollBar)
- XtRealizeWidget(vScrollBar);
- }
-
- /*
- * Retained pixmap stuff
- *
- */
-
- if (is_retained && (hExtent > 0) && (vExtent > 0))
- {
- if ((hExtent != pixmapWidth) || (vExtent != pixmapHeight))
- {
- pixmapWidth = hExtent;
- pixmapHeight = vExtent;
-
- if (backingPixmap)
- XFreePixmap(XtDisplay(drawingArea), backingPixmap);
-
- backingPixmap = XCreatePixmap(XtDisplay(drawingArea),
- RootWindowOfScreen(XtScreen(drawingArea)), hExtent, vExtent,
- DefaultDepthOfScreen(XtScreen(drawingArea)));
-
- Clear();
- OnPaint();
- }
- }
-
- // This necessary to make scrollbars appear, for some reason!
- int w, h, x, y;
- GetSize(&w, &h);
- GetPosition(&x, &y);
- SetSize(x, y, w, h);
- #endif
- #ifdef wx_xview
- Canvas canvas = (Canvas)handle;
- if (!horiz_scroll && horizontal > 0)
- horiz_scroll = xv_create(canvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,NULL);
- if (horizontal > 0)
- {
- int canvas_width = horizontal*x_length + 1;
- (void)xv_set(horiz_scroll,
- SCROLLBAR_PIXELS_PER_UNIT, horizontal,
- SCROLLBAR_OBJECT_LENGTH, x_length,
- SCROLLBAR_PAGE_LENGTH, x_page,
- SCROLLBAR_VIEW_LENGTH, x_page,
- NULL);
- (void)xv_set(canvas, CANVAS_WIDTH, canvas_width,
- CANVAS_AUTO_EXPAND, FALSE,
- CANVAS_AUTO_SHRINK, FALSE,
- NULL);
- }
- if (vertical > 0 && !vert_scroll)
- vert_scroll = xv_create(canvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL, NULL);
- if (vertical > 0)
- {
- int canvas_height = vertical*y_length + 1;
- (void)xv_set(vert_scroll,
- SCROLLBAR_PIXELS_PER_UNIT, vertical,
- SCROLLBAR_OBJECT_LENGTH, y_length,
- SCROLLBAR_PAGE_LENGTH, y_page,
- SCROLLBAR_VIEW_LENGTH, y_page,
- NULL);
- (void)xv_set(canvas, CANVAS_HEIGHT, canvas_height,
- CANVAS_AUTO_EXPAND, FALSE,
- CANVAS_AUTO_SHRINK, FALSE,
- NULL);
-
- }
-
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
- if (wnd)
- {
- wnd->xscroll_pixels_per_line = horizontal;
- wnd->yscroll_pixels_per_line = vertical;
- wnd->xscroll_lines = x_length;
- wnd->yscroll_lines = y_length;
- wnd->xscroll_lines_per_page = x_page;
- wnd->yscroll_lines_per_page = y_page;
-
- SetScrollRange(wnd->handle, SB_HORZ, 0, x_length, TRUE);
- SetScrollRange(wnd->handle, SB_VERT, 0, y_length, TRUE);
- }
-
- #endif
- }
-
- /*
- * Scroll to given position (scroll position, not pixel position)
- */
- void wxCanvas::Scroll(int x_pos, int y_pos)
- {
- int old_x, old_y;
- ViewStart(&old_x, &old_y);
- if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
- return;
-
- #ifdef wx_motif
- Bool clearCanvas = FALSE;
-
- if (hScroll)
- {
- XtVaSetValues(hScrollBar, XmNvalue, x_pos, NULL);
- if (hScrollingEnabled && !is_retained)
- clearCanvas = TRUE;
-
- if (GetDC())
- GetDC()->device_origin_x = -(x_pos * horiz_units);
- if (is_retained)
- pixmapOffsetX = (x_pos * horiz_units);
- }
- if (vScroll)
- {
- XtVaSetValues(vScrollBar, XmNvalue, y_pos, NULL);
-
- if (vScrollingEnabled && !is_retained)
- clearCanvas = TRUE;
-
- if (GetDC())
- GetDC()->device_origin_y = -(y_pos * vert_units);
- if (is_retained)
- pixmapOffsetY = (y_pos * vert_units);
- }
-
- if (clearCanvas)
- Clear();
- Refresh();
- #endif
- #ifdef wx_xview
- if (x_pos > -1 && horiz_scroll)
- (void)xv_set(horiz_scroll, SCROLLBAR_VIEW_START, x_pos, NULL);
-
- if (y_pos > -1 && vert_scroll)
- (void)xv_set(vert_scroll, SCROLLBAR_VIEW_START, y_pos, NULL);
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
-
- if (x_pos > -1)
- {
- wnd->xscroll_position = x_pos;
- SetScrollPos(wnd->handle, SB_HORZ, x_pos, TRUE );
- }
- if (y_pos > -1)
- {
- wnd->yscroll_position = y_pos;
- SetScrollPos(wnd->handle, SB_VERT, y_pos, TRUE );
- }
- InvalidateRect(wnd->handle, NULL, TRUE);
- UpdateWindow(wnd->handle);
- #endif
- }
-
- void wxCanvas::SetCountdown(int n)
- {
- #ifdef wx_xview
- repaint_countdown = n;
- #endif
- }
-
- void wxCanvas::EnableScrolling(Bool x_scroll, Bool y_scroll)
- {
- #ifdef wx_motif
- hScrollingEnabled = x_scroll;
- vScrollingEnabled = y_scroll;
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
- wnd->x_scrolling_enabled = x_scroll;
- wnd->y_scrolling_enabled = y_scroll;
- #endif
- }
-
- void wxCanvas::GetVirtualSize(int *x, int *y)
- {
- #ifdef wx_motif
- if (hExtent == 0)
- *x = canvasWidth;
- else
- *x = hExtent;
-
- if (vExtent == 0)
- *y = canvasHeight;
- else
- *y = vExtent;
- #endif
- #ifdef wx_xview
- Canvas canvas = (Canvas)handle;
- *x = (int)xv_get(canvas, CANVAS_WIDTH);
- *y = (int)xv_get(canvas, CANVAS_HEIGHT);
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
- if (wnd)
- {
- *x = wnd->xscroll_pixels_per_line * wnd->xscroll_lines;
- *y = wnd->yscroll_pixels_per_line * wnd->yscroll_lines;
- }
- #endif
- }
-
- #ifdef wx_xview
- void wxCanvasRepaintProc(Canvas x_canvas, Xv_Window paint_win,
- Display *display, Window xwin, Xv_xrectlist *xrects)
- {
- // cout << "Canvas paint: " << xrects->count << " rectangles\n";
-
- wxCanvas *canvas = (wxCanvas *)xv_get(x_canvas, WIN_CLIENT_DATA);
- if (canvas && canvas->repaint_countdown > 0)
- {
- canvas->repaint_countdown --;
- return;
- }
- if (canvas && display && xwin)
- {
- if (xrects && canvas->is_retained)
- {
- canvas->xrects = xrects;
- XSetClipRectangles(canvas->display, canvas->GetDC()->gc, 0, 0, xrects->rect_array, xrects->count, Unsorted);
- }
-
- canvas->paint_window = paint_win;
- canvas->display = display;
- canvas->xwindow = xwin;
-
- canvas->OnPaint();
-
- canvas->xrects = NULL;
-
- XGCValues gc_val;
- gc_val.clip_mask = None;
- XChangeGC(canvas->display, canvas->GetDC()->gc, GCClipMask, &gc_val);
- }
- }
-
- void wxCanvasResizeProc(Canvas x_canvas, int width, int height)
- {
- wxCanvas *canvas = (wxCanvas *)xv_get(x_canvas, WIN_CLIENT_DATA);
- if (canvas)
- {
- Xv_Window pw = canvas_paint_window(x_canvas);
- canvas->paint_window = pw;
- canvas->xwindow = (Window)xv_get(pw, XV_XID);
- canvas->OnSize(width, height);
- }
- }
-
- void wxCanvasEventProc(Xv_Window window, Event *x_event, Notify_arg arg)
- {
- wxCanvas *canvas = (wxCanvas *)xv_get(window, WIN_CLIENT_DATA);
- if (canvas)
- {
- canvas->paint_window = window;
- canvas->xwindow = (Window)xv_get(window, XV_XID);
-
- if (event_id(x_event) == KBD_USE)
- canvas->OnSetFocus();
- else if (event_id(x_event) == KBD_DONE)
- canvas->OnKillFocus();
- else if (event_is_ascii(x_event))
- {
- canvas->OnChar(x_event->ie_code);
- }
- else
- {
- wxEvent event(x_event);
- if (canvas->GetDC())
- {
- event.x = canvas->GetDC()->DeviceToLogicalX(event_x(x_event));
- event.y = canvas->GetDC()->DeviceToLogicalY(event_y(x_event));
- }
-
- if (event.Dragging())
- {
- // Don't respond to ALL drag events since we can't necessarily
- // keep up with them (dependent on application, really - define
- // DRAG_MAX differently if necessary)
- if (canvas->drag_count > 0)
- {
- canvas->drag_count --;
- }
- else
- {
- canvas->drag_count = canvas->DRAG_MAX;
- canvas->OnEvent(event);
- }
- }
- else canvas->OnEvent(event);
- }
- }
- }
- #endif
-
- #ifdef wx_motif
- void wxCanvasRepaintProc(Widget drawingArea, XtPointer clientData, XmDrawingAreaCallbackStruct *cbs)
- {
- wxCanvas *canvas = (wxCanvas *)clientData;
-
- if (canvas && (cbs->reason == XmCR_EXPOSE) && canvas->allowRepainting)
- {
- // cout << "Canvas repaint\n";
- canvas->display = XtDisplay(drawingArea);
- canvas->Refresh();
- }
- }
-
- void wxCanvasKeyEvent(Widget drawingArea, XKeyEvent *event)
- {
- wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)drawingArea);
-
- switch (event->type)
- {
- case KeyPress:
- {
- KeySym keySym;
- XComposeStatus compose;
- (void)XLookupString(event, wxBuffer, 20, &keySym, &compose);
- canvas->OnChar(wxBuffer[0]);
- break;
- }
- case FocusIn:
- {
- canvas->OnSetFocus();
- break;
- }
- case FocusOut:
- {
- canvas->OnKillFocus();
- }
- }
- }
-
- void wxCanvasInputEvent(Widget drawingArea, XButtonEvent *event)
- {
- wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)drawingArea);
-
- switch (event->type)
- {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- {
- wxEvent wxevent;
- wxevent.event_handle = event;
-
- if (canvas->GetDC())
- {
- wxevent.x = canvas->GetDC()->DeviceToLogicalX(event->x);
- wxevent.y = canvas->GetDC()->DeviceToLogicalY(event->y);
- }
-
- if (event->type == ButtonPress)
- {
- if (event->button == Button1)
- canvas->button1Pressed = TRUE;
- else if (event->button == Button2)
- canvas->button2Pressed = TRUE;
- else if (event->button == Button3)
- canvas->button3Pressed = TRUE;
- }
- else if (event->type == ButtonRelease)
- {
- if (event->button == Button1)
- canvas->button1Pressed = FALSE;
- else if (event->button == Button2)
- canvas->button2Pressed = FALSE;
- else if (event->button == Button3)
- canvas->button3Pressed = FALSE;
- }
-
- wxevent.button1Pressed = canvas->button1Pressed;
- wxevent.button2Pressed = canvas->button2Pressed;
- wxevent.button3Pressed = canvas->button3Pressed;
-
- canvas->OnEvent(wxevent);
- break;
- }
- }
- }
- #endif
-
- // Where the current view starts from
- void wxCanvas::ViewStart(int *x, int *y)
- {
- #ifdef wx_motif
- int xx, yy;
- if (hScroll)
- XtVaGetValues(hScrollBar, XmNvalue, &xx, NULL);
- else xx = 0;
- if (vScroll)
- XtVaGetValues(vScrollBar, XmNvalue, &yy, NULL);
- else yy = 0;
- *x = xx;
- *y = yy;
- #endif
- #ifdef wx_xview
- if (horiz_scroll)
- *x = (int)xv_get(horiz_scroll, SCROLLBAR_VIEW_START);
- else *x = 0;
-
- if (vert_scroll)
- *y = (int)xv_get(vert_scroll, SCROLLBAR_VIEW_START);
- else *y = 0;
-
- #endif
- #ifdef wx_msw
- wxWnd *wnd = (wxWnd *)handle;
- *x = wnd->xscroll_position;
- *y = wnd->yscroll_position;
- #endif
- }
-
- // Use this to set the canvas's 'context' member to
- // a user-supplied dc
- void wxCanvas::SetContext(wxDC *dc)
- {
- context = dc;
- }
-
- // Reset 'context' back to the canvas' context
- void wxCanvas::ResetContext(void)
- {
- context = wx_dc;
- }
-
- void wxCanvas::Clear(void)
- {
- wx_dc->Clear();
- }
-
- void wxCanvas::DrawLine(float x1, float y1, float x2, float y2)
- {
- wx_dc->DrawLine(x1, y1, x2, y2);
- }
-
- void wxCanvas::DrawPoint(float x, float y)
- {
- wx_dc->DrawPoint(x, y);
- }
-
- void wxCanvas::DrawPolygon(int n, wxPoint points[], float xoffset, float yoffset)
- {
- wx_dc->DrawPolygon(n, points, xoffset, yoffset);
- }
-
- void wxCanvas::DrawPolygon(wxList *list, float xoffset, float yoffset)
- {
- wx_dc->DrawPolygon(list, xoffset, yoffset);
- }
-
- void wxCanvas::DrawLines(int n, wxPoint points[], float xoffset, float yoffset)
- {
- wx_dc->DrawLines(n, points, xoffset, yoffset);
- }
-
- void wxCanvas::DrawLines(wxList *list, float xoffset, float yoffset)
- {
- wx_dc->DrawLines(list, xoffset, yoffset);
- }
-
- void wxCanvas::DrawRectangle(float x, float y, float width, float height)
- {
- wx_dc->DrawRectangle(x, y, width, height);
- }
-
- void wxCanvas::DrawRoundedRectangle(float x, float y, float width, float height, float radius)
- {
- wx_dc->DrawRoundedRectangle(x, y, width, height, radius);
- }
-
- void wxCanvas::DrawEllipse(float x, float y, float width, float height)
- {
- wx_dc->DrawEllipse(x, y, width, height);
- }
-
-
- void wxCanvas::SetFont(wxFont *the_font)
- {
- wx_dc->SetFont(the_font);
- }
-
- void wxCanvas::SetPen(wxPen *pen)
- {
- wx_dc->SetPen(pen);
- }
-
- void wxCanvas::SetTextForeground(wxColour *colour)
- {
- wx_dc->SetTextForeground(colour);
- }
-
- void wxCanvas::SetTextBackground(wxColour *colour)
- {
- wx_dc->SetTextBackground(colour);
- }
-
- void wxCanvas::SetBrush(wxBrush *brush)
- {
- wx_dc->SetBrush(brush);
- }
-
- void wxCanvas::DrawText(char *text, float x, float y)
- {
- wx_dc->DrawText(text, x, y);
- }
-
- void wxCanvas::SetBackground(wxBrush *brush)
- {
- wx_dc->SetBackground(brush);
- }
-
- void wxCanvas::SetLogicalFunction(int function)
- {
- wx_dc->SetLogicalFunction(function);
- }
-
- // Make a 3-point spline
- void wxCanvas::DrawSpline(float x1, float y1, float x2, float y2, float x3, float y3)
- {
- wx_dc->DrawSpline(x1, y1, x2, y2, x3, y3);
- }
-
- void wxCanvas::DrawSpline(wxList *list)
- {
- wx_dc->DrawSpline(list);
- }
-
- int wxCanvas::GetTextFamily(void)
- {
- return wx_dc->GetTextFamily();
- }
-
- int wxCanvas::GetTextStyle(void)
- {
- return wx_dc->GetTextStyle();
- }
-
- int wxCanvas::GetTextWeight(void)
- {
- return wx_dc->GetTextWeight();
- }
-
- float wxCanvas::GetTextHeight(void)
- {
- return wx_dc->GetTextHeight();
- }
-
- float wxCanvas::GetTextWidth(void)
- {
- return wx_dc->GetTextWidth();
- }
-
- void wxCanvas::GetTextExtent(char *string, float *x, float *y)
- {
- wx_dc->GetTextExtent(string, x, y);
- }
-
- #ifdef wx_msw
- void wxWnd::DeviceToLogical(float *x, float *y)
- {
- if (is_canvas)
- {
- wxCanvas *canvas = (wxCanvas *)wx_window;
- *x = canvas->wx_dc->DeviceToLogicalX((int)*x);
- *y = canvas->wx_dc->DeviceToLogicalY((int)*y);
- }
- }
-
- wxCanvasWnd::wxCanvasWnd(wxWnd *parent, wxWindow *wx_win,
- int x, int y, int width, int height, DWORD style):
- wxSubWnd(parent, "wxCanvasClass", wx_win, x, y, width, height, style)
- {
- is_canvas = TRUE;
- // ShowScrollBar(handle, SB_BOTH, TRUE);
- }
-
-
- BOOL wxCanvasWnd::OnEraseBkgnd(HDC pDC)
- {
- if (background_brush)
- {
- RECT rect;
- GetClientRect(handle, &rect);
- int mode = SetMapMode(pDC, MM_TEXT);
- FillRect(pDC, &rect, background_brush);
- SetMapMode(pDC, mode);
-
- wxCanvas *canvas = (wxCanvas *)wx_window;
- SetViewportExtEx(pDC, VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL);
- SetWindowExtEx(pDC, canvas->wx_dc->window_ext_x, canvas->wx_dc->window_ext_y, NULL);
-
- return TRUE;
- }
- else return FALSE;
- }
-
-
- #endif
-