diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Item.c | 2772 | ||||
-rw-r--r-- | generic/Item.h | 138 |
2 files changed, 239 insertions, 2671 deletions
diff --git a/generic/Item.c b/generic/Item.c index 89656d2..65db502 100644 --- a/generic/Item.c +++ b/generic/Item.c @@ -38,7 +38,9 @@ #include <GL/glu.h> #endif +#include "Field.h" #include "Item.h" +#include "Group.h" #include "Types.h" #include "WidgetInfo.h" #include "Geo.h" @@ -54,101 +56,11 @@ static const char rcsid[] = "$Id$"; static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; -#define FIELD_SENSITIVE_BIT 1 -#define FIELD_VISIBLE_BIT 2 -#define FILLED_BIT 4 -#define TEXT_ON_TOP_BIT 8 -#define CACHE_OK 16 - - static ZnList item_classes = NULL; static ZnList item_stack = NULL; /* - * Field record. - */ -typedef struct _FieldStruct { - /* Public data */ - ZnGradient *color; - ZnGradient *fill_color; - Pixmap fill_pattern; - ZnGradient *border_color; - char *text; - char *image_name; - char *tile_name; - ZnFont font; - unsigned short flags; - Border border_edges; - ZnJustify alignment; - ReliefStyle relief; - ZnDim relief_thickness; - AutoAlign auto_alignment; - - /* Private data */ - ZnImage image; - ZnImage tile; - ZnGradient *gradient; - ZnPoint *grad_geo; - short orig_x; - short orig_y; - short corner_x; - short corner_y; - FieldSet field_set; -#ifdef GLX - TexFont *txf; -#endif -} FieldStruct, *Field; - - -/* - * The -text, -image, -border, -relief, -visible and - * -filled attributes set the ZN_COORDS_FLAG to update - * the leader that might protude if not clipped by the text. - */ -ZnAttrConfig field_attrs[] = { - { ZN_CONFIG_JUSTIFY, "-alignment", NULL, - Tk_Offset(FieldStruct, alignment), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_AUTO_JUSTIFY, "-autoalignment", NULL, - Tk_Offset(FieldStruct, auto_alignment), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-backcolor", NULL, - Tk_Offset(FieldStruct, fill_color), 0, - ZN_DRAW_FLAG|ZN_BORDER_FLAG, False }, - { ZN_CONFIG_BORDER, "-border", NULL, - Tk_Offset(FieldStruct, border_edges), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-bordercolor", NULL, - Tk_Offset(FieldStruct, border_color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_GRADIENT, "-color", NULL, - Tk_Offset(FieldStruct, color), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-filled", NULL, - Tk_Offset(FieldStruct, flags), FILLED_BIT, ZN_COORDS_FLAG, False }, - { ZN_CONFIG_PATTERN, "-fillpattern", NULL, - Tk_Offset(FieldStruct, fill_pattern), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_FONT, "-font", NULL, - Tk_Offset(FieldStruct, font), 0, ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_IMAGE, "-image", NULL, - Tk_Offset(FieldStruct, image_name), 0, - ZN_COORDS_FLAG|ZN_IMAGE_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_RELIEF, "-relief", NULL, - Tk_Offset(FieldStruct, relief), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_DIM, "-reliefthickness", NULL, - Tk_Offset(FieldStruct, relief_thickness), 0, ZN_DRAW_FLAG, False }, - { ZN_CONFIG_BOOL, "-sensitive", NULL, - Tk_Offset(FieldStruct, flags), - FIELD_SENSITIVE_BIT, ZN_REPICK_FLAG, False }, - { ZN_CONFIG_TEXT, "-text", NULL, - Tk_Offset(FieldStruct, text), 0, ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, - { ZN_CONFIG_IMAGE, "-tile", NULL, - Tk_Offset(FieldStruct, tile_name), 0, - ZN_COORDS_FLAG|ZN_TILE_FLAG, False }, - { ZN_CONFIG_BOOL, "-visible", NULL, - Tk_Offset(FieldStruct, flags), FIELD_VISIBLE_BIT, - ZN_COORDS_FLAG|ZN_CLFC_FLAG, False }, /* Keep ZN_COORDS_FLAG here */ - - { ZN_CONFIG_END, NULL, NULL, 0, 0, 0 } -}; - -/* * This array must be kept in sync with the * corresponding defines in Types.h. */ @@ -197,20 +109,9 @@ static char *attribute_type_strings[] = { * ********************************************************************************** */ -static void Damage(WidgetInfo *wi, ZnBBox *damage); static void Invalidate(Item item, int reason); -static int ConfigureField(FieldSet field_set, unsigned int field, - int argc, Tcl_Obj *CONST argv[], int *flags); -static int QueryField(FieldSet field_set, unsigned int field, - int argc, Tcl_Obj *CONST argv[]); -static void AttributeToObj(WidgetInfo *wi, char *record, - ZnAttrConfig *desc, char *buffer, - Tcl_Obj *result); -static void FieldImageChange(ClientData client_data, int x, int y, int width, - int height, int image_width, int image_height); -static void FieldTileChange(ClientData client_data, int x, int y, int width, - int height, int image_width, int image_height); -static void GetLabelBBox(FieldSet field_set, ZnDim *w, ZnDim *h); +static void AttributeToObj(WidgetInfo *wi, void *record, ZnAttrConfig *desc, + char *buffer, Tcl_Obj *result); /* @@ -241,38 +142,16 @@ InitAttrDesc(ZnAttrConfig *attr_desc) * ********************************************************************************** */ -static int -AttributesInfo(Item item, - int field, /* 0< means the item itself. */ - int argc, - Tcl_Obj *CONST args[]) +int +ZnAttributesInfo(WidgetInfo *wi, + void *record, + ZnAttrConfig *desc, + int argc, + Tcl_Obj *CONST args[]) { - WidgetInfo *wi = item->wi; - char *record; - ZnAttrConfig *desc; Tk_Uid attr_uid = NULL; Tcl_Obj *l, *entries[5]; char buffer[256]; - - if (field < 0) { - record = (char *) item; - desc = item->class->attr_desc; - } - else { - FieldSet field_set; - if (!item->class->has_fields) { - Tcl_AppendResult(wi->interp, "item class \"", item->class->name, - "\" doesn't support fields", NULL); - return ZN_ERROR; - } - field_set = item->class->GetFieldSet(item); - if (field >= field_set->num_fields) { - Tcl_AppendResult(wi->interp, "invalid field index \"", NULL); - return ZN_ERROR; - } - record = (char *) &field_set->fields[field]; - desc = field_attrs; - } if (argc == 1) { attr_uid = Tk_GetUid(Tcl_GetString(args[0])); @@ -319,44 +198,24 @@ AttributesInfo(Item item, /* ********************************************************************************** * - * ConfigureAttributes -- + * ZnConfigureAttributes -- * ********************************************************************************** */ -static int -ConfigureAttributes(char *record, - int field, /* 0< means item itself. */ - int argc, - Tcl_Obj *CONST args[], - int *flags) +int +ZnConfigureAttributes(WidgetInfo *wi, + void *record, + ZnAttrConfig *attr_desc, + int argc, + Tcl_Obj *CONST args[], + int *flags) { - WidgetInfo *wi; - Item item = NULL; int i; Tk_Uid attr_uid; ZnAttrConfig *desc; ZnPtr valp; - ZnAttrConfig *attr_desc; - FieldSet field_set = NULL; char *str; - if (field < 0) { - item = (Item) record; - wi = item->wi; - attr_desc = item->class->attr_desc; - } - else { - field_set = (FieldSet) record; - wi = field_set->wi; - if (field >= field_set->num_fields) { - Tcl_AppendResult(wi->interp, "invalid field index \"", NULL); - return ZN_ERROR; - } - record = (char *) &field_set->fields[field]; - /*printf("record <0x%X>, field %d\n", record, field);*/ - attr_desc = field_attrs; - } - for (i = 0; i < argc; i += 2) { attr_uid = Tk_GetUid(Tcl_GetString(args[i])); @@ -375,7 +234,7 @@ ConfigureAttributes(char *record, Tcl_GetString(args[i]), "\" can only be read", NULL); return ZN_ERROR; } - valp = record + desc->offset; + valp = ((char *) record) + desc->offset; /*printf("record <0x%X>, valp <0x%X>, offset %d\n", record, valp, desc->offset);*/ switch (desc->type) { case ZN_CONFIG_COLOR: @@ -595,12 +454,12 @@ ConfigureAttributes(char *record, return ZN_ERROR; } if (*((ZnList *) valp)) { - ITEM.FreeTags(item); + ITEM.FreeTags((Item) record); *flags |= desc->flags; } if (num_tags) { for (j = 0; j < num_tags; j++) { - ITEM.AddTag(item, Tk_GetUid(Tcl_GetString(elems[j]))); + ITEM.AddTag((Item) record, Tk_GetUid(Tcl_GetString(elems[j]))); } *flags |= desc->flags; } @@ -1064,8 +923,9 @@ ConfigureAttributes(char *record, str++; } if (strlen(str) != 0) { + Item item = (Item) record; frmt = LabelFormatCreate(wi->interp, str, - item->class->GetFieldSet(item)->num_fields); + FIELD.NumFields(item->class->GetFieldSet(item))); if (frmt == NULL) { return ZN_ERROR; } @@ -1248,12 +1108,12 @@ ConfigureAttributes(char *record, */ static void AttributeToObj(WidgetInfo *wi, - char *record, + void *record, ZnAttrConfig *desc, char *buffer, Tcl_Obj *result) { - char *valp = record + desc->offset; + char *valp = ((char *) record) + desc->offset; char *str = ""; Tcl_Obj *o; int i; @@ -1580,37 +1440,19 @@ AttributeToObj(WidgetInfo *wi, /* ********************************************************************************** * - * QueryAttribute -- + * ZnQueryAttribute -- * ********************************************************************************** */ -static int -QueryAttribute(char *record, - int field, /* 0< means item itself. */ - Tcl_Obj *attr_name) +int +ZnQueryAttribute(WidgetInfo *wi, + void *record, + ZnAttrConfig *desc, + Tcl_Obj *attr_name) { - WidgetInfo *wi; - Item item; Tk_Uid attr_uid = Tk_GetUid(Tcl_GetString(attr_name)); Tcl_Obj *result = NULL; char buffer[256]; - ZnAttrConfig *desc; - - if (field < 0) { - item = (Item) record; - wi = item->wi; - desc = item->class->attr_desc; - } - else { - FieldSet field_set = (FieldSet) record; - wi = field_set->wi; - if (field >= field_set->num_fields) { - Tcl_AppendResult(wi->interp, "invalid field index \"", NULL); - return ZN_ERROR; - } - record = (char *) &field_set->fields[field]; - desc = field_attrs; - } while (True) { if (desc->type == ZN_CONFIG_END) { @@ -1633,12 +1475,12 @@ QueryAttribute(char *record, /* ********************************************************************************** * - * ItemClassList -- + * ZnItemClassList -- * ********************************************************************************** */ -static ZnList -ItemClassList() +ZnList +ZnItemClassList() { return item_classes; } @@ -1646,12 +1488,12 @@ ItemClassList() /* ********************************************************************************** * - * LookupItemClass -- + * ZnLookupItemClass -- * ********************************************************************************** */ -static ItemClass -LookupItemClass(char *class_name) +ItemClass +ZnLookupItemClass(char *class_name) { ItemClass *class; int i, num_classes; @@ -1670,14 +1512,14 @@ LookupItemClass(char *class_name) /* ********************************************************************************** * - * AddItemClass -- + * ZnAddItemClass -- * ********************************************************************************** */ -static void -AddItemClass(ItemClass class) +void +ZnAddItemClass(ItemClass class) { - if (!LookupItemClass(class->name)) { + if (!ZnLookupItemClass(class->name)) { ZnListAdd(item_classes, &class, ZnListTail); InitAttrDesc(class->attr_desc); } @@ -1686,735 +1528,32 @@ AddItemClass(ItemClass class) /* ********************************************************************************** * - * GlobalModuleInit -- + * ZnItemInit -- * Initialize classes static state. * ********************************************************************************** */ -static void -GlobalModuleInit() +void +ZnItemInit() { /* First check if static part already inited */ if (item_classes == NULL) { item_classes = ZnListNew(16, sizeof(ItemClass)); - AddItemClass(ZnTrack); - AddItemClass(ZnWayPoint); - AddItemClass(ZnMap); - AddItemClass(ZnReticle); - AddItemClass(ZnTabular); - AddItemClass(ZnRectangle); - AddItemClass(ZnArc); - AddItemClass(ZnCurve); - AddItemClass(ZnBezier); - AddItemClass(ZnTriangles); - AddItemClass(ZnGroup); - AddItemClass(ZnIcon); - AddItemClass(ZnText); - AddItemClass(ZnWind); - /*AddItemClass(ZnMosaic);*/ - InitAttrDesc(field_attrs); - } -} - - -/* - ********************************************************************************** - * - * ComputeFieldAttachment -- - * Compute the location/size of the field, computing attachments if any. - * - ********************************************************************************** - */ -static void -ComputeFieldAttachment(FieldSet field_set, - int field, - ZnBBox *field_bbox) -{ - - ZnBBox ref_bbox; - ZnDim real_width, real_height; - int ref_field, num_fields; - char x_attach, y_attach, x_dim, y_dim; - short width_spec, height_spec; - int x_spec, y_spec, icon_width=0, icon_height=0; - Field field_ptr; - Tk_FontMetrics fm; - - field_ptr = &field_set->fields[field]; - if (ISSET(field_ptr->flags, CACHE_OK)) { - field_bbox->orig.x = (ZnPos) field_ptr->orig_x; - field_bbox->orig.y = (ZnPos) field_ptr->orig_y; - field_bbox->corner.x = field_ptr->corner_x; - field_bbox->corner.y = field_ptr->corner_y; - return; - } - - /* - * Preset this field to a default position/size and pretend - * its cache is ok to break any deadlocks. - */ - field_ptr->orig_x = field_ptr->orig_y = 0; - field_ptr->corner_x = field_ptr->corner_y = 0; - field_bbox->orig.x = field_bbox->orig.y = 0; - field_bbox->corner.x = field_bbox->corner.y = 0; - SET(field_ptr->flags, CACHE_OK); - - num_fields = LabelFormatNumFields(field_set->label_format); - LabelFormatGetField(field_set->label_format, field, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - - /* - * First try to compute the field size which may be a factor - * of the field content (but not a factor of other fields). - */ - if ((field_ptr->image != ZnUnspecifiedImage) && - ((x_dim == LF_DIM_ICON) || (y_dim == LF_DIM_ICON) || - (x_dim == LF_DIM_AUTO) || (y_dim == LF_DIM_AUTO))) { - Tk_SizeOfImage(field_ptr->image, &icon_width, &icon_height); - } - - switch (x_dim) { - case LF_DIM_FONT: - real_width = (ZnDim) (width_spec*ZnTextWidth(field_ptr->font, "N", 1)/100); - break; - case LF_DIM_ICON: - real_width = (ZnDim) (width_spec*icon_width/100); - break; - case LF_DIM_AUTO: - { - int len = strlen(field_ptr->text); - ZnDim text_width; - - real_width = 0.0; - if (field_ptr->image != ZnUnspecifiedImage) { - real_width = (ZnDim) icon_width; - } - if (len) { - /* - * The 4 extra pixels are needed for border and padding. - */ - text_width = (ZnDim) ZnTextWidth(field_ptr->font, field_ptr->text, len) + 4; - real_width = text_width < real_width ? real_width : text_width; - } - real_width += (ZnDim) width_spec; - break; - } - case LF_DIM_LABEL: - { - ZnDim lh; - - GetLabelBBox(field_set, &real_width, &lh); - break; - } - case LF_DIM_PIXEL: - default: - real_width = (ZnDim) width_spec; - break; - } - /*printf("field %d, width = %g\n", field, real_width);*/ - - switch (y_dim) { - case LF_DIM_FONT: - { - Tk_GetFontMetrics(field_ptr->font, &fm); - real_height = (ZnDim) (height_spec*(fm.ascent + fm.descent)/100); - break; - } - case LF_DIM_ICON: - real_height = (ZnDim) (height_spec*icon_height/100); - break; - case LF_DIM_AUTO: - { - ZnDim text_height; - - real_height = 0.0; - if (field_ptr->image != ZnUnspecifiedImage) { - real_height = (ZnDim) icon_height; - } - if (strlen(field_ptr->text)) { - Tk_GetFontMetrics(field_ptr->font, &fm); - text_height = (ZnDim) (fm.ascent + fm.descent); - real_height = text_height < real_height ? real_height : text_height; - } - real_height += (ZnDim) height_spec; - break; - } - case LF_DIM_LABEL: - { - ZnDim lw; - - GetLabelBBox(field_set, &lw, &real_height); - break; - } - case LF_DIM_PIXEL: - default: - real_height = (ZnDim) height_spec; - break; - } - /*printf("field %d, height = %g\n", field, real_height);*/ - - /* - * Update the cache with the newly computed infos - * (breaking of deadlocks). - */ - field_bbox->corner.x = field_ptr->corner_x = real_width; - field_bbox->corner.y = field_ptr->corner_y = real_height; - - /* - * Then try to deduce the position, resolving any attachments - * if needed. - */ - - /* - * Do the x axis. - */ - if (x_dim != LF_DIM_LABEL) { - if (x_attach == LF_ATTACH_PIXEL) { - field_bbox->orig.x = (ZnPos) x_spec; - field_bbox->corner.x = field_bbox->orig.x + real_width; - } - else { - ref_field = x_spec; - field_bbox->orig.x = field_bbox->corner.x = 0; - if ((ref_field < 0) || (ref_field >= num_fields)) { - ZnWarning ("Attached (x) to an inexistant field geometry\n"); - } - else { - ComputeFieldAttachment(field_set, ref_field, &ref_bbox); - switch (x_attach) { - case LF_ATTACH_FWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->orig.x = ref_bbox.corner.x; - } - else { - field_bbox->orig.x = ref_bbox.orig.x; - } - field_bbox->corner.x = field_bbox->orig.x + real_width; - break; - case LF_ATTACH_BWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.x = ref_bbox.orig.x; - } - else { - field_bbox->corner.x = ref_bbox.corner.x; - } - field_bbox->orig.x = field_bbox->corner.x - real_width; - break; - case LF_ATTACH_LEFT: - field_bbox->orig.x = ref_bbox.orig.x; - field_bbox->corner.x = field_bbox->orig.x + real_width; - break; - case LF_ATTACH_RIGHT: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.x = ref_bbox.corner.x; - } - else { - field_bbox->corner.x = ref_bbox.orig.x; - } - field_bbox->orig.x = field_bbox->corner.x - real_width; - break; - } - } - } - /*printf("field %d, x = %g\n", field, field_bbox->orig.x);*/ - } - - /* - * Then the y axis. - */ - if (y_dim != LF_DIM_LABEL) { - if (y_attach == LF_ATTACH_PIXEL) { - field_bbox->orig.y = (ZnPos) y_spec; - field_bbox->corner.y = field_bbox->orig.y + real_height; - } - else { - ref_field = y_spec; - field_bbox->orig.y = field_bbox->corner.y = 0; - if ((ref_field < 0) || (ref_field >= num_fields)) { - ZnWarning ("Attached (y) to an inexistant field geometry\n"); - } - else { - ComputeFieldAttachment(field_set, ref_field, &ref_bbox); - switch (y_attach) { - case LF_ATTACH_FWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->orig.y = ref_bbox.corner.y; - } - else { - field_bbox->orig.y = ref_bbox.orig.y; - } - field_bbox->corner.y = field_bbox->orig.y + real_height; - break; - case LF_ATTACH_BWD: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.y = ref_bbox.orig.y; - } - else { - field_bbox->corner.y = ref_bbox.corner.y; - } - field_bbox->orig.y = field_bbox->corner.y - real_height; - break; - case LF_ATTACH_LEFT: - field_bbox->orig.y = ref_bbox.orig.y; - field_bbox->corner.y = field_bbox->orig.y + real_height; - break; - case LF_ATTACH_RIGHT: - if (ISSET(field_set->fields[ref_field].flags, FIELD_VISIBLE_BIT)) { - field_bbox->corner.y = ref_bbox.corner.y; - } - else { - field_bbox->corner.y = ref_bbox.orig.y; - } - field_bbox->orig.y = field_bbox->corner.y - real_height; - break; - } - } - } - /*printf("field %d, y = %g\n", field, field_bbox->orig.y);*/ - } - - field_ptr->orig_x = (short) field_bbox->orig.x; - field_ptr->orig_y = (short) field_bbox->orig.y; - field_ptr->corner_x = (short) field_bbox->corner.x; - field_ptr->corner_y = (short) field_bbox->corner.y; - SET(field_ptr->flags, CACHE_OK); -} - - -/* - ********************************************************************************** - * - * ClearFieldCache -- - * Reset the geometric cache of all fields depending on a given field (or - * of all fields if the field is < 0). Clear also the label bounding box - * cache if some action has been taken on a field. - * - ********************************************************************************** - */ -void -ClearFieldCache(FieldSet field_set, - int field) -{ - int i, num_fields; - ZnBool clear_bbox; - int x_spec, y_spec; - char x_attach, y_attach, x_dim, y_dim; - short width_spec, height_spec; - - if (field < 0) { - for (i = 0; i < field_set->num_fields; i++) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - } - field_set->label_width = field_set->label_height = -1.0; - return; - } - - clear_bbox = False; - if (!field_set->label_format) { - return; - } - num_fields = LabelFormatNumFields(field_set->label_format); - if (field >= num_fields) { - return; - } - LabelFormatGetField(field_set->label_format, field, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - if ((x_dim != LF_DIM_PIXEL) || (y_dim != LF_DIM_PIXEL)) { - CLEAR(field_set->fields[field].flags, CACHE_OK); - clear_bbox = True; - } - for (i = 0; i < num_fields; i++) { - LabelFormatGetField(field_set->label_format, i, - &x_attach, &y_attach, &x_dim, &y_dim, - &x_spec, &y_spec, &width_spec, &height_spec); - if ((x_attach == LF_ATTACH_PIXEL) && (y_attach == LF_ATTACH_PIXEL)) { - continue; - } - if (x_attach != LF_ATTACH_PIXEL) { - if ((x_spec == field) && ISSET(field_set->fields[i].flags, CACHE_OK)) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - ClearFieldCache(field_set, i); - clear_bbox = True; - } - } - if (y_attach != LF_ATTACH_PIXEL) { - if ((y_spec == field) && ISSET(field_set->fields[i].flags, CACHE_OK)) { - CLEAR(field_set->fields[i].flags, CACHE_OK); - ClearFieldCache(field_set, i); - clear_bbox = True; - } - } - } - - if (clear_bbox) { - field_set->label_width = field_set->label_height = -1.0; - } -} - - -/* - ********************************************************************************** - * - * GetLabelBBox -- - * - ********************************************************************************** - */ -void -GetLabelBBox(FieldSet field_set, - ZnDim *w, - ZnDim *h) -{ - ZnBBox bbox, tmp_bbox; - ZnLabelFormat lf; - int i, num_fields; - ZnDim clip_w, clip_h; - - if ((field_set->label_width >= 0.0) && (field_set->label_height >= 0.0)) { - *w = field_set->label_width; - *h = field_set->label_height; - return; - } - - lf = field_set->label_format; - if (lf == NULL) { - *w = *h = field_set->label_width = field_set->label_height = 0.0; - return; - } - - ResetBBox(&bbox); - num_fields = LabelFormatNumFields(lf); - for (i = 0; i < num_fields; i++) { - ComputeFieldAttachment(field_set, i, &tmp_bbox); - /*printf("field %d bbox %g %g %g %g\n", i, tmp_bbox.orig.x, tmp_bbox.orig.y, - tmp_bbox.corner.x, tmp_bbox.corner.y);*/ - AddBBoxToBBox(&bbox, &tmp_bbox); - } - field_set->label_width = bbox.corner.x; - field_set->label_height = bbox.corner.y; - - /*printf("GetLabelBBox size before clipping; w = %g, h = %g\n", - field_set->label_width, field_set->label_height);*/ - if (LabelFormatGetClipBox(lf, &clip_w, &clip_h)) { - if (clip_w < field_set->label_width) { - field_set->label_width = clip_w; - } - if (clip_h < field_set->label_height) { - field_set->label_height = clip_h; - } - } - - *w = field_set->label_width; - *h = field_set->label_height; - /*printf("GetLabelBBox returns computed size; w = %g, h = %g\n", *w, *h);*/ -} - - -/* - ********************************************************************************** - * - * GetFieldBBox -- - * Compute the location of the field described - * by the field entry index in the item current LabelFormat. - * - ********************************************************************************** - */ -static void -GetFieldBBox(FieldSet field_set, - unsigned int index, - ZnBBox *field_bbox) -{ - ZnReal ox, oy; - - if (field_set->label_format) { - ox = REAL_TO_INT(field_set->label_pos.x); - oy = REAL_TO_INT(field_set->label_pos.y); - ComputeFieldAttachment(field_set, index, field_bbox); - field_bbox->orig.x += ox; - field_bbox->orig.y += oy; - field_bbox->corner.x += ox; - field_bbox->corner.y += oy; - } - else { - ResetBBox(field_bbox); - } -} - - -/* - ********************************************************************************** - * - * ComputeFieldTextLocation -- - * Compute the position of the text in a field. This is a position - * that we can give to XDrawText. The position is deduced from the - * field bounding box passed in bbox. - * Return also the text bounding box. - * - ********************************************************************************** - */ -static void -ComputeFieldTextLocation(Field field_ptr, - ZnBBox *bbox, - ZnPoint *pos, - ZnBBox *text_bbox) -{ - ZnDim w, h; - Tk_FontMetrics fm; - - Tk_GetFontMetrics(field_ptr->font, &fm); - w = ZnTextWidth(field_ptr->font, field_ptr->text, strlen(field_ptr->text)); - h = fm.ascent + fm.descent; - text_bbox->orig.y = (bbox->orig.y + bbox->corner.y - h) / 2.0; - text_bbox->corner.y = text_bbox->orig.y + h; - pos->y = text_bbox->orig.y + fm.ascent; - - switch (field_ptr->alignment) { - case ZnJustifyLeft: - text_bbox->orig.x = bbox->orig.x + 2; - break; - case ZnJustifyRight: - text_bbox->orig.x = bbox->corner.x - w - 2; - break; - default: - text_bbox->orig.x = (bbox->orig.x + bbox->corner.x - w) / 2.0; - break; - } - text_bbox->corner.x = text_bbox->orig.x + w; - pos->x = text_bbox->orig.x; -} - - -/* - ********************************************************************************** - * - * LeaderToLabel -- - * Compute the segment part of segment <start, end> that lies - * outside the fields of item. - * - ********************************************************************************** - */ -static void -LeaderToLabel(FieldSet field_set, - ZnPoint *start, - ZnPoint *end) -{ - int b_num; - ZnPoint delta, inf, sup; - ZnPos xt=0, yu=0, yw=0, xv=0; - Field field_ptr; - int i; - ZnBBox field_bbox; - - /* Intersection points : */ - /* T |xt / delta_y U |x1 V |y1 W |yw / delta_x */ - /* |y2 |yu / delta_x |xv / delta_y |x2 */ - /* */ - /* y = ax + b; */ - /* a = delta_y / delta_x */ - /* b = (y * delta_x - x * delta_y) / delta_x */ - - delta.x = start->x - end->x; - delta.y = start->y - end->y; - b_num = start->y*delta.x - start->x*delta.y; - - for (i = 0; i < LabelFormatNumFields(field_set->label_format); i++) { - field_ptr = &field_set->fields[i]; - /* - * If the field is made invisible or has no graphics of - * its own, don't clip. - */ - if (ISCLEAR(field_ptr->flags, FIELD_VISIBLE_BIT) || - ((*field_ptr->text == 0) && - ISCLEAR(field_ptr->flags, FILLED_BIT) && - (field_ptr->border_edges == NO_BORDER) && - (field_ptr->relief == RELIEF_FLAT) && - (field_ptr->image == ZnUnspecifiedImage))) { - continue; - } - - /* - * field_bbox is in absolute device coordinates. - */ - GetFieldBBox(field_set, i, &field_bbox); - - /* - * Adjust leader on real text, not on field boundaries. This is - * important when there are leading and trailing spaces. - * The correct test here is really *field_ptr->text, an empty - * text is represented by an empty string NOT by a NULL pointer. - */ - if (*field_ptr->text && ISCLEAR(field_ptr->flags, FILLED_BIT) && - (field_ptr->border_edges == NO_BORDER) && - (field_ptr->relief == RELIEF_FLAT) && - (field_ptr->image == ZnUnspecifiedImage)) { - ZnBBox text_bbox; - ZnPoint text_pos; /* dummy */ - int space_width; - int scan_forw, scan_back; - space_width = ZnTextWidth(field_ptr->font, " ", 1); - - ComputeFieldTextLocation(field_ptr, &field_bbox, &text_pos, &text_bbox); - /* - * Correct adjusments made by ComputeFieldTextLocation (Vincent Pomey). - * - * PLC: IMHO, this is to compensate for exotic fonts like 'symbolesATC'. - * I am not planning to port this to Tk for two reasons: - * 1/ Current positions are no longer implemented as characters - * and 2/ Tk does not give access (easily) to lbearings and rbearings. - * This patch has been contributed by Phidias team. I don't know the - * problem it was meant to solve. - * text_bbox.x -= field_ptr->font->per_char[field_ptr->text[0]].lbearing + 3; - * text_bbox.width += field_ptr->font->per_char[field_ptr->text[0]].lbearing + 3; - */ - /* - * Change bbox according to leading and trailing spaces. - */ - scan_forw = 0; - while (field_ptr->text[scan_forw] == ' ') { - /* leading spaces */ - text_bbox.orig.x += space_width; - scan_forw++; - } - - /* - * Empty text. - */ - if (field_ptr->text[scan_forw] == 0) { - continue; - } - - scan_back = strlen(field_ptr->text)-1; - while ((field_ptr->text[scan_back] == ' ') && (scan_back > scan_forw)) { - /* trailing spaces */ - text_bbox.corner.x -= space_width; - scan_back--; - } - - field_bbox = text_bbox; - } - - if (field_bbox.corner.x <= field_bbox.orig.x) { - continue; - } - - if ((start->x >= field_bbox.orig.x) && (start->x < field_bbox.corner.x) && - (start->y >= field_bbox.orig.y) && (start->y < field_bbox.corner.y)) { - end->x = start->x; - end->y = start->y; - } - if (delta.x) { - yu = (field_bbox.orig.x*delta.y + b_num) / delta.x; - yw = (field_bbox.corner.x*delta.y + b_num) / delta.x; - } - if (delta.y) { - xt = (field_bbox.corner.y*delta.x - b_num) / delta.y; - xv = (field_bbox.orig.y*delta.x - b_num) / delta.y; - } - - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - - if (delta.x) { - if ((yu >= field_bbox.orig.y) && (yu <= field_bbox.corner.y) && - (field_bbox.orig.x >= inf.x) && (field_bbox.orig.x <= sup.x) && - (yu >= inf.y) && (yu <= sup.y)) { - end->x = field_bbox.orig.x; - end->y = yu; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - if ((yw >= field_bbox.orig.y) && (yw <= field_bbox.corner.y) && - (field_bbox.corner.x >= inf.x) && (field_bbox.corner.x <= sup.x) && - (yw >= inf.y) && (yw <= sup.y)) { - end->x = field_bbox.corner.x; - end->y = yw; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - } - if (delta.y) { - if ((xt >= field_bbox.orig.x) && (xt <= field_bbox.corner.x) && - (xt >= inf.x) && (xt <= sup.x) && - (field_bbox.corner.y >= inf.y) && (field_bbox.corner.y <= sup.y)) { - end->x = xt; - end->y = field_bbox.corner.y; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - if ((xv >= field_bbox.orig.x) && (xv <= field_bbox.corner.x) && - (xv >= inf.x) && (xv <= sup.x) && - (field_bbox.orig.y >= inf.y) && (field_bbox.orig.y <= sup.y)) { - end->x = xv; - end->y = field_bbox.orig.y; - inf.x = MIN(start->x, end->x); - sup.x = MAX(start->x, end->x); - inf.y = MIN(start->y, end->y); - sup.y = MAX(start->y, end->y); - } - } - } -} - - -/* - ********************************************************************************** - * - * InsertDependentItem -- - * - ********************************************************************************** - */ -static void -InsertDependentItem(Item item) -{ - GroupItem group = (GroupItem) item->parent; - - if (!group) { - return; - } - if (!group->dependents) { - group->dependents = ZnListNew(2, sizeof(Item)); - } - ZnListAdd(group->dependents, &item, ZnListTail); -} - - -/* - ********************************************************************************** - * - * ExtractDependentItem -- - * - ********************************************************************************** - */ -static void -ExtractDependentItem(Item item) -{ - GroupItem group = (GroupItem) item->parent; - int index, num_items; - Item *deps; - - if (!group || !group->dependents) { - return; - } - num_items = ZnListSize(group->dependents); - deps = (Item *) ZnListArray(group->dependents); - for (index = 0; index < num_items; index++) { - if (deps[index]->id == item->id) { - ZnListDelete(group->dependents, index); - if (ZnListSize(group->dependents) == 0) { - ZnListFree(group->dependents); - group->dependents = NULL; - break; - } - } + ZnAddItemClass(ZnTrack); + ZnAddItemClass(ZnWayPoint); + ZnAddItemClass(ZnMap); + ZnAddItemClass(ZnReticle); + ZnAddItemClass(ZnTabular); + ZnAddItemClass(ZnRectangle); + ZnAddItemClass(ZnArc); + ZnAddItemClass(ZnCurve); + ZnAddItemClass(ZnBezier); + ZnAddItemClass(ZnTriangles); + ZnAddItemClass(ZnGroup); + ZnAddItemClass(ZnIcon); + ZnAddItemClass(ZnText); + ZnAddItemClass(ZnWind); + InitAttrDesc(FIELD.attr_desc); } } @@ -2422,7 +1561,7 @@ ExtractDependentItem(Item item) /* ********************************************************************************** * - * UpdateItemDependency -- + * UpdateItemDependency -- Method * Update the group dependency list following a change in the * connection of an item. * @@ -2434,18 +1573,18 @@ UpdateItemDependency(Item item, { if (old_connection == ZN_NO_ITEM) { /* Add a connection */ - InsertDependentItem(item); + ZnInsertDependentItem(item); } else if (item->connected_item == ZN_NO_ITEM) { /* Remove a connection */ - ExtractDependentItem(item); + ZnExtractDependentItem(item); } else { /* Move at end to ensure that it will be updated after * the (new) item it depends upon. */ - ExtractDependentItem(item); - InsertDependentItem(item); + ZnExtractDependentItem(item); + ZnInsertDependentItem(item); } } @@ -2453,36 +1592,45 @@ UpdateItemDependency(Item item, /* ********************************************************************************** * - * DisconnectDependentItems -- - * + * ExtractItem -- + * Extract an item from its context, includes updating graphic + * state flags. * ********************************************************************************** */ static void -DisconnectDependentItems(Item item) +ExtractItem(Item item) { - Item current_item; - GroupItem group = (GroupItem) item->parent; - Item *deps; - int num_deps, i; - - if (!group || !group->dependents) { - return; + WidgetInfo *wi = item->wi; + Item group = item->parent; + + /* damage bounding boxes */ + if (ISSET(item->flags, VISIBLE_BIT)) { + ZnDamage(wi, &item->item_bounding_box); + ZnNeedRedisplay(wi); } - deps = (Item *) ZnListArray(group->dependents); - num_deps = ZnListSize(group->dependents); - for (i = num_deps-1; i >= 0; i--) { - current_item = deps[i]; - if (current_item->connected_item == item) { - current_item->connected_item = ZN_NO_ITEM; - ZnListDelete(group->dependents, i); - Invalidate(current_item, ZN_COORDS_FLAG); - } + /* + * Tell that we need to repick + */ + if (item->class != ZnGroup) { + SET(wi->events_flags, INTERNAL_NEED_REPICK); } - if (ZnListSize(group->dependents) == 0) { - ZnListFree(group->dependents); - group->dependents = NULL; + + if (group != ZN_NO_ITEM) { + /* Remove me from dependency list. */ + ZnExtractDependentItem(item); + + /* Disconnect all dependents on me. */ + ZnDisconnectDependentItems(item); + /* + * Remove me from item list. + */ + ZnGroupExtractItem(item); + /* + * Remove me as a clip item. + */ + ZnGroupRemoveClip(group, item); } } @@ -2490,7 +1638,7 @@ DisconnectDependentItems(Item item) /* ********************************************************************************** * - * InsertItem -- + * InsertItem -- Method * * Insert an item in the display list according to its priority. * It is inserted in front of items of lower or same priority. If @@ -2506,131 +1654,23 @@ InsertItem(Item item, Item mark_item, ZnBool before) { - WidgetInfo *wi = item->wi; - GroupItem group = (GroupItem) grp; - - if (!group) { - group = (GroupItem) wi->top_group; + if (!grp) { + grp = item->wi->top_group; } - item->parent = (Item) group; + item->parent = grp; - if (mark_item && (mark_item->parent != (Item) group)) { + if (mark_item && (mark_item->parent != grp)) { mark_item = ZN_NO_ITEM; } - /* - * Empty list, add the first item. - */ - if (group->head == ZN_NO_ITEM) { - group->head = item; - group->tail = item; - item->previous = item->next = ZN_NO_ITEM; - return; - } - - if (mark_item != ZN_NO_ITEM) { - /* - * Better leave here, mark_item will not - * have the links set right. - */ - if (mark_item == item) { - return; - } - /* - * Force the priority to be the same as the reference - * item; - */ - item->priority = mark_item->priority; - } - else { - mark_item = group->head; - while ((mark_item != ZN_NO_ITEM) && - (mark_item->priority > item->priority)) { - mark_item = mark_item->next; - } - before = True; - } - - if (before && (mark_item != ZN_NO_ITEM)) { - /* - * Insert before mark. - */ - item->next = mark_item; - item->previous = mark_item->previous; - if (mark_item->previous == ZN_NO_ITEM) { - group->head = item; - } - else { - mark_item->previous->next = item; - } - mark_item->previous = item; - } - else { - /* - * Insert after mark either because 'before' is False - * and mark_item valid or because the right place is at - * the end of the list and mark_item is ZN_NO_ITEM. - */ - if (mark_item == ZN_NO_ITEM) { - group->tail->next = item; - item->previous = group->tail; - group->tail = item; - } - else { - item->previous = mark_item; - item->next = mark_item->next; - if (item->next == ZN_NO_ITEM) { - group->tail = item; - } - else { - item->next->previous = item; - } - mark_item->next = item; - } - } -} - - -/* - ********************************************************************************** - * - * ExtractItem -- - * - ********************************************************************************** - */ -static void -ExtractItem(Item item) -{ - GroupItem group; - - if (!item->parent) { - return; - } - group = (GroupItem) item->parent; - - if (item->previous != ZN_NO_ITEM) { - item->previous->next = item->next; - } - else { - group->head = item->next; - } - if (item->next != ZN_NO_ITEM) { - item->next->previous = item->previous; - } - else { - group->tail = item->previous; - } - - item->previous = ZN_NO_ITEM; - item->next = ZN_NO_ITEM; - item->parent = NULL; + ZnGroupInsertItem(grp, item, mark_item, before); } /* ********************************************************************************** * - * UpdateItemPriority -- + * UpdateItemPriority -- Method * Reorder a group's item list following a change in an * item priority or a call to lower/raise. * @@ -2643,7 +1683,7 @@ UpdateItemPriority(Item item, { Item parent = item->parent; - ExtractItem(item); + ZnGroupExtractItem(item); InsertItem(item, parent, mark_item, before); Invalidate(item, ZN_DRAW_FLAG); SET(item->wi->events_flags, INTERNAL_NEED_REPICK); @@ -2654,7 +1694,7 @@ UpdateItemPriority(Item item, ********************************************************************************** * * SetId, - * FreeId -- + * FreeId -- Method * Get a fresh object id from the widget and enter the new * object with this id in the object hash table. The id is * incremented. FreeId on the other hand suppress the item @@ -2692,7 +1732,7 @@ FreeId(Item item) /* ********************************************************************************** * - * AddTag -- + * AddTag -- Method * Add a tag to the item. If the tag is already on the list it * is not added. As a side effect the tag/item pair is added to * the tag table of the widget. @@ -2734,7 +1774,7 @@ AddTag(Item item, /* ********************************************************************************** * - * RemoveTag -- + * RemoveTag -- Method * ********************************************************************************** */ @@ -2766,7 +1806,7 @@ RemoveTag(Item item, /* ********************************************************************************** * - * FreeTags -- + * FreeTags -- Method * ********************************************************************************** */ @@ -2784,7 +1824,7 @@ FreeTags(Item item) /* ********************************************************************************** * - * CreateItem -- + * ZnCreateItem -- * * InsertItem and ConfigureItem must be called after CreateItem * to finalize the setup of a new item. This is so even if @@ -2794,15 +1834,15 @@ FreeTags(Item item) * ********************************************************************************** */ -static Item -CreateItem(WidgetInfo *wi, - ItemClass item_class, - int *argc, - Tcl_Obj *CONST *args[]) +Item +ZnCreateItem(WidgetInfo *wi, + ItemClass item_class, + int *argc, + Tcl_Obj *CONST *args[]) { Item item; - item = (Item) ZnMalloc(item_class->item_size); + item = (Item) ZnMalloc(item_class->size); /* Initialize common state */ item->class = item_class; @@ -2837,7 +1877,7 @@ CreateItem(WidgetInfo *wi, /* ********************************************************************************** * - * CloneItem -- + * CloneItem -- Method * Can't clone the top level group. * ********************************************************************************** @@ -2854,8 +1894,8 @@ CloneItem(Item model) return ZN_NO_ITEM; } - item = (Item) ZnMalloc(model->class->item_size); - memcpy(item, model, model->class->item_size); + item = (Item) ZnMalloc(model->class->size); + memcpy(item, model, model->class->size); item->previous = ZN_NO_ITEM; item->next = ZN_NO_ITEM; @@ -2890,7 +1930,7 @@ CloneItem(Item model) /* ********************************************************************************** * - * ConfigureItem -- + * ConfigureItem -- Method * ********************************************************************************** */ @@ -2913,12 +1953,12 @@ ConfigureItem(Item item, return ZN_ERROR; } if (item->class->has_fields && ISSET(flags, ZN_CLFC_FLAG)) { - ClearFieldCache(item->class->GetFieldSet(item), -1); + FIELD.ClearFieldCache(item->class->GetFieldSet(item), -1); } } else if (item->class->has_fields) { - FieldSet field_set = item->class->GetFieldSet(item); - if (ConfigureField(field_set, field, argc, argv, &flags) == ZN_ERROR) { + if (FIELD.ConfigureField(item->class->GetFieldSet(item), + field, argc, argv, &flags) == ZN_ERROR) { return ZN_ERROR; } } @@ -2932,7 +1972,7 @@ ConfigureItem(Item item, * Special case when the item has its visibility * just turned out. */ - Damage(wi, &item->item_bounding_box); + ZnDamage(wi, &item->item_bounding_box); ZnNeedRedisplay(wi); } @@ -2945,7 +1985,7 @@ ConfigureItem(Item item, /* ********************************************************************************** * - * QueryItem -- + * QueryItem -- Method * ********************************************************************************** */ @@ -2959,8 +1999,8 @@ QueryItem(Item item, return item->class->Query(item, argc, argv); } else if (item->class->has_fields) { - FieldSet field_set = item->class->GetFieldSet(item); - return QueryField(field_set, field, argc, argv); + return FIELD.QueryField(item->class->GetFieldSet(item), + field, argc, argv); } return ZN_ERROR; @@ -3028,7 +2068,7 @@ ComposeTransform(ZnTransfo *transfo, /* ********************************************************************************** * - * GetItemTransform -- + * GetItemTransform -- Method * Compute the current transform for an item. * ********************************************************************************** @@ -3075,41 +2115,41 @@ GetItemTransform(Item item, /* ********************************************************************************** * - * ResetTransformStack - * InitTransformStack - * FreeTransformStack - * CurrentTransform - * PushTransform - * PopTransform -- + * ZnResetTransformStack + * ZnInitTransformStack + * ZnFreeTransformStack + * ZnCurrentTransform + * ZnPushTransform + * ZnPopTransform -- * ********************************************************************************** */ -static void -ResetTransformStack(WidgetInfo *wi) +void +ZnResetTransformStack(WidgetInfo *wi) { ZnListAssertSize(wi->transfo_stack, 1); wi->current_transfo = (ZnTransfo *) ZnListAt(wi->transfo_stack, 0); ZnTransfoSetIdentity(wi->current_transfo); } -static void -InitTransformStack(WidgetInfo *wi) +void +ZnInitTransformStack(WidgetInfo *wi) { wi->transfo_stack = ZnListNew(8, sizeof(ZnTransfo)); - ResetTransformStack(wi); + ZnResetTransformStack(wi); } -static void -FreeTransformStack(WidgetInfo *wi) +void +ZnFreeTransformStack(WidgetInfo *wi) { ZnListFree(wi->transfo_stack); } -static void -PushTransform(WidgetInfo *wi, - ZnTransfo *transfo, - ZnBool compose_scale, - ZnBool compose_rot) +void +ZnPushTransform(WidgetInfo *wi, + ZnTransfo *transfo, + ZnBool compose_scale, + ZnBool compose_rot) { ZnTransfo *next_t; int num_t; @@ -3127,8 +2167,8 @@ PushTransform(WidgetInfo *wi, wi->current_transfo = next_t; } -static void -PopTransform(WidgetInfo *wi) +void +ZnPopTransform(WidgetInfo *wi) { /* * Restore the previous transform. @@ -3141,12 +2181,12 @@ PopTransform(WidgetInfo *wi) /* ********************************************************************************** * - * ResetClipStack - * InitClipStack - * FreeClipStack - * CurrentClip - * PushClip - * PopClip -- + * ZnResetClipStack + * ZnInitClipStack + * ZnFreeClipStack + * ZnCurrentClip + * ZnPushClip + * ZnPopClip -- * ********************************************************************************** */ @@ -3161,8 +2201,8 @@ typedef struct _ClipState { ZnBBox clip_box; /* The bounding box of the clip area. */ } ClipState; -static void -ResetClipStack(WidgetInfo *wi) +void +ZnResetClipStack(WidgetInfo *wi) { int i; ClipState *clips = (ClipState *) ZnListArray(wi->clip_stack); @@ -3178,24 +2218,24 @@ ResetClipStack(WidgetInfo *wi) wi->current_clip = NULL; } -static void -InitClipStack(WidgetInfo *wi) +void +ZnInitClipStack(WidgetInfo *wi) { wi->clip_stack = ZnListNew(8, sizeof(ClipState)); - ResetClipStack(wi); + ZnResetClipStack(wi); } -static void -FreeClipStack(WidgetInfo *wi) +void +ZnFreeClipStack(WidgetInfo *wi) { ZnListFree(wi->clip_stack); } -static ZnBool -CurrentClip(WidgetInfo *wi, - Region *reg, - ZnBBox **clip_box, - ZnBool *simple) +ZnBool +ZnCurrentClip(WidgetInfo *wi, + Region *reg, + ZnBBox **clip_box, + ZnBool *simple) { if (wi->current_clip) { if (reg) { @@ -3218,11 +2258,11 @@ CurrentClip(WidgetInfo *wi, * array of two points. In the other case it * is a regular pointer to a multi contour poly. */ -static void -PushClip(WidgetInfo *wi, - ZnTriStrip *tristrip, - ZnBool simple, - ZnBool set_gc) +void +ZnPushClip(WidgetInfo *wi, + ZnTriStrip *tristrip, + ZnBool simple, + ZnBool set_gc) { int i, j, num_clips; int num_pts, max_num_pts; @@ -3384,9 +2424,9 @@ PushClip(WidgetInfo *wi, } } -static void -PopClip(WidgetInfo *wi, - ZnBool set_gc) +void +ZnPopClip(WidgetInfo *wi, + ZnBool set_gc) { int num_clips; @@ -3458,7 +2498,7 @@ PopClip(WidgetInfo *wi, /* ********************************************************************************** * - * Invalidate -- + * Invalidate -- Method * ********************************************************************************** */ @@ -3494,7 +2534,7 @@ Invalidate(Item item, else if (ISSET(reason, ZN_DRAW_FLAG)) { if (ISSET(item->flags, VISIBLE_BIT)) { /*printf("invalidate graphics for item %d\n", item->id);*/ - Damage(item->wi, &item->item_bounding_box); + ZnDamage(item->wi, &item->item_bounding_box); ZnNeedRedisplay(item->wi); } } @@ -3504,7 +2544,7 @@ Invalidate(Item item, /* ********************************************************************************** * - * InvalidateItems -- + * InvalidateItems -- Method * Invalidate the geometric state of all items belonging * to a given class. The search for items starts at group * and proceed depth first. @@ -3520,7 +2560,7 @@ InvalidateItems(Item group, if (group->class != ZnGroup) { return; } - item = ((GroupItem) group)->head; + item = ZnGroupHead(group); while (item != ZN_NO_ITEM) { if (item->class == item_class) { Invalidate(item, ZN_COORDS_FLAG); @@ -3540,7 +2580,7 @@ InvalidateItems(Item group, * SetTransfo * TranslateItem * ScaleItem - * RotateItem -- + * RotateItem -- Methods * Set of functions that deal with item transform. They take care * of all details including managing NULL transforms and invalidating * the item hierarchy. @@ -3624,60 +2664,7 @@ RotateItem(Item item, /* ********************************************************************************** * - * RemoveItem -- - * Extract an item from its context, includes updating graphic - * state flags. - * - ********************************************************************************** - */ -static void -RemoveItem(Item item) -{ - WidgetInfo *wi = item->wi; - GroupItem group; - - group = (GroupItem) item->parent; - - /* damage bounding boxes */ - if (ISSET(item->flags, VISIBLE_BIT)) { - Damage(wi, &item->item_bounding_box); - ZnNeedRedisplay(wi); - } - - /* - * Tell that we need to repick - */ - if (item->class != ZnGroup) { - SET(wi->events_flags, INTERNAL_NEED_REPICK); - } - - if (group) { - if (group->dependents) { - /* Remove me from dependency list. */ - ExtractDependentItem(item); - - /* Disconnect all dependents on me. */ - DisconnectDependentItems(item); - } - /* - * Remove me from item list. - */ - ExtractItem(item); - /* - * Remove me as a clip item. - */ - if (group->clip == item) { - group->clip = ZN_NO_ITEM; - Invalidate((Item) group, ZN_COORDS_FLAG); - } - } -} - - -/* - ********************************************************************************** - * - * DestroyItem -- + * DestroyItem -- Method * ********************************************************************************** */ @@ -3685,11 +2672,12 @@ static void DestroyItem(Item item) { WidgetInfo *wi = item->wi; - + TextInfo *ti = &wi->text_info; + /* * Extract it from its group. */ - RemoveItem(item); + ExtractItem(item); /* * Update state variables to prevent dangling pointers. @@ -3705,11 +2693,17 @@ DestroyItem(Item item) if ((wi->hot_item == item) || (wi->hot_prev) == item) { wi->hot_item = ZN_NO_ITEM; } - if (wi->text_info.sel_item == item) { - wi->text_info.sel_item = ZN_NO_ITEM; + if (ti->sel_item == item) { + ti->sel_item = ZN_NO_ITEM; + ti->sel_field = ZN_NO_PART; + } + if (ti->anchor_item == item) { + ti->anchor_item = ZN_NO_ITEM; + ti->anchor_field = ZN_NO_PART; } - if (wi->text_info.sel_item == item) { - wi->text_info.focus_item = ZN_NO_ITEM; + if (wi->focus_item == item) { + wi->focus_item = ZN_NO_ITEM; + wi->focus_field = ZN_NO_PART; } /* @@ -3739,1400 +2733,20 @@ DestroyItem(Item item) /* ********************************************************************************** * - * FieldImageChange -- - * - ********************************************************************************** - */ -static void -FieldImageChange(ClientData client_data, - int x, - int y, - int width, - int height, - int image_width, - int image_height) -{ - Field field = (Field) client_data; - int i; - ZnBBox bbox; - - if (field->image != ZnUnspecifiedImage) { - i = (((char *) field) - ((char *) field->field_set->fields)) / sizeof(FieldStruct); - GetFieldBBox(field->field_set, i, &bbox); - Damage(field->field_set->wi, &bbox); - ZnNeedRedisplay(field->field_set->wi); - ClearFieldCache(field->field_set, i); - } -} - - -/* - ********************************************************************************** - * - * FieldTileChange -- - * - ********************************************************************************** - */ -static void -FieldTileChange(ClientData client_data, - int x, - int y, - int width, - int height, - int image_width, - int image_height) -{ - Field field = (Field) client_data; - int i; - ZnBBox bbox; - - if (field->tile != ZnUnspecifiedImage) { - i = (((char *) field) - ((char *) field->field_set->fields)) / sizeof(FieldStruct); - InvalidateImage(field->tile_name); - GetFieldBBox(field->field_set, i, &bbox); - Damage(field->field_set->wi, &bbox); - ZnNeedRedisplay(field->field_set->wi); - } -} - - -/* - ********************************************************************************** - * - * InitFields -- - * - * Perform the init of each field in a FieldSet. The number of such - * fields must have been inited before calling this fun. - * - ********************************************************************************** - */ -static void -InitFields(FieldSet field_set) -{ - WidgetInfo *wi = field_set->wi; - Field field; - unsigned int i, num_fields; - - /*printf("size of a field = %d\n", sizeof(FieldStruct));*/ - - if (field_set->num_fields < 0) { - field_set->num_fields = 0; - } - if (!field_set->num_fields) { - return; - } - num_fields = field_set->num_fields; - field_set->fields = (Field) ZnMalloc(num_fields*sizeof(FieldStruct)); - - for (i = 0; i < num_fields; i++){ - field = &field_set->fields[i]; - - field->field_set = field_set; - field->color = ZnGetGradientByValue(wi->fore_color); - field->fill_color = ZnGetGradientByValue(wi->back_color); - field->border_color = ZnGetGradientByValue(wi->fore_color); - SET(field->flags, FIELD_VISIBLE_BIT); - SET(field->flags, FIELD_SENSITIVE_BIT); - CLEAR(field->flags, FILLED_BIT); - CLEAR(field->flags, CACHE_OK); - field->fill_pattern = ZnUnspecifiedPattern; - field->text = ""; - field->image = ZnUnspecifiedImage; - field->image_name = ""; - field->tile = ZnUnspecifiedImage; - field->tile_name = ""; - field->font = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(wi->font)); - field->border_edges = NO_BORDER; - field->alignment = ZnJustifyLeft; - field->auto_alignment.automatic = False; - - field->relief = RELIEF_FLAT; - field->relief_thickness = 2; - SET(field->flags, TEXT_ON_TOP_BIT); - - field->gradient = NULL; - field->grad_geo = NULL; -#ifdef GLX - field->txf = NULL; -#endif - } - field_set->label_pos.x = field_set->label_pos.y = 0.0; - field_set->label_width = field_set->label_height = -1.0; -} - - -/* - ********************************************************************************** - * - * CloneFields -- - * - ********************************************************************************** - */ -static void -CloneFields(FieldSet field_set) -{ - WidgetInfo *wi = field_set->wi; - Field field, fields_ret; - unsigned int i, num_fields; - char *text; - - if (field_set->label_format) { - field_set->label_format = LabelFormatDuplicate(field_set->label_format); - } - num_fields = field_set->num_fields; - if (!num_fields) { - return; - } - fields_ret = (Field) ZnMalloc(num_fields*sizeof(FieldStruct)); - memcpy(fields_ret, field_set->fields, num_fields*sizeof(FieldStruct)); - field_set->fields = fields_ret; - - for (i = 0; i < num_fields; i++) { - field = &fields_ret[i]; - if (field->gradient) { - field->gradient = ZnGetGradientByValue(field->gradient); - } - if (field->grad_geo) { - ZnPoint *grad_geo = ZnMalloc(4*sizeof(ZnPoint)); - memcpy(grad_geo, field->grad_geo, 4*sizeof(ZnPoint)); - field->grad_geo = grad_geo; - } - if (field->image != ZnUnspecifiedImage) { - text = ZnMalloc((strlen(field->image_name) + 1) * sizeof(char)); - strcpy(text, field->image_name); - field->image_name = text; - field->image = Tk_GetImage(wi->interp, wi->win, field->image_name, - FieldImageChange, (ClientData) field); - } - if (field->tile != ZnUnspecifiedImage) { - text = ZnMalloc((strlen(field->tile_name) + 1) * sizeof(char)); - strcpy(text, field->tile_name); - field->tile_name = text; - field->tile = Tk_GetImage(wi->interp, wi->win, field->tile_name, - FieldTileChange, (ClientData) field); - } - if (field->fill_pattern != ZnUnspecifiedPattern) { - field->fill_pattern = Tk_GetBitmap(wi->interp, wi->win, - Tk_NameOfBitmap(wi->dpy, field->fill_pattern)); - } - field->font = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(field->font)); - field->color = ZnGetGradientByValue(field->color); - field->fill_color = ZnGetGradientByValue(field->fill_color); - field->border_color = ZnGetGradientByValue(field->border_color); - - if (strlen(field->text) != 0) { - text = (char *) ZnMalloc((strlen(field->text) + 1) * sizeof(char)); - strcpy(text, field->text); - field->text = text; - } - } -} - - -/* - ********************************************************************************** - * - * ConfigureField -- - * - ********************************************************************************** - */ -static int -ConfigureField(FieldSet field_set, - unsigned int field, - int argc, - Tcl_Obj *CONST argv[], - int *flags) -{ - int i; - Field field_ptr; - ZnBBox bbox; - WidgetInfo *wi = field_set->wi; - XColor *color; - int alpha; - - if (field >= field_set->num_fields) { - return ZN_ERROR; - } - - field_ptr = &field_set->fields[field]; - - if (ConfigureAttributes((char *) field_set, field, argc, argv, flags) == ZN_ERROR) { - return ZN_ERROR; - } - - if (ISSET(*flags, ZN_REPICK_FLAG)) { - SET(wi->events_flags, INTERNAL_NEED_REPICK); - } - if (ISSET(*flags, ZN_CLFC_FLAG)) { - ClearFieldCache(field_set, field); - } - - if (field_ptr->gradient && - (ISSET(*flags, ZN_BORDER_FLAG) || (field_ptr->relief == RELIEF_FLAT))) { - ZnFreeGradient(field_ptr->gradient); - field_ptr->gradient = NULL; - } - if ((field_ptr->relief != RELIEF_FLAT) && !field_ptr->gradient) { - color = ZnGetGradientColor(field_ptr->border_color, 51.0, &alpha); - field_ptr->gradient = ZnGetReliefGradient(wi->interp, wi->win, - ZnNameOfColor(color), alpha); - if (field_ptr->gradient == NULL) { - return ZN_ERROR; - } - } - - if (ISSET(*flags, ZN_IMAGE_FLAG)) { - if (ValidateImage(wi, field_ptr, field_ptr->image_name, FieldImageChange, - &field_ptr->image, "field -image") == ZN_ERROR) { - return ZN_ERROR; - } - } - - if (ISSET(*flags, ZN_TILE_FLAG)) { - if (ValidateImage(wi, field_ptr, field_ptr->tile_name, FieldTileChange, - &field_ptr->tile, "field -tile") == ZN_ERROR) { - return ZN_ERROR; - } - } - - /* - * This is done here to limit the redraw to the area of the - * modified fields. - */ - if (ISCLEAR(*flags, ZN_COORDS_FLAG) && - field_set->label_format && ISSET(*flags, ZN_DRAW_FLAG)) { - for (i = 0; i < LabelFormatNumFields(field_set->label_format); i++) { - if (i == field) { - GetFieldBBox(field_set, i, &bbox); - Damage(wi, &bbox); - break; - } - } - } - - return ZN_OK; -} - - -/* - ********************************************************************************** - * - * QueryField -- - * - ********************************************************************************** - */ -static int -QueryField(FieldSet field_set, - unsigned int field, - int argc, - Tcl_Obj *CONST argv[]) -{ - Field field_ptr; - - if (field >= field_set->num_fields) { - return ZN_ERROR; - } - - field_ptr = &field_set->fields[field]; - if (QueryAttribute((char *) field_set, field, argv[0]) == ZN_ERROR) { - return ZN_ERROR; - } - - return ZN_OK; -} - - -/* - ********************************************************************************** - * - * FreeFields -- - * - ********************************************************************************** - */ -static void -FreeFields(FieldSet field_set) -{ - WidgetInfo *wi = field_set->wi; - unsigned int i, num_fields; - Field field; - - if (field_set->label_format) { - LabelFormatDelete(field_set->label_format); - } - - num_fields = field_set->num_fields; - for (i = 0; i < num_fields; i++) { - field = &field_set->fields[i]; - - if (strlen(field->text) != 0) { - ZnFree(field->text); - } - if (field->gradient) { - ZnFreeGradient(field->gradient); - } - if (field->grad_geo) { - ZnFree(field->grad_geo); - } - if (field->image != ZnUnspecifiedImage) { - Tk_FreeImage(field->image); - field->image = ZnUnspecifiedImage; - } - if (strlen(field->image_name) != 0) { - ZnFree(field->image_name); - } - if (field->tile != ZnUnspecifiedImage) { - Tk_FreeImage(field->tile); - field->tile = ZnUnspecifiedImage; - } - if (strlen(field->tile_name) != 0) { - ZnFree(field->tile_name); - } - if (field->fill_pattern != ZnUnspecifiedPattern) { - Tk_FreeBitmap(wi->dpy, field->fill_pattern); - field->fill_pattern = ZnUnspecifiedPattern; - } - /*printf("freeing a font\n");*/ - Tk_FreeFont(field->font); - ZnFreeGradient(field->color); - ZnFreeGradient(field->fill_color); - ZnFreeGradient(field->border_color); - } - if (num_fields) { - ZnFree(field_set->fields); - } -} - - -/* - ********************************************************************************** - * - * ComputeFieldImageLocation -- - * Compute the bounding box of the pixmap in a field. The position is - * deduced from the field bounding box passed in bbox. - * - ********************************************************************************** - */ -static void -ComputeFieldImageLocation(Field field_ptr, - ZnBBox *bbox, - ZnBBox *pm_bbox) -{ - int width, height; - - Tk_SizeOfImage(field_ptr->image, &width, &height); - pm_bbox->orig.y = (bbox->orig.y + bbox->corner.y - height) / 2; - pm_bbox->corner.y = pm_bbox->orig.y + height; - - switch (field_ptr->alignment) { - case ZnJustifyLeft: - pm_bbox->orig.x = bbox->orig.x; - break; - case ZnJustifyRight: - pm_bbox->orig.x = bbox->corner.x - width - 1; - break; - default: - pm_bbox->orig.x = (bbox->orig.x + bbox->corner.x - width) / 2; - break; - } - pm_bbox->corner.x = pm_bbox->orig.x + width; -} - - -/* - ********************************************************************************** - * - * FieldsEngine -- - * - ********************************************************************************** - */ -static void -FieldsEngine(FieldSet field_set, - void (*cb)()) -{ - WidgetInfo *wi = field_set->wi; - int i; /* This one *NEED* to be an int */ - int num; - Field field_ptr; - ZnBBox label_clip_box, clip_bbox, bbox, *global_clip_box; - ZnBBox text_bbox, clip_text_bbox; - ZnPoint pts[2]; - ZnTriStrip tristrip; - ZnPoint text_pos; - ZnBBox pm_bbox, clip_pm_bbox; - ZnBool restore = False; - ZnDim lwidth, lheight; - ZnReal val; - - if (field_set->label_format && LabelFormatNumFields(field_set->label_format)) { - bbox.orig.x = REAL_TO_INT(field_set->label_pos.x); - bbox.orig.y = REAL_TO_INT(field_set->label_pos.y); - GetLabelBBox(field_set, &lwidth, &lheight); - bbox.corner.x = bbox.orig.x + lwidth; - bbox.corner.y = bbox.orig.y + lheight; - CurrentClip(wi, NULL, &global_clip_box, NULL); - - if (!wi->render) { - IntersectBBox(global_clip_box, &bbox, &label_clip_box); - if (IsEmptyBBox(&label_clip_box)) { - return; - } - } - else { - label_clip_box = bbox; - } - - num = LabelFormatNumFields(field_set->label_format); - for (i = 0; i < num; i++) { - field_ptr = &field_set->fields[i]; - - if (ISCLEAR(field_ptr->flags, FIELD_VISIBLE_BIT)) { - continue; - } - - GetFieldBBox(field_set, i, &bbox); - IntersectBBox(&label_clip_box, &bbox, &clip_bbox); - if (IsEmptyBBox(&clip_bbox)) { - continue; - } - - if (field_ptr->text) { - ComputeFieldTextLocation(field_ptr, &bbox, &text_pos, &text_bbox); - } - else { - ResetBBox(&text_bbox); - } - - IntersectBBox(&clip_bbox, &text_bbox, &clip_text_bbox); - - if (field_ptr->image != ZnUnspecifiedImage) { - ComputeFieldImageLocation(field_ptr, &bbox, &pm_bbox); - } - else { - ResetBBox(&pm_bbox); - } - - IntersectBBox(&clip_bbox, &pm_bbox, &clip_pm_bbox); - - /* we must call XSetClipRectangles only if it's required */ - val = clip_bbox.orig.x - bbox.orig.x; - restore = val > 0; - val = clip_bbox.orig.y - bbox.orig.y; - restore |= val > 0; - val = clip_bbox.corner.x - bbox.corner.x; - restore |= val < 0; - val = clip_bbox.corner.y - bbox.corner.y; - restore |= val < 0; - val = clip_text_bbox.orig.x - text_bbox.orig.x; - restore |= val > 0; - val = clip_text_bbox.orig.y - text_bbox.orig.y; - restore |= val > 0; - val = clip_text_bbox.corner.x - text_bbox.corner.x; - restore |= val < 0; - val = clip_text_bbox.corner.y - text_bbox.corner.y; - restore |= val < 0; - val = clip_pm_bbox.orig.x - pm_bbox.orig.x; - restore |= val > 0; - val = clip_pm_bbox.orig.y - pm_bbox.orig.y; - restore |= val > 0; - val = clip_pm_bbox.corner.x - pm_bbox.corner.x; - restore |= val < 0; - val = clip_pm_bbox.corner.y - pm_bbox.corner.y; - restore |= val < 0; - /*restore = True;*/ - if (restore) { - /* we must clip. */ - /*printf("clip\n");*/ - pts[0] = clip_bbox.orig; - pts[1] = clip_bbox.corner; - TRI_STRIP1(&tristrip, pts, 2); - PushClip(wi, &tristrip, True, True); - } - - (*cb)(wi, field_ptr, &bbox, &clip_bbox, &pm_bbox, &clip_pm_bbox, &text_pos); - - if (restore) { - /* Restore the previous clip. */ - PopClip(wi, True); - restore = False; - } - } - } -} - - -/* - ********************************************************************************** - * - * DrawFields -- - * - ********************************************************************************** - */ -void -DrawField(WidgetInfo *wi, - Field field_ptr, - ZnBBox *bbox, - ZnBBox *clip_bbox, - ZnBBox *pm_bbox, - ZnBBox *clip_pm_bbox, - ZnPoint *text_pos) -{ - XGCValues values; - XRectangle r; - int j; - - /* - * Draw the background. - */ - if (ISSET(field_ptr->flags, FILLED_BIT)) { - values.foreground = ZnPixel(ZnGetGradientColor(field_ptr->fill_color, 0.0, NULL)); - - if (field_ptr->tile != ZnUnspecifiedImage) { /* Fill tiled */ - Pixmap pmap = GetImagePixmap(wi->win, field_ptr->tile_name, - field_ptr->tile, NULL); - values.fill_style = FillTiled; - values.tile = pmap; - values.ts_x_origin = (int) bbox->orig.x; - values.ts_y_origin = (int) bbox->orig.y; - XChangeGC(wi->dpy, wi->gc, - GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCTile, - &values); - } - else if (field_ptr->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ - values.fill_style = FillStippled; - values.stipple = field_ptr->fill_pattern; - values.ts_x_origin = (int) bbox->orig.x; - values.ts_y_origin = (int) bbox->orig.y; - XChangeGC(wi->dpy, wi->gc, - GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle|GCStipple|GCForeground, - &values); - } - else { /* Fill solid */ - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCForeground|GCFillStyle, &values); - } - BBox2XRect(clip_bbox, &r); - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); - } - - /* - * Draw the image and the text, which is in back depends on - * the value of text_on_top. - */ - for (j = 0; j < 2; j++) { - if ((j == 0 && ISSET(field_ptr->flags, TEXT_ON_TOP_BIT)) || - (j == 1 && ISCLEAR(field_ptr->flags, TEXT_ON_TOP_BIT))) { - /* - * Draw the image. - */ - if (field_ptr->image != ZnUnspecifiedImage) { - Tk_RedrawImage(field_ptr->image, - clip_pm_bbox->orig.x - pm_bbox->orig.x, - clip_pm_bbox->orig.y - pm_bbox->orig.y, - REAL_TO_INT(clip_pm_bbox->corner.x - clip_pm_bbox->orig.x), - REAL_TO_INT(clip_pm_bbox->corner.y - clip_pm_bbox->orig.y), - wi->draw_buffer, - clip_pm_bbox->orig.x, clip_pm_bbox->orig.y); - } - } - else { - /* - * Draw the text. - */ - if (field_ptr->text && strlen(field_ptr->text)) { - values.foreground = ZnPixel(ZnGetGradientColor(field_ptr->color, 0, NULL)); - values.fill_style = FillSolid; - values.font = ZnFontId(field_ptr->font); - XChangeGC(wi->dpy, wi->gc, GCForeground | GCFillStyle | GCFont, &values); - Tk_DrawChars(wi->dpy, wi->draw_buffer, wi->gc, field_ptr->font, - field_ptr->text, strlen(field_ptr->text), - text_pos->x, text_pos->y); - } - } - } - - BBox2XRect(bbox, &r); - /* - * Draw the border relief. - */ - if ((field_ptr->relief != RELIEF_FLAT) && (field_ptr->relief_thickness > 1)) { - DrawRectangleRelief(wi, field_ptr->relief, field_ptr->gradient, - &r, (unsigned int) field_ptr->relief_thickness); - } - - /* - * Draw the border line. - */ - if (field_ptr->border_edges != NO_BORDER) { - values.foreground = ZnPixel(ZnGetGradientColor(field_ptr->border_color, 0, NULL)); - values.line_width = 0; - values.line_style = LineSolid; - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, - GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, &values); - if (field_ptr->border_edges & LEFT_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, - r.x, r.y + r.height - 1); - } - if (field_ptr->border_edges & RIGHT_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x + r.width - 1, r.y, - r.x + r.width - 1, r.y + r.height - 1); - } - if (field_ptr->border_edges & TOP_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y, r.x + r.width - 1, r.y); - } - if (field_ptr->border_edges & BOTTOM_BORDER) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y + r.height - 1, - r.x + r.width - 1, r.y + r.height - 1); - } - if (field_ptr->border_edges & OBLIQUE) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y, r.x + r.width - 1, r.y + r.height - 1); - } - if (field_ptr->border_edges & COUNTER_OBLIQUE) { - XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, - r.x, r.y + r.height - 1, - r.x + r.width - 1, r.y); - } - } -} - -static void -DrawFields(FieldSet field_set) -{ - FieldsEngine(field_set, DrawField); -} - - -/* - ********************************************************************************** - * - * RenderFields -- - * - ********************************************************************************** - */ -void -FieldRenderCB(void *closure) -{ -#ifdef GLX - ZnBBox *bbox = (ZnBBox *) closure; - - glBegin(GL_QUADS); - glVertex2f(bbox->orig.x, bbox->orig.y); - glVertex2f(bbox->orig.x, bbox->corner.y); - glVertex2f(bbox->corner.x, bbox->corner.y); - glVertex2f(bbox->corner.x, bbox->orig.y); - glEnd(); -#endif -} - -void -RenderField(WidgetInfo *wi, - Field field_ptr, - ZnBBox *bbox, - ZnBBox *clip_bbox, - ZnBBox *pm_bbox, - ZnBBox *clip_pm_bbox, - ZnPoint *text_pos) -{ -#ifdef GLX - int j; - XColor *color; - int alpha; - - /* - * Draw the background. - */ - if (ISSET(field_ptr->flags, FILLED_BIT)) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (!ZnGradientFlat(field_ptr->fill_color)) { -#if 0 /* TODO_GLX Faire le dégradé dans le fond des champs. */ - int type = field_ptr->fill_color->type; - ZnBool fast = (type == ZN_AXIAL_GRADIENT) && !field_ptr->grad_geo; - - RenderGradient(wi, field_ptr->fill_color, - fast ? NULL : FieldRenderCB, - bbox, fast ? (ZnPoint *) bbox : field_ptr->grad_geo); -#endif - } - else { - if (field_ptr->tile != ZnUnspecifiedImage) { /* Fill tiled */ - RenderTile(wi, GetImageTexture(wi->win, field_ptr->tile_name, field_ptr->tile), - field_ptr->fill_color, FieldRenderCB, bbox, (ZnPoint *) bbox); - } - else { /* Fill solid */ - if (field_ptr->fill_pattern != ZnUnspecifiedPattern) { /* Fill stippled */ - /* - * Setup polygon stippling. - */ - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(GetBitmapMask(wi->dpy, field_ptr->fill_pattern)->pixels); - } - color = ZnGetGradientColor(field_ptr->fill_color, 0.0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - FieldRenderCB(clip_bbox); - glDisable(GL_POLYGON_STIPPLE); - } - } - } - - /* - * Draw the image and the text, which one is in back depends on - * the value of text_on_top. - */ - for (j = 0; j < 2; j++) { - if ((j == 0 && ISSET(field_ptr->flags, TEXT_ON_TOP_BIT)) || - (j == 1 && ISCLEAR(field_ptr->flags, TEXT_ON_TOP_BIT))) { - /* - * Draw the image. - */ - if (field_ptr->image != ZnUnspecifiedImage) { - RenderImage(wi, GetImageTexture(wi->win, field_ptr->image_name, field_ptr->image), - field_ptr->fill_color, &(pm_bbox->orig), False); - } - } - else { - /* - * Draw the text. - */ - if (field_ptr->text && strlen(field_ptr->text)) { - if (!field_ptr->txf) { - field_ptr->txf = GetTexFont(wi->win, field_ptr->font); - } - if (field_ptr->txf) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - color = ZnGetGradientColor(field_ptr->color, 0, &alpha); - alpha = ZnComposeAlpha(alpha, wi->alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glBindTexture(GL_TEXTURE_2D, field_ptr->txf->texobj); - glPushMatrix(); - glTranslatef(text_pos->x, text_pos->y, 0.0); - txfRenderString(field_ptr->txf, field_ptr->text, strlen(field_ptr->text)); - glPopMatrix(); - glDisable(GL_TEXTURE_2D); - } - } - } - } - - /* - * Draw the border relief. - */ - if ((field_ptr->relief != RELIEF_FLAT) && (field_ptr->relief_thickness > 1)) { - ZnPoint p[5]; - - p[0].x = bbox->orig.x; - p[0].y = bbox->orig.y; - p[2].x = bbox->corner.x; - p[2].y = bbox->corner.y; - p[1].x = p[0].x; - p[1].y = p[2].y; - p[3].x = p[2].x; - p[3].y = p[0].y; - p[4] = p[0]; - RenderPolygonRelief(wi, field_ptr->relief, field_ptr->gradient, - False, p, 5, field_ptr->relief_thickness); - } - - /* - * Draw the border line. - */ - if (field_ptr->border_edges != NO_BORDER) { - color = ZnGetGradientColor(field_ptr->border_color, 0, &alpha); - glColor4us(color->red, color->green, color->blue, alpha); - glLineWidth(1); - SetLineStyle(wi, LINE_SIMPLE); - glBegin(GL_LINES); - if (field_ptr->border_edges & LEFT_BORDER) { - glVertex2f(bbox->orig.x, bbox->orig.y); - glVertex2f(bbox->orig.x, bbox->corner.y); - } - if (field_ptr->border_edges & RIGHT_BORDER) { - glVertex2f(bbox->corner.x, bbox->orig.y); - glVertex2f(bbox->corner.x, bbox->corner.y); - } - if (field_ptr->border_edges & TOP_BORDER) { - glVertex2f(bbox->orig.x, bbox->orig.y); - glVertex2f(bbox->corner.x, bbox->orig.y); - } - if (field_ptr->border_edges & BOTTOM_BORDER) { - glVertex2f(bbox->orig.x, bbox->corner.y); - glVertex2f(bbox->corner.x, bbox->corner.y); - } - if (field_ptr->border_edges & OBLIQUE) { - glVertex2f(bbox->orig.x, bbox->orig.y); - glVertex2f(bbox->corner.x, bbox->corner.y); - } - if (field_ptr->border_edges & COUNTER_OBLIQUE) { - glVertex2f(bbox->orig.x, bbox->corner.y); - glVertex2f(bbox->corner.x, bbox->orig.y); - } - glEnd(); - } -#endif -} - -static void -RenderFields(FieldSet field_set) -{ - FieldsEngine(field_set, RenderField); -} - - -/* - ********************************************************************************** - * - * IsFieldsSensitive -- - * - ********************************************************************************** - */ -static ZnBool -IsFieldSensitive(FieldSet field_set, - int part) -{ - if ((part >= 0) && (part < field_set->num_fields)) { - return ISSET(field_set->fields[part].flags, FIELD_SENSITIVE_BIT); - } - else { - return False; - } -} - - -/* - ********************************************************************************** - * - * FieldsPick -- - * Return the first field that contains <x, y>. - * A field is selected if <x, y> is over a non transparent area. - * Such areas are : a solid filled background, a text, an icon. - * This does *NOT* do with *GLOBAL* visible and sensitive. - * But we need to take into account local field visible and - * sensitive as they modifiy local transparency. Local means - * within a single item. - * - ********************************************************************************** - */ -static double -FieldsPick(FieldSet field_set, - ZnPoint *p, - int *part) -{ - Field field_ptr; - ZnBBox bbox; - int i, best_field = 0; - double new_dist, dist = 1e40; - - if (field_set->label_format) { - for (i = LabelFormatNumFields(field_set->label_format)-1; i >= 0; i--) { - field_ptr = &field_set->fields[i]; - - if (ISCLEAR(field_ptr->flags, FIELD_VISIBLE_BIT) && - ISCLEAR(field_ptr->flags, FIELD_SENSITIVE_BIT)) { - continue; - } - - GetFieldBBox(field_set, i, &bbox); - - new_dist = RectangleToPointDist(&bbox, p); - if (new_dist < dist) { - dist = new_dist; - best_field = i; - } - if (dist <= 0.0) { - dist = 0.0; - break; - } - } - } - - *part = best_field; - return dist; -} - - -/* - ********************************************************************************** - * - * FieldsToArea -- - * Return -1 if no field is in the given area, 1 if they are - * all in it or 0 if there is some overlap. The function consider - * only fields that are either sensible or visible. - * - ********************************************************************************** - */ -static int -FieldsToArea(FieldSet field_set, - ZnBBox *area) -{ - Field field_ptr; - ZnBBox bbox; - int inside = -1; - int i; - ZnBool first_done = False; - - for (i = LabelFormatNumFields(field_set->label_format)-1; i >= 0; i--) { - field_ptr = &field_set->fields[i]; - - if (ISCLEAR(field_ptr->flags, FIELD_VISIBLE_BIT) && - ISCLEAR(field_ptr->flags, FIELD_SENSITIVE_BIT)) { - continue; - } - - GetFieldBBox(field_set, i, &bbox); - if (!first_done) { - first_done = True; - inside = BBoxInBBox(&bbox, area); - if (inside == 0) { - return 0; - } - } - else { - if (BBoxInBBox(&bbox, area) != inside) { - return 0; - } - } - } - - return inside; -} - - -/* - ********************************************************************************** - * - * SetFieldsAutoAlign -- - * - ********************************************************************************** - */ -static void -SetFieldsAutoAlign(Item item, - int alignment) -{ - int i; - FieldSet field_set; - Field field; - - if (!item->class->has_fields) { - return; - } - if ((alignment >= AA_LEFT) && (alignment <= AA_RIGHT)) { - field_set = item->class->GetFieldSet(item); - for (i = 0; i < field_set->num_fields; i++) { - field = &field_set->fields[i]; - if (field->auto_alignment.automatic) { - field->alignment = field->auto_alignment.align[alignment]; - } - } - } -} - - -static void -Damage(WidgetInfo *wi, - ZnBBox *damage) -{ - if ((damage == NULL) || IsEmptyBBox(damage)) { - return; - } - - /*printf("damaging area: %g %g %g %g\n", damage->orig.x, - damage->orig.y, damage->corner.x, damage->corner.y);*/ - - if (IsEmptyBBox(&wi->damaged_area)) { - wi->damaged_area.orig.x = damage->orig.x; - wi->damaged_area.orig.y = damage->orig.y; - wi->damaged_area.corner.x = damage->corner.x; - wi->damaged_area.corner.y = damage->corner.y; - } - else { - wi->damaged_area.orig.x = MIN(wi->damaged_area.orig.x, damage->orig.x); - wi->damaged_area.orig.y = MIN(wi->damaged_area.orig.y, damage->orig.y); - wi->damaged_area.corner.x = MAX(wi->damaged_area.corner.x, damage->corner.x); - wi->damaged_area.corner.y = MAX(wi->damaged_area.corner.y, damage->corner.y); - } - /*printf("damaged area: %g %g %g %g\n", wi->damaged_area.orig.x, - wi->damaged_area.orig.y, wi->damaged_area.corner.x, - wi->damaged_area.corner.y);*/ -} - -static void -ClampDamageArea(WidgetInfo *wi) -{ - int width, height; - - if (wi->damaged_area.orig.x < wi->inset) { - wi->damaged_area.orig.x = wi->inset; - } - if (wi->damaged_area.orig.y < wi->inset) { - wi->damaged_area.orig.y = wi->inset; - } - if (wi->damaged_area.corner.x < wi->inset) { - wi->damaged_area.corner.x = wi->inset; - } - if (wi->damaged_area.corner.y < wi->inset) { - wi->damaged_area.corner.y = wi->inset; - } - width = wi->width - wi->inset; - height = wi->height - wi->inset; - if (wi->damaged_area.orig.x > width) { - wi->damaged_area.orig.x = width; - } - if (wi->damaged_area.orig.y > height) { - wi->damaged_area.orig.y = height; - } - if (wi->damaged_area.corner.x > width) { - wi->damaged_area.corner.x = width; - } - if (wi->damaged_area.corner.y > height) { - wi->damaged_area.corner.y = height; - } -} - -static void -Update(WidgetInfo *wi) -{ - /* - * Give the overlap manager a chance to do its work. - */ -#ifdef OM - if ((wi->om_group != ZN_NO_ITEM) && - ((GroupItem) wi->om_group)->call_om) { - ZnPoint scale={1.0,1.0}; - if (wi->om_group->transfo) { - ZnTransfoDecompose(wi->om_group->transfo, &scale, - NULL, NULL, NULL); - } - OmProcessOverlap((void *) wi, wi->width, wi->height, scale.x); - ((GroupItem) wi->om_group)->call_om = False; - } -#endif - - if (ISSET(wi->top_group->inv_flags, ZN_COORDS_FLAG) || - ISSET(wi->top_group->inv_flags, ZN_TRANSFO_FLAG)) { - wi->top_group->class->ComputeCoordinates(wi->top_group, False); - } -} - - -static void -Repair(WidgetInfo *wi) -{ - XGCValues values; - ZnPoint pts[2]; - ZnTriStrip tristrip; - XColor *color; - ZnReal int_width = Tk_Width(wi->win); - ZnReal int_height = Tk_Height(wi->win); - - if (wi->render) { -#ifdef GLX -#ifdef GLX_DAMAGE - ClampDamageArea(wi); - /* - * Merge the exposed area. - */ - AddBBoxToBBox(&wi->damaged_area, &wi->exposed_area); - if (IsEmptyBBox(&wi->damaged_area)) { - return; - } -#endif - - glXMakeCurrent(wi->dpy, ZnWindowId(wi->win), wi->gl_context); - glEnable(GL_POINT_SMOOTH); - glEnable(GL_LINE_SMOOTH); -#if 0 - glEnable(GL_POLYGON_SMOOTH); /* expensive ? */ -#endif - - glEnable(GL_BLEND); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glClearStencil(0); - color = ZnGetGradientColor(wi->back_color, 0, NULL); - glClearColor(color->red/65536.0, color->green/65536.0, - color->blue/65536.0, 0.0); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - /* - * Init the composite group alpha. - */ - wi->alpha = 100; - - glViewport(0, 0, (GLsizei) int_width, int_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, int_width, int_height, 0.0); - glMatrixMode(GL_MODELVIEW); - -#ifdef GLX_DAMAGE - glEnable(GL_SCISSOR_TEST); - - /* - * Set the damaged area as the scissor area. - */ - wi->damaged_area.orig.x = REAL_TO_INT(wi->damaged_area.orig.x); - wi->damaged_area.orig.y = REAL_TO_INT(wi->damaged_area.orig.y); - wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x); - wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); - glScissor(wi->damaged_area.orig.x, - int_height - wi->damaged_area.corner.y, - wi->damaged_area.corner.x - wi->damaged_area.orig.x, - wi->damaged_area.corner.y - wi->damaged_area.orig.y); -#else - /* - * We do not use the damaged area for GL rendering, - * set it to the whole area. - */ - wi->damaged_area.orig.x = wi->damaged_area.orig.y = wi->inset; - wi->damaged_area.corner.x = int_width-wi->inset; - wi->damaged_area.corner.y = int_height-wi->inset; -#endif - - /* - * Clear the GL buffers. - */ - glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - /* - * Setup the background tile if needed. - */ - if (wi->tile != ZnUnspecifiedImage) { - ZnBBox bbox; - - bbox.orig.x = bbox.orig.y = 0.0; - bbox.corner.x = int_width; - bbox.corner.y = int_height; - - RenderTile(wi, GetImageTexture(wi->win, wi->tile_name, wi->tile), - NULL, NULL, NULL, (ZnPoint *) &bbox); - } - - wi->top_group->class->Render(wi->top_group); - - if ((wi->border_width > 0) || (wi->highlight_width > 0)) { - int alpha; - -#ifdef GLX_DAMAGE - glDisable(GL_SCISSOR_TEST); -#endif - if (wi->highlight_width > 0) { - if (wi->text_info.got_focus) { - color = ZnGetGradientColor(wi->highlight_color, 0, &alpha); - } - else { - color = ZnGetGradientColor(wi->highlight_bg_color, 0, &alpha); - } - alpha = ZnComposeAlpha(alpha, 100); - glColor4us(color->red, color->green, color->blue, alpha); - - glBegin(GL_QUAD_STRIP); - glVertex2f(0.0, 0.0); - glVertex2f(wi->highlight_width, wi->highlight_width); - glVertex2f(int_width, 0); - glVertex2f(int_width - wi->highlight_width, wi->highlight_width); - glVertex2f(int_width, int_height); - glVertex2f(int_width - wi->highlight_width, int_height - wi->highlight_width); - glVertex2f(0, int_height); - glVertex2f(wi->highlight_width, int_height - wi->highlight_width); - glVertex2f(0, 0); - glVertex2f(wi->highlight_width, wi->highlight_width); - glEnd(); - } - if (wi->border_width > 0) { - ZnPoint p[5]; - - p[4].x = p[4].y = p[3].y = p[1].x = wi->highlight_width; - p[0] = p[4]; - p[3].x = p[2].x = int_width - wi->highlight_width; - p[2].y = p[1].y = int_height - wi->highlight_width; - RenderPolygonRelief(wi, wi->relief, wi->relief_grad, - False, p, 5, wi->border_width); - } -#ifdef GLX_DAMAGE - glEnable(GL_SCISSOR_TEST); -#endif - } - /* Switch the GL buffers. */ - glXSwapBuffers(wi->dpy, ZnWindowId(wi->win)); - glFlush(); - - /* - * Wait the end of GL update if we need to synchronize - * to monitor perfs. - */ - if (wi->monitoring) { - glXWaitGL(); - } -#endif - } - else { - XRectangle r; - ZnBBox merge; - - ClampDamageArea(wi); - /* - * Merge the damaged area with the exposed area. - */ - ResetBBox(&merge); - CopyBBox(&wi->damaged_area, &merge); - AddBBoxToBBox(&merge, &wi->exposed_area); - if (!IsEmptyBBox(&merge)) { - - /* Set the whole damaged area as clip rect. */ - wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x); - wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y); - wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x); - wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); - r.width = wi->damaged_area.corner.x - wi->damaged_area.orig.x; - r.height = wi->damaged_area.corner.y - wi->damaged_area.orig.y; - pts[0] = wi->damaged_area.orig; - pts[1] = wi->damaged_area.corner; - TRI_STRIP1(&tristrip, pts, 2); - PushClip(wi, &tristrip, True, True); - - /* Fill the background of the double buffer pixmap. */ - if (wi->tile == ZnUnspecifiedImage) { - values.foreground = ZnPixel(ZnGetGradientColor(wi->back_color, 0, NULL)); - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &values); - } - else { - values.fill_style = FillTiled; - values.tile = GetImagePixmap(wi->win, wi->tile_name, wi->tile, NULL); - values.ts_x_origin = values.ts_y_origin = 0; - XChangeGC(wi->dpy, wi->gc, - GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, - &values); - } - /*printf("Repair : filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/ - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); - - /* Draw the items */ - /*printf("Drawing\n");*/ - wi->top_group->class->Draw(wi->top_group); - - PopClip(wi, True); - - /* - * Send the merged area back to screen. - */ - merge.orig.x = MAX(merge.orig.x, wi->inset); - merge.orig.y = MAX(merge.orig.y, wi->inset); - merge.corner.x = MIN(merge.corner.x, int_width-wi->inset); - merge.corner.y = MIN(merge.corner.y, int_height-wi->inset); - BBox2XRect(&merge, &r); - XCopyArea(wi->dpy, - wi->draw_buffer, ZnWindowId(wi->win), wi->gc, - r.x, r.y, r.width, r.height, r.x, r.y); - } - - /* - * Redraw the borders. - */ - if (wi->border_width > 0) { - Pixmap save; - XRectangle r; - - save = wi->draw_buffer; - wi->draw_buffer = ZnWindowId(wi->win); - r.x = r.y = wi->highlight_width; - r.width = int_width - 2*wi->highlight_width; - r.height = int_height - 2*wi->highlight_width; - DrawRectangleRelief(wi, wi->relief, wi->relief_grad, - &r, wi->border_width); - wi->draw_buffer = save; - } - if (wi->highlight_width > 0) { - XRectangle r[4]; - - XSetForeground(wi->dpy, wi->gc, - ZnPixel(ZnGetGradientColor(wi->text_info.got_focus ? - wi->highlight_color : - wi->highlight_bg_color, - 0, NULL))); - XSetFillStyle(wi->dpy, wi->gc, FillSolid); - r[0].x = r[0].y = 0; - r[0].width = int_width; - r[0].height = wi->highlight_width; - r[1].x = int_width - wi->highlight_width; - r[1].y = 0; - r[1].width = wi->highlight_width; - r[1].height = int_height; - r[2].x = 0; - r[2].y = int_height - wi->highlight_width; - r[2].width = int_width; - r[2].height = wi->highlight_width; - r[3].x = r[3].y = 0; - r[3].width = wi->highlight_width; - r[3].height = int_height; - XFillRectangles(wi->dpy, ZnWindowId(wi->win), wi->gc, r, 4); - } - } -} - - -/* - ********************************************************************************** - * - * Exported functions structs -- + * Generic methods on items -- * ********************************************************************************** */ -struct _ITEM_P ITEM_P = { - GlobalModuleInit, - CreateItem, - AddItemClass, - LookupItemClass, - ItemClassList, - Damage, - Repair, - Update, - ConfigureAttributes, - QueryAttribute, - InitFields, - CloneFields, - FreeFields, - DrawFields, - RenderFields, - FieldsToArea, - IsFieldSensitive, - FieldsPick, - LeaderToLabel, - GetLabelBBox, - GetFieldBBox, - InitTransformStack, - FreeTransformStack, - ResetTransformStack, - PushTransform, - PopTransform, - InitClipStack, - FreeClipStack, - ResetClipStack, - PushClip, - PopClip, - CurrentClip, -}; struct _ITEM ITEM = { CloneItem, DestroyItem, ConfigureItem, QueryItem, - AttributesInfo, - SetFieldsAutoAlign, InsertItem, UpdateItemPriority, - InsertDependentItem, UpdateItemDependency, - RemoveItem, + ExtractItem, SetId, FreeId, AddTag, diff --git a/generic/Item.h b/generic/Item.h index 67fd646..840fa2c 100644 --- a/generic/Item.h +++ b/generic/Item.h @@ -33,7 +33,9 @@ #include "PostScript.h" #include "Attrs.h" +#include "Types.h" #include "List.h" +#include "Field.h" #include <X11/Xlib.h> @@ -81,6 +83,9 @@ #define COMPOSE_ROTATION_BIT 64 +struct _WidgetInfo; +struct _ZnTransfo; + /* * Item record header -- */ @@ -106,45 +111,6 @@ typedef struct _ItemStruct { /* - * Group item special record. - */ -typedef struct _GroupItemStruct { - ItemStruct header; - - /* Public data */ - Item clip; - unsigned char alpha; - - /* Private data */ - Item head; /* Doubly linked list of all items. */ - Item tail; - ZnList dependents; /* List of dependent items. */ -#ifdef OM - /* Overlap manager variables. - * These variables are valid *only* if the overlap - * manager is active. */ - ZnBool call_om; /* Tell if there is a need to call the */ - /* overlap manager. */ -#endif -} GroupItemStruct, *GroupItem; - - -/* - * Field array management record. - */ -typedef struct _FieldSetStruct { - struct _WidgetInfo *wi; - ZnLabelFormat label_format; - unsigned int num_fields; - struct _FieldStruct *fields; - ZnDim label_width; /* Describe the label size. Access these */ - ZnDim label_height; /* 2 only with GetLabelBBox. -1 means - * not up to date. */ - ZnPoint label_pos; /* Describe the label origin. */ -} FieldSetStruct, *FieldSet; - - -/* * Item class record -- */ typedef int (*ItemInitMethod)(Item item, int *argc, Tcl_Obj *CONST *args[]); @@ -162,7 +128,7 @@ typedef ZnBool (*ItemIsSensitiveMethod)(Item item, int part); typedef double (*ItemPickMethod)(Item item, ZnPoint *point, Item start_item, int aperture, Item *a_item, int *a_part); -typedef FieldSet (*ItemGetFieldSetMethod)(Item item); +typedef struct _FieldSetStruct* (*ItemGetFieldSetMethod)(Item item); typedef void (*ItemContourMethod)(Item item, int cmd, ZnPoly *poly); typedef void (*ItemPickVertexMethod)(Item item, ZnPoint *p, int *contour, int *vertex, int *o_vertex); @@ -171,21 +137,24 @@ typedef ZnBool (*ItemGetClipVerticesMethod)(Item item, ZnTriStrip *tristrip); typedef ZnBool (*ItemGetContoursMethod)(Item item, ZnPoly *poly); typedef int (*ItemCoordsMethod)(Item item, int contour, int index, int cmd, ZnPoint **points, int *num_points); -typedef void (*ItemInsertCharsMethod)(Item item, int index, char *chars); -typedef void (*ItemDeleteCharsMethod)(Item item, int first, int last); -typedef void (*ItemCursorMethod)(Item item, int index); -typedef int (*ItemIndexMethod)(Item item, Tcl_Obj *index_spec, int *index); +typedef void (*ItemInsertCharsMethod)(Item item, int field, int *index, + char *chars); +typedef void (*ItemDeleteCharsMethod)(Item item, int field, int *first, + int *last); +typedef void (*ItemCursorMethod)(Item item, int field, int index); +typedef int (*ItemIndexMethod)(Item item, int field, Tcl_Obj *index_spec, + int *index); typedef int (*ItemPartMethod)(Item item, Tcl_Obj **part_spec, int *part); -typedef int (*ItemSelectionMethod)(Item item, int offset, char *chars, - int max_chars); +typedef int (*ItemSelectionMethod)(Item item, int field, int offset, + char *chars, int max_chars); typedef void (*ItemPostScriptMethod)(Item item, PostScriptInfo ps_info); typedef struct _ItemClassStruct { - int item_size; - ZnBool has_fields; + int size; + ZnBool has_fields; /* 1 if fields are supported */ int num_parts; /* 0 if no special parts, else * gives how many parts exist. */ - ZnBool has_anchors; + ZnBool has_anchors; /* 1 if anchors are supported */ char *name; ZnAttrConfig *attr_desc; ItemInitMethod Init; @@ -229,13 +198,10 @@ extern struct _ITEM { int (*ConfigureItem)(Item item, int field, int argc, Tcl_Obj *CONST args[], ZnBool init); int (*QueryItem)(Item item, int field, int argc, Tcl_Obj *CONST args[]); - int (*AttributesInfo)(Item item, int field, int argc, Tcl_Obj *CONST args[]); - void (*SetFieldsAutoAlign)(Item item, int alignment); void (*InsertItem)(Item item, Item group, Item mark_item, ZnBool before); void (*UpdateItemPriority)(Item item, Item mark_item, ZnBool before); - void (*InsertDependentItem)(Item item); void (*UpdateItemDependency)(Item item, Item old_connection); - void (*RemoveItem)(Item item); + void (*ExtractItem)(Item item); void (*SetId)(Item item); void (*FreeId)(Item item); void (*AddTag)(Item item, Tk_Uid tag); @@ -259,45 +225,33 @@ extern struct _ITEM { * ********************************************************************************** */ -extern struct _ITEM_P { - void (*GlobalModuleInit)(); - Item (*CreateItem)(struct _WidgetInfo *wi, ItemClass item_class, - int *argc, Tcl_Obj *CONST *args[]); - void (*AddItemClass)(ItemClass class); - ItemClass (*LookupItemClass)(char *class_name); - ZnList (*ItemClassList)(); - void (*Damage)(struct _WidgetInfo *wi, ZnBBox *damage); - void (*Repair)(struct _WidgetInfo *wi); - void (*Update)(struct _WidgetInfo *wi); - int (*ConfigureAttributes)(char *record, int field, int argc, - Tcl_Obj *CONST args[], int *flags); - int (*QueryAttribute)(char *record, int field, Tcl_Obj *attr_name); - void (*InitFields)(FieldSet field_set); - void (*CloneFields)(FieldSet field_set); - void (*FreeFields)(FieldSet field_set); - void (*DrawFields)(FieldSet field_set); - void (*RenderFields)(FieldSet field_set); - int (*FieldsToArea)(FieldSet field_set, ZnBBox *area); - ZnBool (*IsFieldSensitive)(FieldSet field_set, int part); - double (*FieldsPick)(FieldSet field_set, ZnPoint *p, int *part); - void (*LeaderToLabel)(FieldSet field_set, ZnPoint *start, ZnPoint *end); - void (*GetLabelBBox)(FieldSet field_set, ZnDim *w, ZnDim *h); - void (*GetFieldBBox)(FieldSet field_set, unsigned int index, ZnBBox *field_bbox); - void (*InitTransformStack)(struct _WidgetInfo *wi); - void (*FreeTransformStack)(struct _WidgetInfo *wi); - void (*ResetTransformStack)(struct _WidgetInfo *wi); - void (*PushTransform)(struct _WidgetInfo *wi, struct _ZnTransfo *transfo, - ZnBool compose_scale, ZnBool compose_rot); - void (*PopTransform)(struct _WidgetInfo *wi); - void (*InitClipStack)(struct _WidgetInfo *wi); - void (*FreeClipStack)(struct _WidgetInfo *wi); - void (*ResetClipStack)(struct _WidgetInfo *wi); - void (*PushClip)(struct _WidgetInfo *wi, ZnTriStrip *tristrip, ZnBool simple, - ZnBool set_gc); - void (*PopClip)(struct _WidgetInfo *wi, ZnBool set_gc); - ZnBool (*CurrentClip)(struct _WidgetInfo *wi, Region *reg, ZnBBox **clip_box, - ZnBool *simple); -} ITEM_P; +void ZnItemInit(); +Item ZnCreateItem(struct _WidgetInfo *wi, ItemClass item_class, + int *argc, Tcl_Obj *CONST *args[]); +void ZnAddItemClass(ItemClass class); +ItemClass ZnLookupItemClass(char *class_name); +ZnList ZnItemClassList(); +int ZnConfigureAttributes(struct _WidgetInfo *wi, void *record, + ZnAttrConfig *attr_desc, int argc, Tcl_Obj *CONST args[], + int *flags); +int ZnAttributesInfo(struct _WidgetInfo *wi, void *record, + ZnAttrConfig *attr_desc, int argc, Tcl_Obj *CONST args[]); +int ZnQueryAttribute(struct _WidgetInfo *wi, void *record, ZnAttrConfig *attr_desc, + Tcl_Obj *attr_name); +void ZnInitTransformStack(struct _WidgetInfo *wi); +void ZnFreeTransformStack(struct _WidgetInfo *wi); +void ZnResetTransformStack(struct _WidgetInfo *wi); +void ZnPushTransform(struct _WidgetInfo *wi, struct _ZnTransfo *transfo, + ZnBool compose_scale, ZnBool compose_rot); +void ZnPopTransform(struct _WidgetInfo *wi); +void ZnInitClipStack(struct _WidgetInfo *wi); +void ZnFreeClipStack(struct _WidgetInfo *wi); +void ZnResetClipStack(struct _WidgetInfo *wi); +void ZnPushClip(struct _WidgetInfo *wi, ZnTriStrip *tristrip, ZnBool simple, + ZnBool set_gc); +void ZnPopClip(struct _WidgetInfo *wi, ZnBool set_gc); +ZnBool ZnCurrentClip(struct _WidgetInfo *wi, Region *reg, ZnBBox **clip_box, + ZnBool *simple); extern ZnItemClassId ZnArc; |