📄 test5.c
字号:
/* $Header: /cvsroot/lesstif/lesstif/test/Xm/scrolledwindow/test5.c,v 1.4 2001/05/23 14:30:30 amai Exp $** Generated by X-Designer ** autopan*//***LIBS: -lXm -lXt -lX11*/#include <X11/Xatom.h>#include <X11/Intrinsic.h>#include <X11/Shell.h>#include <Xm/Xm.h>#include <Xm/DialogS.h>#include <Xm/DrawingA.h>#include <Xm/Form.h>#include <Xm/PushB.h>#include <Xm/ScrollBar.h>#include <Xm/ScrolledW.h>#include <Xm/Xm.h>#include <stdio.h>typedef struct canvas_s { Widget da; Widget hsb; Widget vsb; int width, height, x_offset, y_offset; GC gc; /* New fields for autopanning */ int v_scroll_direction; int h_scroll_direction; XtIntervalId timer;} canvas_t, *canvas_p;extern Widget create_appshell();/* * *LIBS: -lXm -lXt -lX11 */extern void register_actions();extern void expand();extern void expose();extern void graphics_expose();extern void resize();extern void hsb_changed();extern void vsb_changed();extern void create_gc();extern void adjust_size();voidexpand(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data;{ /* Double the size of the (notional) canvas */ canvas_p canvas = (canvas_p)client_data; canvas->width=2*canvas->width; canvas->height=2*canvas->height; adjust_size(canvas); /* * Generate expose event for entire window (strictly * only needed if XmDrawingArea is larger than canvas. */ XClearArea(XtDisplay(canvas->da), XtWindow(canvas->da), 0, 0, 0, 0, True);}static voidset_no_clip(canvas) canvas_p canvas;{ XSetClipMask(XtDisplay(canvas->da), canvas->gc, None);}/* * XmScrollBar callbacks copy an area from the window to itself. */voidhsb_changed(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data;{ canvas_p canvas = (canvas_p) client_data; int slider_size; int pixels_to_lose; Boolean positive; Display *display = XtDisplay(canvas->da); Window window = XtWindow(canvas->da); int new_value = ((XmScrollBarCallbackStruct *) call_data)->value; XEvent event; XSync(display, False); while (XCheckWindowEvent(display, window, ExposureMask, &event)) XtDispatchEvent(&event); if (canvas->x_offset == new_value) return; XtVaGetValues(canvas->hsb, XmNsliderSize, &slider_size, NULL); /* Work out how far (and in which direction) we need to scroll */ if ((positive = (new_value > canvas->x_offset))) pixels_to_lose = new_value - canvas->x_offset; else pixels_to_lose = canvas->x_offset - new_value; canvas->x_offset = new_value; if (pixels_to_lose >= slider_size) /* Scrolling more than a page, nothing worth copying */ XClearArea(display, window, 0, 0, 0, 0, True); else { /* Copy useful section, and expose revealed section */ Dimension width, height; XtVaGetValues(canvas->da, XmNwidth, &width, XmNheight, &height, NULL); set_no_clip(canvas); if (positive) { XCopyArea(display, window, window, canvas->gc, pixels_to_lose, 0, width - pixels_to_lose, height, 0, 0); XClearArea(display, window, width - pixels_to_lose, 0, pixels_to_lose, height, True); } else { XCopyArea(display, window, window, canvas->gc, 0, 0, width - pixels_to_lose, height, pixels_to_lose, 0); XClearArea(display, window, 0, 0, pixels_to_lose, height, True); } }}void vsb_changed(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data;{ canvas_p canvas = (canvas_p) client_data; int slider_size; int pixels_to_lose; Boolean positive; XEvent event; Display *display = XtDisplay(canvas->da); Window window = XtWindow(canvas->da); int new_offset = ((XmScrollBarCallbackStruct *) call_data)->value * 20; /* * Basically the same code as before, but converts from * scrollbar units (lines) to pixels. */ if (canvas->y_offset == new_offset) return; XSync(display, False); while (XCheckWindowEvent(display, window, ExposureMask, &event)) XtDispatchEvent(&event); XtVaGetValues(canvas->vsb, XmNsliderSize, &slider_size, NULL); if ((positive = (new_offset > canvas->y_offset))) pixels_to_lose = new_offset - canvas->y_offset; else pixels_to_lose = canvas->y_offset - new_offset; canvas->y_offset = new_offset; if (pixels_to_lose >= slider_size * 20) /* Scrolling more than a page, nothing worth copying */ XClearArea(display, window, 0, 0, 0, 0, True); else { /* Copy useful section, and expose revealed section */ Dimension width, height; XtVaGetValues(canvas->da, XmNwidth, &width, XmNheight, &height, NULL); set_no_clip(canvas); if (positive) { XCopyArea(display, window, window, canvas->gc, 0, pixels_to_lose, width, height - pixels_to_lose, 0, 0); XClearArea(display, window, 0, height - pixels_to_lose, width, pixels_to_lose, True); } else { XCopyArea(display, window, window, canvas->gc, 0, 0, width, height - pixels_to_lose, 0, pixels_to_lose); XClearArea(display, window, 0, 0, width, pixels_to_lose, True); } }}/* * Adjust one XmScrollBar to suit proportions of XmDrawingArea * and the * notional canvas. adjust_scrollbar() is as before. adjust_v_scrollbar() * uses line units. */voidadjust_scrollbar(sbar, size, visible_size, value) Widget sbar; int size, *value; Dimension visible_size;{ /* Assume that minimum is 0 */ int slider_size = visible_size; int maximum = size; XtVaGetValues(sbar, XmNvalue, value, NULL); if (slider_size > maximum) slider_size = maximum; if (*value > maximum - slider_size) *value = maximum - slider_size; XtVaSetValues(sbar, XmNvalue, *value, XmNsliderSize, slider_size, XmNmaximum, maximum, NULL);}voidadjust_v_scrollbar(sbar, size, visible_size, offset) Widget sbar; int size, *offset; Dimension visible_size;{ int slider_size = (visible_size + 19) / 20; int maximum = (size + 19) / 20; int value; XtVaGetValues(sbar, XmNvalue, &value, NULL); if (slider_size > maximum) slider_size = maximum; if (value > maximum - slider_size) value = maximum - slider_size; XtVaSetValues(sbar, XmNvalue, value, XmNsliderSize, slider_size, XmNmaximum, maximum, NULL); *offset = value * 20;}/* * Set XmScrollBars to suit canvas and XmDrawingArea */voidadjust_size(canvas) canvas_p canvas;{ Dimension width, height; XtVaGetValues(canvas->da, XmNwidth, &width, XmNheight, &height, NULL); adjust_v_scrollbar(canvas->vsb, canvas->height, height, &canvas->y_offset); adjust_scrollbar(canvas->hsb, canvas->width, width, &canvas->x_offset);}/* * XmDrawingArea resize callback */voidresize(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data;{ canvas_p canvas = (canvas_p) client_data; adjust_size(canvas);}static char *da_translations ="<Btn1Down>: drag_start()\n\<Btn1Motion>: drag_motion()\n\<Btn1Up>: drag_stop()";void drag_start();void drag_motion();void drag_stop();static void timer();static XtActionsRec da_actions[] = { {"drag_start", drag_start}, {"drag_motion", drag_motion}, {"drag_stop", drag_stop}};voidregister_actions(canvas) canvas_p canvas;{ /* Register new actions first, then translations that use them */ XtAppAddActions(XtWidgetToApplicationContext(canvas->da), da_actions, XtNumber(da_actions)); XtOverrideTranslations(canvas->da, XtParseTranslationTable(da_translations));}static Booleanauto_scroll_bar(w, doit, amount) Widget w; Boolean doit; int amount;{ int min, max, value, slider_size, inc, pinc; Boolean space; XtVaGetValues(w, XmNminimum, &min, XmNmaximum, &max, XmNvalue, &value, XmNsliderSize, &slider_size, XmNincrement, &inc, XmNpageIncrement, &pinc, NULL); value = value + amount; space = (value >= min && value + slider_size <= max);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -