/* File: coltest.c * Author: Ed Griffiths (edgrif@sanger.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1998 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (Sanger Centre, UK) rd@sanger.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.crbm.cnrs-mop.fr * * Description: Test column control and graph. * Exported functions: * HISTORY: * Last edited: Sep 17 16:15 1998 (edgrif) * * Sep 17 16:14 1998 (edgrif): Had to change the colControlCreate to * a new routine colControlBasicCreate because of graph * restructuring changes. * Created: Thu Sep 17 16:13:56 1998 (edgrif) *------------------------------------------------------------------- */ /* $Id: coltest.c,v 1.4 1999/09/01 10:52:15 fw Exp $ */ #include "graph.h" #include "colcontrol.h" /* all per-map-private data goes here */ typedef struct ExampleLook { int from; MAPCONTROL map; } *EXAMPLELOOK; extern struct ProtoStruct exampleColumn; /* forward decl */ static COLPROTO columnsTab[] = { &mapLocatorColumn, &exampleColumn, &mapScaleColumn, 0 }; static COLDEFAULT columnSpec = { { &mapLocatorColumn, TRUE, "Locator" }, { &exampleColumn, TRUE, "Example" }, { &mapScaleColumn, FALSE, "Scale" }, { 0, 0, 0} }; /* scale is initially hidden */ static MENUOPT exampleMenu[] = { graphDestroy, "Quit", 0,0 }; static void exampleDrawHeader(MAPCONTROL map) { controlDrawButtons(map, 5, 0.5, map->control->graphWidth); } main(int argc, char *argv[]) { COLCONTROL control; MAPCONTROL map; EXAMPLELOOK look; graphInit(&argc, argv); control = colControlBasicCreate(FALSE, TEXT_FIT, "example", 0.5, 0.5, 0, 0); map = mapControlCreate(control, 0); /* 2nd param is finalise routine, if reqd */ /* this block is required */ map->prototypes = columnsTab; /* the column types we can display */ /* this block is optional */ map->menu = exampleMenu; /* window menu whenever our map is current */ map->name = "Test"; /* defaults to "" */ map->drawHeader = exampleDrawHeader; /* draw the header */ map->topMargin = 3; /* how much space the header needs */ /* other optional fields: map->beforeDraw called on each map before drawing columns map->headerpick called on click on header area map->convertTrans display list stuff map->keyboard called on current map when key pressed */ /* This memory will evaporate automatically when the map does */ look = (EXAMPLELOOK)handleAlloc(0, map->handle, sizeof(struct ExampleLook)); map->look = look; look->map = map; map->max = 10; map->min = -10; map->centre = 0; controlAddMap(control, map); controlConvertPerm(map); /* make display lists */ controlReadConfig(map, columnSpec); /* column spec says what to make */ look->from = 4; /* highlight box displaying this first */ controlDraw(); /* finally do it */ look->from = 0; /* don't highlight on future draws */ graphLoop (FALSE) ; } /*********************************************************/ /** convert function: may be shared between many columns */ /*********************************************************/ typedef struct DrawCommand { int number; float coord; } *DRAWCOMMAND; static void *exampleConvert(MAPCONTROL map, void *params) { Array dl = arrayHandleCreate(100, struct DrawCommand, map->handle); int i; int disp = 7; /* noddy */ for (i=0; i<10; i++) { DRAWCOMMAND draw = arrayp(dl, i, struct DrawCommand); draw->coord = i; draw->number = disp++; } return dl; } /******************************/ /*** definition of a column ***/ /******************************/ typedef struct ExamplePriv { Array dl; /* drawing list */ int selno; /* number of selected thing */ } * EXAMPLEPRIV; static void exampleDraw(COLINSTANCE instance, float *offset) { EXAMPLEPRIV private = instance->private; MAPCONTROL map = instance->map; COLCONTROL control = map->control; EXAMPLELOOK look = map->look; Array dl = private->dl; int i, ibox; DRAWCOMMAND draw; float y; int max = 0, len; for(i=0; icoord); if (y > control->topMargin && y < control->graphHeight-1) { ibox = graphBoxStart(); array(control->boxIndex, ibox, COLINSTANCE) = instance; /* NB the next line depends on not extending dl after drawing */ array(control->boxIndex2, ibox, void *) = draw; graphText(messprintf("%d", draw->number), *offset, y); len = strlen(messprintf("%d", draw->number)); if (len > max) max = len; graphBoxEnd(); /* this box gets selected */ if (draw->number == look->from) control->fromBox = ibox; } } *offset += max+1; } static BOOL exampleSetSelect(COLINSTANCE instance, int box, double x, double y) /* Called when a box is left clicked. Does no drawing, simply sets up the columns state so that it knows what is selected. Note that the column code keeps track of which instance has the selected box in control->activeInstance */ { EXAMPLEPRIV private = instance->private; COLCONTROL control = instance->map->control; DRAWCOMMAND draw = (DRAWCOMMAND) array(control->boxIndex2, box, void *); private->selno = draw->number; return FALSE; /* return TRUE if re-draw is needed */ } static BOOL exampleUnselect(COLINSTANCE instance, int box) /* Called if a box is unselected, and no re-draw is done, must either fix of the window, or return TRUE for a re-draw. Doesn't need to change select state, the column control does this by zeroing control->activeInstance */ { graphBoxDraw(box, BLACK, WHITE); return FALSE; } static void exampleDoColour(COLINSTANCE instance, int box) /* Called for every box */ { COLCONTROL control = instance->map->control; EXAMPLEPRIV private = instance->private; DRAWCOMMAND draw = (DRAWCOMMAND) array(control->boxIndex2, box, void *); if (control->activeInstance == instance && /* always check this */ private->selno == draw->number) { graphBoxDraw(box, WHITE, RED); control->activeBox = box; /* compulsary */ } } static void exampleFollowBox(COLINSTANCE instance, int box, double x, double y) /* called when selected box is clicked again, intended to open a new display for the double-clicked object */ { COLCONTROL control = instance->map->control; DRAWCOMMAND draw = (DRAWCOMMAND) array(control->boxIndex2, box, void *); messout (" double clicked on box %d", draw->number); } static BOOL exampleCreate(COLINSTANCE instance, OBJ init) /* in non-ACEDB case init is always zero */ { EXAMPLEPRIV private = (EXAMPLEPRIV) handleAlloc(0, instance->handle, sizeof(struct ExamplePriv)); /* this block needed */ instance->draw = exampleDraw; /* this block optional */ instance->private = private; instance->setSelectBox = exampleSetSelect; instance->unSelectBox = exampleUnselect; instance->doColour = exampleDoColour; instance->followBox = exampleFollowBox; /* also allowed here: instance->beforeDraw called before any draw routines instance->configure change config of flexible columns */ /* Powerfull magic to pick up results from our registered convert function */ private->dl = *(instance->proto->convertResults); return TRUE; /* can return FALSE if not possible to create */ } static void exampleButtonPressed(void *arg) { messout ("Ding dong"); } static COLOUROPT exampleButton[] = { exampleButtonPressed, 0, /* 0 is arg to function */ BLACK, WHITE, "A Button", 0 }; static MENUOPT menuOnButton[] = { graphDestroy, "Quit-from-button", 0, 0}; static void exampleInit(MAPCONTROL map, COLCONTROL control) /* called once per prototype from controlAddMap, chief job is to call control addButton*/ { controlAddButton(map, exampleButton, menuOnButton); } struct ProtoStruct exampleColumn = { /* it all links in via here */ exampleInit, /* called from controlAddMap for each prototype */ exampleCreate, /* called to make an instance */ 0, /* becomes finalisation routine for all instance structures */ "example", /* name */ 0, /* void * specialisation, can have two column prototypes identical, except for name and specialisation behave subtly differently access via instance->proto->specialisation in create routine */ FALSE, /* unique, is set only one instance of column allowed */ exampleConvert, /* call this routine for our display list */ 0 /* with this parameter */ };