The Karma widgets library is a set of Xt Intrinsics widgets which is intended to tie the Karma graphics library into a Graphical User Interface implemented by one or more third-party widget libraries. The tedious details of geometry management and event insertion into the Karma graphics library is solved by a range of display widgets. Advanced dynamic colourmap control and other user interface widgets are also provided.
The documentation on image display, communications support, colourmap support and image editing support are highly recommended. The reader may also want to become familiar with Xt Intrinsics and widget libraries in general. The reference manual is also required.
The Karma widgets library is distinct from the rest of the library in that it is not so clearly layered. There is no naming convention to determine the level a package/routine is in, and hence it's power. Furthermore, widgets are free to draw upon the resources of packages at any level in the rest of the library. Basic information about what each widget provides is given below. The reference manual lists all the resources for each widget, giving the name, class, representation type and default value.
The AnimateControl widget provides various buttons, sliders and value widgets to assist an application to animate through a sequence of images or graphics. Used in the ImageDisplay widget.
This widget controls movie loops. It allows the user to control the speed and direction of movies, as well as the ability to skip frames. The following controls are provided:
You can also step through the cube by clicking (left) for the previous frame or click (right) for the next frame in the black rectangle which appears below the Goto Frame button. In addition, you can click (middle) and drag in this black rectangle, allowing you to dynamically slide through the movie.
A screen snapshot is available here.
The Canvas widget is the fundamental link between Xt Intrinsics and the Karma graphics library. It provides geometry management and event insertion from the Xt world into a Karma pixel canvas. The pixel canvas is managed by the widget. The visual type of the underlying X window (and hence the pixel canvas) may be specified at creation (the default is to copy the parent window visual). On display hardware which supports stereoscopic display, a stereo canvas may be created if requested, rather than a regular canvas. A stereo canvas has a left and right pixel canvas created, rather than a monoscopic (normal) pixel canvas. A set of Canvas widgets may be created by creating one MultiCanvas widget. Please read the section on the MultiCanvas widget.
All drawing operations in Karma tools are performed on a ``canvas'', which is usually a big plain black or white rectangle.
The canvas allows you to freeze ``mouse move'' operations (i.e. things which happen in response to your moving the mouse over the window, but not while pressing any mouse buttons or keyboard keys). This is useful when you have pointed at a certain place, and want to maintain a position or profile display while you move the mouse to some other window (perhaps to print the window). All you need to do is press the spacebar, and any further mouse moves are ignored. If you press the spacebar again the mouse moves once again do something. So that you don't forget that mouse moves are disabled, you will hear a quiet beep every time you move the mouse into the window.
The ChoiceMenu widget is an easy to construct non-exclusive menu widget. There is no state associated with the widget. This widget is most useful for grouping together a set of related functions.
The ContourSimpleControl wigdet allows the user to manipulate the display of a contour image.
The Cmapwin wigdet is a colourmap manipulation widget for PseudoColour visuals. Very handy for applications which require dynamic colourmap control. This widget is really a building block for the Cmapwinpopup (section 13.9.2) widget.
The Cmapwinpopup is the real colourmap widget that people use: it comes in it's own popup window. Hence it's name.
This widget controls a colourtable for a ``PseudoColour'' display canvas. Data values are used to index into a table of colours. This is typically used for ``false colour'' image display. The following controls are provided:
You can manipulate the colours in the colourtable by moving the round dot in the big square box (left mouse button). Usually moving the dot horizontally changes the apparent position of the colours, while moving it vertically changes the range of colours.
There are many ``colour functions'' available to set the colourmap, the default one being ``Greyscale1''. Some colour functions produce smoothly-varying colourtables, while others have sharp boundaries.
A final way of manipulating the colourtable is provided by the Red Scale, Green Scale and Blue Scale sliders. With these you can turn down the amount of each primary colour for all the colours in the colourtable.
A screen snapshot is available here.
The Dataclip widget computes and displays the histogram of a n-dimensional Intelligent Array. The user may then define a region on that widget and have the co-ordinates of the region passed to a callback function. Handy for segmenting data by value, rather than position.
This widget allows the user to specify a number of data ``regions'' (ranges). It it most often used to give control over a single region, so that an intensity range may be specified. The widget displays a histogram of the data values in the array, with the vertical axis being logarithmic. The following controls are provided:
If you click with the left mouse button in the histogram display, you define the lower boundary of a region. If no region exists, one is created. If you then click with the right mouse button, the upper boundary is defined. Once the lower and upper boundaries are defined, you will see two vertical lines depicting the boundaries, with two diagonal lines joining them. You will also see a circle, the height of which indicates the width of the region relative to the width of the entire histogram. If you click with the middle mouse button, the horizontal cursor position will control the midpoint of the region (i.e. change the lower and upper boundaries at the same time), and the vertical cursor position changes the width of the region. You can drag any of the three mouse buttons to see things continuously change.
If you have not yet defined a region, you may first click with the right button to define the upper boundary. The lower boundary is automatically set to the data minimum. This is a convenience facility when you want to set the lower boundary to the data minimum and set the upper boundary manually. You can get the same effect by pressing Full Range first and then clicking with the right button.
A screen snapshot is available here.
The Dialogpopup widget is a simple dialog widget (text entry) which has it's own window. Good for implementing a last-minute filename query before doing something (like saving data to a file). The widget can choose filenames which do not already exist.
The DirectCmapwin widget is a colourmap manipulation widget for DirectColour visuals. Very handy for applications which require dynamic colourmap control. This widget is really a building block for the Cmapwinpopup (section 13.9.2) widget.
The DressingControl widget controls the axis labelling for a number of world canvases (see the canvas package).
This widget controls the way axis labels are drawn onto a canvas. The following controls are available:
A further set of controls is provided under the red line (most of the time you will not need to use these):
Note that the axis labelling currently does not handle co-ordinate systems which have rotations close to 90 degrees or 270 degrees.
A screen snapshot is available here.
The ExclusiveMenu widget is another menu widget, but the choices are exclusive: i.e. only one choice is allowed at a time. Good for implementing a mode menu. The current choice is displayed at all times.
The ExportMenu widget is a widget to simplfy exporting of data from applications. A building block for the ImageDisplay widget.
This widget allows you to export the currently displayed data to some other format. The following options are available:
The Filepopup widget is a directory browser and file selector widget. You can specify a filename pattern matching/rejecting routine. A callback is called when the user selects a file. The user can also navigate up and down the directory tree. This widget has it's own window.
This widget allows the user to browse a directory tree and select files. All the files and directories the application wants the user to see are displayed. Any one of these may be selected by clicking the left mouse button over the filename. The ``D'' character is used to denote directories, while the ``F'' character is used to denote ordinary files. Above the list of files and directories is shown the current directory for the browser. If you edit the text and press return the current directory is changed appropriately. The ``'' notation is supported, as well as other simple Borne Shell-like expansions of environment variables using the $variable, ${variable} and ${variable:-word} notations. The following controls are provided:
A screen snapshot is available here.
This widget supports the following extensions:
The Filewin widget is the building block for the Filepopup (section 13.16.2) widget: it needs a window around it.
The Hdial widget is made to look a bit like an old-style tuning knob.
The ImageDisplay widget is the all singing, all dancing display widget. It does practically everything but choose the data you want to display. It comes with the following widgets: Filepopup (section 13.16.2), Cmapwinpopup (section 13.9.2), Postscript (section 13.30.2), AnimateControl (section 13.4.2) and Dataclip (section 13.10.2). It also has zoom controls.
Many of the visualisation tools have one or two very similar main windows. This is because they are all derived from the ImageDisplay widget, which provides most of the common functionality. Most of the tools which use this widget provide the following controls:
You will also see a few lines of display under the control buttons, which gives information about the data under the current cursor position.
A screen snapshot is available here.
Wherever you move the mouse over the main image, you will see a magnified portion of that part of the image (the magnification is 4x the data resolution). You can resize the magnifier window.
Simply click with the left mouse button in the panner window and the main window will pan to the desired location. The panner window will display a green rectangle showing you where you have panned to, relative to the entire image. You can resize the panner window. When you select the panner from the Intensity menu, the panner is popped up and the main window is set to panning mode.
To zoom an image, click (left) and drag the mouse (still keeping the left button down) across the window. You will see a ``rubber-banded'' box stretching between the first point and the current mouse cursor position. When you release the button the section of the image within the box will be zoomed. To unzoom, choose the Unzoom option in the Zoom menu, or press the ``u'' key while the cursor is in the image window. This will show the entire image.
You can also press the ``i'' key (zoom in) and the image is zoomed 2x, with the new centre of the image being the position of the mouse when the ``i'' key was pressed. You can zoom in as many times as you like. To unzoom 2x, press the ``o'' key (zoom out). When unzooming it doesn't matter where the mouse is.
If you press and release the left mouse button without moving the mouse in between, the image will be panned so that what is under the mouse cursor is moved to the centre of the image. An extra facility in <kview> and <MultibeamView> is the ability to zoom in and out using the middle and right mouse buttons, respectively, in a similar fashion to using the ``i'' and ``o'' keys.
Note that these zoom controls are not available when you place the main window in panning mode.
Another key you can press is ``r'' which simply refreshes the window, without changing the zoom area.
Many programmes have a facility to compute and display the statistics of the current (sub)image being viewed. Simply press the ``s'' key in the display window and you will see a summary of the image statistics in the terminal window. This summary includes the number of (non-blank) values, the standard deviation, the mean, minimum, maximum and sum value. Alternatively, you can click (left) and drag the mouse to a new position (still holding the mouse down!) and press the ``s'' key. The statistics are computed over the boxed area. After you press ``s'' you may release the mouse button. This feature saves you from having to zoom in and unzoom every time you wish to compute statistics on a sub-image. Note that the old box remains on the image until something clears it (this is useful when you want to know which regions you have already computed statistics over).
Many programmes allow you to inspect the header of the dataset you are currently viewing as an image. Simply press the ``h'' key and the header will be displayed in the terminal window. If you press the ``H'' key, you will get the header without the history.
The Increment widget is a simple widget with a ``+'', ``-'' buttons and a value display.
The IntensityPolicy widget controls the intensity policy of a set of KWorldCanvas objects (see the canvas package).
This widget controls the intensity policy to be used for displaying image data on a drawing canvas. The following controls are provided:
A screen snapshot is available here.
The Ktoggle widget is a nice toggle widget which can show a cross or a tick to show it's state.
The LoadAndDecimate widget allows you to load and decimate datacubes on the fly.
This widget controls the process of loading and decimating a datacube. The user can skip/average data values along each dimension as well as extract a subcube. The following controls are provided:
Under the first row of buttons, the size of the file (in data elements) is displayed. Under that the memory size required by the decimated subcube is displayed. As you change the slider parameters, the memory requirement changes, and this is reported to you. It is wise to not use more than about half the physical RAM (Random Access Memory) available in your machine.
As the file is loaded and decimated, a simple progress meter shows you how much longer you have to wait. Remember: you can always abort.
A screen snapshot is available here.
The MagnifierPopup widget is subclassed from the SlaveImageDisplayPopup widget. It will monitor mouse movement events on the canvases in the ancestor ImageDisplay widget and uses these events to control the display inside the magnifier window. It is the responsibility of the application to ensure display objects such as viewable images are maintained for the magnifier canvases.
This widget does not define any resources of its own, however it overrides the XkwNfastPanner resource of the SlaveImageDisplayPopup widget to set a default value of False.
This widget supports the following extensions:
This widget is a subclass of the SlaveImageDisplayPopup widget.
The MomentGenerator widget controls the generation of moment maps (the 0th and 1st moments are computed). You supply a 3-dimensional Intelligent Array and you get two 2-dimensional moment maps. The user can control clip levels and the type of algorithm used.
This widget allows the user to generate the 0th (total intensity) and 1st (velocity field) moment maps from a cube. The following controls are available:
A screen snapshot is available here.
The MultiCanvas widget allows you to create many Canvas widgets in one fell swoop. All the Canvas widgets occupy the same area in the window: only one can be visible at a time. You can ask for canvases with any of the following visuals: PseudoColour, Directcolour, TrueColour. You can also ask for stereo canvases. The widget will try to create all the canvas types you requested possible on your display hardware. At any time the application can switch which type of canvas is visible (i.e. when switching from an 8bit PseudoColour display to a 24bit TrueColour display). Saves an awful lot of code trying to work out what visuals the display can support. This is used in the ImageDisplay (section 13.19.2) widget.
The OverlayEditorControl widget is a control panel for interactively drawing overlays over an image.
This widget allows you to interactively draw overlays on top of an image. It uses the overlay package which maintains a list of geometric figures which should be drawn.
The following controls are provided:
A screen snapshot is available here.
This widget uses the middle mouse button for its drawing functions. Some tools may already be using this button for other purposes, in which case the tool should provide a control which allows you to disable the normal use of the middle mouse button. For instance, the <kview> programme provides such a control through the ZoomPolicy widget (section 13.40.2).
You click down the mouse button to define one corner of the rectangle and move the mouse (keeping the button down) until you have a rectangle to your liking. Once you are happy, release the button and the rectangle will be added to the overlay list.
Click the mouse button to define the centre of the ellipse and move the mouse (keeping the button down) to change the size and shape of the ellipse. If you press and release the 'r' key (still with the button down), this will toggle rotation mode, so that now as you move the mouse the ellipse will rotate. To leave rotate mode, just press the 'r' key again, and you will be back to changing the size and shape of the ellipse. Once you have an ellipse you are happy with, release the mouse button and it will be added to the overlay list.
Click and release the mouse button to define the first and subsequent vertices of the polygon. To close (terminate) the polygon, click and release the button twice without moving the mouse. Once you have closed the polygon it is added to the overlay list.
The Palette widget is a building block for the Cmapwin (section 13.8) widget: a simple colour palette, allowing the user to choose a colour (such as when drawing).
The PannerPopup widget is subclassed from the SlaveImageDisplayPopup widget. When popped up it will enable panning mode for the ancestor ImageDisplay widget canvas (the main window). Once popped down the main window reverts back to its original (non panning) mode. It is the responsibility of the application to ensure display objects such as viewable images are maintained for the magnifier canvases.
This widget is a subclass of the SlaveImageDisplayPopup widget.
The Postscript widget, given a Karma pixel canvas, allows the user to specify page size, orientation and whether to generate a PostScript file (or EPS) or to queue directly to a printer.
This widget provides controls for generating PostScript hardcopy. It supports different orientations and trays and allows you to queue directly to a printer. The following controls are available:
A screen snapshot is available here.
The Repeater widget is a fixed version of the Repeater widget from the Athena widget library. Does the right thing when the widget is set insensitive. Holding down the mouse button over this widget will result in periodic invocation of the registered callbacks.
See the Xt reference manual for widget resources.
The SimpleColourbar widget is another building block for the Cmapwin (section 13.8) widget: a simple colour palette. Unlike the Palette widget, this widget does not allow the user to choose a colour. While less functional, it is also more streamlined (most applications don't need the colour-picking feature).
The SimpleSlider widget is slider with a nicer user interface than the Value widget, and with a few more resources.
The SlaveImageDisplayPopup widget will create a popup shell which contains a Close button and a set of stacked Canvas widgets, similar to the stacking by the MultiCanvas widget. Each canvas that is created is a clone of the canvases in an ancestor ImageDisplay widget. This means that colourmaps, visuals, foreground and background colours are all copied. Finally, world canvases are created for each pixel canvas. The benefit of this widget is that it allows you to create a secondary window which has the same types of canvases as your main window. This is useful when creating a magnifier or panner window. Note that this widget must be created before the ancestor ImageDisplay widget is realised.
This widget creates slave display canvases by attaching to an ImageDisplay widget (section 13.19.2). A single Close button is provided which allows you to close the window.
The ThreeDeeSlice widget will display the three orthogonal primary planes of a 3-dimensional array, where those planes intersect in a 3-D point. This point may be interactively changed. Nice for slicing through a cube of data.
The TracePopup widget will compute and display a 1-dimensional trace from a multi-dimensional Intelligent Array. You provide the co-ordinates of the trace and the dimension number of the trace and it does the rest.
This widget will display a line plot of a single trace of one-dimensional data. It is fast, allowing dynamic display of data, and provides zooming and smoothing controls, as well as having the ability to display axis labels. The controls available are:
To zoom a profile, click (left) and drag the mouse (still keeping the left button down) across the window. You will see a ``rubber-banded'' box stretching between the first point and the current mouse cursor position. When you release the button the section of the profile within the box will be zoomed. To unzoom, choose the Unzoom option in the Zoom menu, or press the ``u'' key while the cursor is in the profile window. This will show the entire image.
A screen snapshot is available here.
The Twodpos widget is another building block for the Cmapwin (section 13.8) widget. This allows the user to move around a 2-dimensional point in a plane, which can be used to control something else in the application.
The Value is a sort-of slider widget, except that the value is incremented and decremented with slow and fast Repeater (section 13.31) widgets.
The View2Datasets widget will manage the display of two datasets.
This widget provides an advanced control for two datasets (either two-dimensional or three-dimensional). It allows the user to display one dataset or the other, overlay contours of one over the other, show profiles along any axis, and much more. The controls provided are:
The programme should also work with a photographic negative. The centroiding algorithm is automatically modified to look for a trough rather than a peak
These options can be mixed, i.e. -0.03:-0.01+0.01 0.003:0.1+0.02 0.2 0.3 is interpreted correctly.
In addition, if you click the left mouse button without moving it in between the press and release, the image will pan across. If you click the middle mouse button, the image will zoom in 2x (the new centre of the image will be the place where you clicked). Click the right mouse button to zoom out 2x. If the profile mode is ``box'' then you can't use the middle mouse button to zoom.
A screen snapshot is available here.
The ZoomPolicy widget controls the zooming policy of a set of KWorldCanvas objects (see the canvas package).
This widget controls the policy to be used for displaying image data on a drawing canvas. The following controls are provided:
A screen snapshot is available here.
A quite powerful image display tool is <kview>. The power user is urged to use this module and then read the source code to see how much functionality may be packed into so few lines of code, using the image display support in the Karma library and the ImageDisplay widget. A smaller version of <kview> is described in detail in the image display tool chapter.
A simple example is provided below.
This is a complete application (97 lines) which will display a parabola on the screen. It also displays a lot of buttons/menus which you can happily ignore (or explore).
/*----------------------------------------------------------*/ /* Parabola display sample programme */ /*----------------------------------------------------------*/ #include <stdio.h> #include <unistd.h> #include <X11/Xatom.h> #include <X11/Intrinsic.h> #include <X11/StringDefs.h> #include <karma.h> #include <karma_overlay.h> #include <karma_xtmisc.h> #include <karma_im.h> #include <Xkw/ImageDisplay.h> #define VERSION "1.1" #define NUM_SEGMENTS 100 STATIC_FUNCTION (void draw_parabola, (KOverlayList olist) ); /* Private data */ String fallback_resources[] = { "Kparabola*pseudoColourCanvas*background: black", "Kparabola*Command*background: grey70", "Kparabola*Toggle*background: grey80", "Kparabola*ImageDisplay*quit*background: orange", "Kparabola*background: aquamarine", "Kparabola*font: 9x15bold", NULL }; int main (int argc, char **argv) { KWorldCanvas wc_pseudo; KOverlayList olist; XtAppContext app_context; Widget main_shell, image_display; /*static char function_name[] = "main";*/ /* Initialise module */ im_register_module_name ("kparabola"); im_register_module_version_date (VERSION); im_register_lib_version (KARMA_VERSION); /* Start up Xt */ main_shell = xtmisc_init_app_initialise (&app_context, "Kparabola", NULL, 0, &argc, argv, fallback_resources, XTMISC_INIT_ATT_COMMS_SETUP, TRUE, XTMISC_INIT_ATT_END, NULL); image_display = XtVaCreateManagedWidget ("topForm", imageDisplayWidgetClass, main_shell, XtNborderWidth, 0, XkwNnumDatasets, 0, XkwNcreateFilepopup, FALSE, NULL); XtRealizeWidget (main_shell); XtVaGetValues (image_display, XkwNpseudoColourCanvas, &wc_pseudo, NULL); olist = overlay_va_create_list (NULL, NULL, OVERLAY_ATT_END); overlay_specify_canvas (olist, wc_pseudo); overlay_associate_display_canvas (olist, wc_pseudo); draw_parabola (olist); XtAppMainLoop (app_context); return (RV_OK); } /* End Function main */ static void draw_parabola (KOverlayList olist) /* [PURPOSE] This routine will draw a parabola into an overlay list. <olist> The overlay list. [RETURNS] Nothing. */ { int count; double x_factor, x; double x_arr[NUM_SEGMENTS]; double y_arr[NUM_SEGMENTS]; /* Generate array of points */ x_factor = 2.0 / (double) (NUM_SEGMENTS); for (count = 0; count < NUM_SEGMENTS; ++count) { x = (double) (count - NUM_SEGMENTS / 2) * x_factor; x_arr[count] = x / 2.0 + 0.5; y_arr[count] = x * x; } /* Draw lines */ overlay_lines (olist, NUM_SEGMENTS, NULL, x_arr, y_arr, "yellow"); } /* End Function draw_parabola */