/*TEACH Xpw Jonathan Meyer Sept 1990 Updated Julian Clinton Jan 1994 This file contains some sample code to illustrate how to create and use the graphics facilities provided by the Poplog Widget Set. It is written so that it can be loaded as a program file. The examples given here assume that you have some knowledge of the X Toolkit and the Poplog Widget Set. CONTENTS - (Use g to access required sections) -- Load Widgets -- Start Toolkit -- Create A New Shell -- Creating Children -- Make Window -- A Simple Button -- Callbacks - A First Example -- A Label With Some Callbacks -- A Drawing Callback Load Widgets ------------ To load some widgets from eg. the Poplog Widget Set, you need to instruct Poplog to get the relevant libraries and define the widget constants: */ uses popxlib; ;;; using X max(popmemlim, 400000) -> popmemlim; ;;; give us some space. uses xt_widget; uses xt_callback; uses xt_event; uses XpwGraphic; uses XpwPixmap; uses xpwGraphicWidget; uses xpwCompositeWidget; uses xtApplicationShellWidget; /* Start Toolkit ------------- After loading some widgets, you need to initialize the toolkit. This connects your Poplog process to the X Window Server process, the name of which should be held in the environment variable DISPLAY. You can check this environment variable using systranslate('DISPLAY') => Typical display names are ':0.0', 'unix:0.0', 'suna:0.0' etc. Starting up an X connection: */ XptDefaultSetup(); /* Create A New Shell ------------------ Now, create a new shell window, which is the basic top level container window for other widgets: */ vars shell = XtAppCreateShell('xpw', 'Xpw', xtApplicationShellWidget, XptDefaultDisplay, XptArgList([]) ); /* Creating Children ----------------- A shell widget can have only one child. We want to create several different children, so we will make a "Composite" widget inside the shell. Composite widgets manage more than one child widgets, which we will add at a later stage. */ vars composite = XtCreateManagedWidget('composite', xpwCompositeWidget, shell, XptArgList([ {width 300} {height 200} ]) ); /* Now, lets put a graphics widget within the composite widget - this can be used to draw on. */ vars graphic = XtCreateManagedWidget('graphic', xpwGraphicWidget, composite, ;;; make it same size as parent. XptArgList([ {width 300} {height 200} ]) ); /* Make Window ----------- In order to make the window appear, we must "Realize" it. Realizing means telling the X server to create a new window. In this case, we want to realize the top level window, held in the -shell- variable. */ XtRealizeWidget(shell); /* A Simple Button --------------- First, draw a label for the button ( See REF *XpwPixmap for a full list of graphics operations in Xpw). */ XpwDrawImageString(graphic, 10,10, 'Button: '); /* Now create a new widget which we will use to detect button events. We will put this widget in the composite widget we created earlier: */ vars button = XtCreateManagedWidget('button', xpwGraphicWidget, composite, XptArgList([ {width 10} {height 10} {x 75} {y 2} ])); /* Callbacks - A First Example --------------------------- We will use the buttonEvent callback to detect button events within the small button widget we made above. The button callback will use *XptValue to set the foreground of the button to one of three values, according to which button was pressed. The button number must be determined using exacc to convert an external pointer into an integer. */ vars colors; if XptValue(shell, XtN depth) > 1 then ;;; give each button a different colour ['red' 'green' 'yellow']; else ;;; all buttons are black ['black' 'black' 'black'] endif -> colors; ;;; our button event callback: define button_callback(w, client, call); lvars w, client, call, button; exacc ^int call -> button; ;;; get button number as integer if button > 0 then ;;; button going down (negative number when button goes up) ;;; set the window colour XpwSetColor(w, colors(button))->; XpwFillRectangle(w, 0,0,10,10); else ;;; button going up XpwSetColor(w, 'white')->; XpwFillRectangle(w, 0,0,10,10); endif; enddefine; ;;; register our button event handler by adding a callback: XtAddCallback(button, XtN buttonEvent, button_callback, false); ;;; TRY: ;;; click on the button with each mouse button /* A Label With Some Callbacks --------------------------- Now lets make a window with a label in it, which gets inverted each time the button is clicked on the window. Clicking on the label also switches a global variable on and off. */ ;;; load graphic operations as permanent identfiers loadinclude xpt_xgcvalues; vars label = XtCreateManagedWidget('label', xpwGraphicWidget, composite, XptArgList([ {width 100} {height 12} {x 50} {y 70} ])); ;;; write in the label: XpwDrawImageString(label, 10, 9, ' Draw'); ;;; set the label graphics function to exclusive or: GXxor -> XptValue(label, XtN function); ;;; define a callback procedure: vars drawing = false; define label_callback(w, client, call); lvars w, client, call, button; exacc ^int call -> button; ;;; get button as integer if button == 1 then ;;; reverse label not(drawing) -> drawing; XpwFillRectangle(label,0,0,100,12); endif; enddefine; ;;; register callback XtAddCallback(label, XtN buttonEvent, label_callback, false); ;;; TRY: ;;; click on the label marked draw, and also print out ;;; the value of drawing after clicks /* A Drawing Callback ------------------ This final callback tracks the mouse motion events within the "graphic" widget, leaving a trail showing where the mouse has been. It uses the global variable "drawing" defined above to determine whether the trail should be visible. This means clicking on the label widget will turn drawing on and off. */ vars old_x = false, old_y; define motion_callback(w, client, call); lvars w, client, call, x, y; returnunless(drawing); ;;; get mouse location: XptValue(w, XtN mouseX) -> x; XptValue(w, XtN mouseY) -> y; ;;; draw from old mouse location to current mouse location if old_x then XpwDrawLine(w, x,y, old_x, old_y); endif; x -> old_x; y -> old_y; enddefine; XtAddCallback(graphic, XtN motionEvent, motion_callback, false); ;;; TRY: ;;; click on the "Draw" label to turn on drawing, ;;; then drag the mouse around /* --- C.x/x/pop/teach/Xpw --- Copyright University of Sussex 1990. All rights reserved. ---------- */