aboutsummaryrefslogtreecommitdiff
path: root/generic/Window.c
diff options
context:
space:
mode:
authorlecoanet2000-05-26 07:52:39 +0000
committerlecoanet2000-05-26 07:52:39 +0000
commitf219d7b312c32643d01ea6e91e45bb6681cd5186 (patch)
tree4e8a84641bcc260fc1dc6524ce6622c859c65061 /generic/Window.c
parent115089811374191cbbe3c5752502621b9c972ecb (diff)
downloadtkzinc-f219d7b312c32643d01ea6e91e45bb6681cd5186.zip
tkzinc-f219d7b312c32643d01ea6e91e45bb6681cd5186.tar.gz
tkzinc-f219d7b312c32643d01ea6e91e45bb6681cd5186.tar.bz2
tkzinc-f219d7b312c32643d01ea6e91e45bb6681cd5186.tar.xz
Nouvel item fenetre.
Diffstat (limited to 'generic/Window.c')
-rw-r--r--generic/Window.c688
1 files changed, 688 insertions, 0 deletions
diff --git a/generic/Window.c b/generic/Window.c
new file mode 100644
index 0000000..9cc8e7f
--- /dev/null
+++ b/generic/Window.c
@@ -0,0 +1,688 @@
+/*
+ * Window.c -- Implementation of Window item.
+ *
+ * Authors : Patrick LECOANET
+ * Creation date : Fri May 12 11:25:53 2000
+ */
+
+/*
+ * Copyright (c) 1993 - 2000 CENA, Patrick Lecoanet --
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this code; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <malloc.h>
+
+#include "Item.h"
+#include "Geo.h"
+#include "Types.h"
+#include "WidgetInfo.h"
+
+
+static const char rcsid[] = "$Id$";
+static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
+
+/*
+ **********************************************************************************
+ *
+ * Specific Window item record
+ *
+ **********************************************************************************
+ */
+typedef struct _WindowItemStruct {
+ ItemStruct header;
+
+ /* Public data */
+ ZnPoint pos;
+ ZnAnchor anchor;
+ ZnAnchor connection_anchor;
+ ZnWindow win;
+ int width;
+ int height;
+
+ /* Private data */
+ ZnPoint pos_dev;
+ int real_width;
+ int real_height;
+} WindowItemStruct, *WindowItem;
+
+
+static ZnAttrConfig wind_attrs[] = {
+ { ZN_CONFIG_ANCHOR, "-anchor", NULL,
+ Tk_Offset(WindowItemStruct, anchor), 0, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_BOOL, "-composerotation", NULL,
+ Tk_Offset(WindowItemStruct, header.flags), COMPOSE_ROTATION_BIT,
+ ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_BOOL, "-composescale", NULL,
+ Tk_Offset(WindowItemStruct, header.flags), COMPOSE_SCALE_BIT,
+ ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_ITEM, "-connecteditem", NULL,
+ Tk_Offset(WindowItemStruct, header.connected_item), 0,
+ ZN_COORDS_FLAG|ZN_ITEM_FLAG, False },
+ { ZN_CONFIG_ANCHOR, "-connectionanchor", NULL,
+ Tk_Offset(WindowItemStruct, connection_anchor), 0, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_DIM, "-height", NULL,
+ Tk_Offset(WindowItemStruct, height), 0, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_POINT, "-position", NULL, Tk_Offset(WindowItemStruct, pos), 0,
+ ZN_COORDS_FLAG, False},
+ { ZN_CONFIG_PRI, "-priority", NULL,
+ Tk_Offset(WindowItemStruct, header.priority), 0,
+ ZN_DRAW_FLAG|ZN_REPICK_FLAG, False },
+ { ZN_CONFIG_BOOL, "-sensitive", NULL,
+ Tk_Offset(WindowItemStruct, header.flags), SENSITIVE_BIT,
+ ZN_REPICK_FLAG, False },
+ { ZN_CONFIG_TAGS, "-tags", NULL,
+ Tk_Offset(WindowItemStruct, header.tags), 0, 0, False },
+ { ZN_CONFIG_BOOL, "-visible", NULL,
+ Tk_Offset(WindowItemStruct, header.flags), VISIBLE_BIT,
+ ZN_DRAW_FLAG|ZN_REPICK_FLAG|ZN_VIS_FLAG, False },
+ { ZN_CONFIG_DIM, "-width", NULL,
+ Tk_Offset(WindowItemStruct, width), 0, ZN_COORDS_FLAG, False },
+ { ZN_CONFIG_WINDOW, "-window", NULL,
+ Tk_Offset(WindowItemStruct, win), 0,
+ ZN_COORDS_FLAG|ZN_WINDOW_FLAG, False },
+
+ { ZN_CONFIG_END, NULL, NULL, 0, 0, 0 }
+};
+
+
+/*
+ **********************************************************************************
+ *
+ * WindowDeleted --
+ *
+ * Do the bookeeping after a managed window deletion.
+ *
+ **********************************************************************************
+ */
+static void
+WindowDeleted(ClientData client_data,
+ XEvent *event)
+{
+ WindowItem wind = (WindowItem) client_data;
+
+ if (event->type == DestroyNotify) {
+ wind->win = NULL;
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Window item geometry manager --
+ *
+ **********************************************************************************
+ */
+
+/*
+ * A managed window changes requested dimensions.
+ */
+static void
+WindowItemRequest(ClientData client_data,
+ ZnWindow win)
+{
+ WindowItem wind = (WindowItem) client_data;
+
+ ITEM.Invalidate((Item) wind, ZN_COORDS_FLAG);
+}
+
+/*
+ * A managed window turns control over
+ * to another geometry manager.
+ */
+static void
+WindowItemLostSlave(ClientData client_data,
+ ZnWindow win)
+{
+ WindowItem wind = (WindowItem) client_data;
+ WidgetInfo *wi = ((Item) wind)->wi;
+
+ Tk_DeleteEventHandler(wi->win, StructureNotifyMask, WindowDeleted,
+ (ClientData) wind);
+ if (wi->win != Tk_Parent(wind->win)) {
+ Tk_UnmaintainGeometry(wind->win, wi->win);
+ }
+ Tk_UnmapWindow(wind->win);
+ wind->win = NULL;
+}
+
+static Tk_GeomMgr wind_geom_type = {
+ "zincwindow", /* name */
+ WindowItemRequest, /* requestProc */
+ WindowItemLostSlave, /* lostSlaveProc */
+};
+
+
+/*
+ **********************************************************************************
+ *
+ * Init --
+ *
+ **********************************************************************************
+ */
+static int
+Init(Item item,
+ int *argc,
+ Arg **args)
+{
+ WindowItem wind = (WindowItem) item;
+
+ /* Init attributes */
+ SET(item->flags, VISIBLE_BIT);
+ SET(item->flags, SENSITIVE_BIT);
+ SET(item->flags, COMPOSE_ROTATION_BIT);
+ SET(item->flags, COMPOSE_SCALE_BIT);
+ item->priority = DEFAULT_WINDOW_PRIORITY; /* N.A */
+
+ wind->pos.x = wind->pos.y = 0.0;
+ wind->width = wind->height = 0;
+ wind->anchor = ZnAnchorNW;
+ wind->connection_anchor = ZnAnchorSW;
+ wind->win = NULL;
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Clone --
+ *
+ **********************************************************************************
+ */
+static void
+Clone(Item item)
+{
+ WindowItem wind = (WindowItem) item;
+
+ /*
+ * The same Tk widget can't be shared by to Window items.
+ */
+ wind->win = NULL;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Destroy --
+ *
+ **********************************************************************************
+ */
+static void
+Destroy(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+ /*
+ * Unmanage the widget.
+ */
+ if (wind->win) {
+ Tk_DeleteEventHandler(wind->win, StructureNotifyMask, WindowDeleted,
+ (ClientData) item);
+ Tk_ManageGeometry(wind->win, (Tk_GeomMgr *) NULL, (ClientData) NULL);
+ if (wi->win != Tk_Parent(wind->win)) {
+ Tk_UnmaintainGeometry(wind->win, wi->win);
+ }
+ Tk_UnmapWindow(wind->win);
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Configure --
+ *
+ **********************************************************************************
+ */
+static int
+Configure(Item item,
+ int argc,
+ ZnAttrList argv,
+ int *flags)
+{
+ WindowItem wind = (WindowItem) item;
+ WidgetInfo *wi = item->wi;
+ Item old_connected;
+ ZnWindow old_win;
+
+ old_connected = item->connected_item;
+ old_win = wind->win;
+ if (ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags) == ZN_ERROR) {
+ return ZN_ERROR;
+ }
+
+ if (ISSET(*flags, ZN_ITEM_FLAG)) {
+ /*
+ * If the new connected item is not appropriate back up
+ * to the old one.
+ */
+ if ((item->connected_item == ZN_NO_ITEM) ||
+ (item->connected_item->class->has_anchors &&
+ (item->parent == item->connected_item->parent))) {
+ ITEM.UpdateItemDependency(item, old_connected);
+ }
+ else {
+ item->connected_item = old_connected;
+ }
+ }
+
+ if (ISSET(*flags, ZN_WINDOW_FLAG)) {
+ if (old_win != NULL) {
+ Tk_DeleteEventHandler(old_win, StructureNotifyMask,
+ WindowDeleted, (ClientData) item);
+ Tk_ManageGeometry(old_win, (Tk_GeomMgr *) NULL, (ClientData) NULL);
+ Tk_UnmaintainGeometry(old_win, wi->win);
+ Tk_UnmapWindow(old_win);
+ }
+ if (wind->win != NULL) {
+ Tk_CreateEventHandler(wind->win, StructureNotifyMask,
+ WindowDeleted, (ClientData) item);
+ Tk_ManageGeometry(wind->win, &wind_geom_type, (ClientData) item);
+ }
+ }
+
+ if ((wind->win != NULL) &&
+ ISSET(*flags, ZN_VIS_FLAG) &&
+ ISCLEAR(item->flags, VISIBLE_BIT)) {
+ Tk_UnmapWindow(wind->win);
+ }
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Query --
+ *
+ **********************************************************************************
+ */
+static int
+Query(Item item,
+ int argc,
+ ZnAttrList argv)
+{
+ if (ITEM_P.QueryAttribute((char *) item, -1, argv[0]) == ZN_ERROR) {
+ return ZN_ERROR;
+ }
+
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * ComputeCoordinates --
+ *
+ **********************************************************************************
+ */
+static void
+ComputeCoordinates(Item item,
+ ZnBool force)
+{
+ WidgetInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+ ResetBBox(&item->item_bounding_box);
+
+ if (wind->win == NULL) {
+ return;
+ }
+
+ wind->real_width = wind->width;
+ if (wind->real_width <= 0) {
+ wind->real_width = Tk_ReqWidth(wind->win);
+ if (wind->real_width <= 0) {
+ wind->real_width = 1;
+ }
+ }
+ wind->real_height = wind->height;
+ if (wind->real_height <= 0) {
+ wind->real_height = Tk_ReqHeight(wind->win);
+ if (wind->real_height <= 0) {
+ wind->real_height = 1;
+ }
+ }
+
+ /*
+ * The connected item support anchors, this is checked by
+ * configure.
+ */
+ if (item->connected_item != ZN_NO_ITEM) {
+ item->connected_item->class->GetAnchor(item->connected_item,
+ wind->connection_anchor,
+ &wind->pos_dev);
+ }
+ else {
+ ZnTransformPoint(wi->current_transfo, &wind->pos, &wind->pos_dev);
+ }
+
+ Anchor2Origin(&wind->pos_dev, wind->real_width, wind->real_height, wind->anchor,
+ &wind->pos_dev);
+ wind->pos_dev.x = REAL_TO_INT(wind->pos_dev.x);
+ wind->pos_dev.y = REAL_TO_INT(wind->pos_dev.y);
+
+ /*
+ * Compute the bounding box.
+ */
+ AddPointToBBox(&item->item_bounding_box, wind->pos_dev.x, wind->pos_dev.y);
+ AddPointToBBox(&item->item_bounding_box, wind->pos_dev.x+wind->real_width,
+ wind->pos_dev.y+wind->real_height);
+ item->item_bounding_box.orig.x -= 1.0;
+ item->item_bounding_box.orig.y -= 1.0;
+ item->item_bounding_box.corner.x += 1.0;
+ item->item_bounding_box.corner.y += 1.0;
+
+ /*
+ * Update connected items.
+ */
+ SET(item->flags, UPDATE_DEPENDENT_BIT);
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * ToArea --
+ * Tell if the object is entirely outside (-1),
+ * entirely inside (1) or in between (0).
+ *
+ **********************************************************************************
+ */
+static int
+ToArea(Item item,
+ ZnBBox *area,
+ Tk_Uid tag_uid,
+ int enclosed,
+ ZnBool report)
+{
+ WindowItem wind = (WindowItem) item;
+ ZnBBox box;
+ int w=0, h=0;
+
+ box.orig = wind->pos_dev;
+ if (wind->win != NULL) {
+ w = wind->real_width;
+ h = wind->real_height;
+ }
+ box.corner.x = box.orig.x + w;
+ box.corner.y = box.orig.y + h;
+
+ return BBoxInBBox(&box, area);
+}
+
+/*
+ **********************************************************************************
+ *
+ * Draw --
+ *
+ **********************************************************************************
+ */
+static void
+Draw(Item item)
+{
+ WidgetInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+ if (wind->win == NULL) {
+ return;
+ }
+
+ /*
+ * If the window is outside the visible area, unmap it.
+ */
+ if ((item->item_bounding_box.corner.x <= 0) ||
+ (item->item_bounding_box.corner.y <= 0) ||
+ (item->item_bounding_box.orig.x >= wi->width) ||
+ (item->item_bounding_box.orig.y >= wi->height)) {
+ if (wi->win == Tk_Parent(wind->win)) {
+ Tk_UnmapWindow(wind->win);
+ }
+ else {
+ Tk_UnmaintainGeometry(wind->win, wi->win);
+ }
+ return;
+ }
+
+ /*
+ * Position and map the window.
+ */
+ if (wi->win == Tk_Parent(wind->win)) {
+ if ((wind->pos_dev.x != Tk_X(wind->win)) ||
+ (wind->pos_dev.y != Tk_Y(wind->win)) ||
+ (wind->real_width != Tk_Width(wind->win)) ||
+ (wind->real_height != Tk_Height(wind->win))) {
+ Tk_MoveResizeWindow(wind->win,
+ wind->pos_dev.x, wind->pos_dev.y,
+ wind->real_width, wind->real_height);
+ }
+ Tk_MapWindow(wind->win);
+ }
+ else {
+ Tk_MaintainGeometry(wind->win, wi->win,
+ wind->pos_dev.x, wind->pos_dev.y,
+ wind->real_width, wind->real_height);
+ }
+
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * IsSensitive --
+ *
+ **********************************************************************************
+ */
+static ZnBool
+IsSensitive(Item item,
+ int item_part)
+{
+ /*
+ * Sensitivity can't be controlled.
+ */
+ return True;
+}
+
+/*
+ **********************************************************************************
+ *
+ * Pick --
+ *
+ **********************************************************************************
+ */
+static double
+Pick(Item item,
+ ZnPoint *p,
+ Item start_item,
+ int aperture,
+ Item *a_item,
+ int *part)
+{
+ WindowItem wind = (WindowItem) item;
+ ZnBBox box;
+ ZnReal dist = 1e40;
+
+ box.orig = wind->pos_dev;
+ if (wind->win != NULL) {
+ box.corner.x = box.orig.x + wind->real_width;
+ box.corner.y = box.orig.y + wind->real_height;
+ dist = RectangleToPointDist(&box, p);
+ if (dist <= 0.0) {
+ dist = 0.0;
+ }
+ }
+ return dist;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * PostScript --
+ *
+ **********************************************************************************
+ */
+static void
+PostScript(Item item,
+ PostScriptInfo ps_info)
+{
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetAnchor --
+ *
+ **********************************************************************************
+ */
+static void
+GetAnchor(Item item,
+ ZnAnchor anchor,
+ ZnPoint *p)
+{
+ WindowItem wind = (WindowItem) item;
+
+ if (wind->win != NULL) {
+ Origin2Anchor(&wind->pos_dev, wind->real_width,
+ wind->real_height, anchor, p);
+ }
+ else {
+ p->x = p->y = 0.0;
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetClipVertices --
+ * Get the clipping shape.
+ *
+ **********************************************************************************
+ */
+static ZnBool
+GetClipVertices(Item item,
+ ZnPoly *poly)
+{
+ WindowItem wind = (WindowItem) item;
+ int w=0, h=0;
+ ZnPoint *points;
+
+ ZnListAssertSize(item->wi->work_pts, 2);
+ if (wind->win != NULL) {
+ w = wind->real_width;
+ h = wind->real_height;
+ }
+ points = (ZnPoint *) ZnListArray(item->wi->work_pts);
+ POLY_CONTOUR1(poly, points, 2);
+ points[0] = wind->pos_dev;
+ points[1].x = points[0].x + w;
+ points[1].y = points[0].y + h;
+
+ return True;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Coords --
+ * Return or edit the item origin. This doesn't take care of
+ * the possible attachment. The change will be effective at the
+ * end of the attachment.
+ *
+ **********************************************************************************
+ */
+static int
+Coords(Item item,
+ int contour,
+ int index,
+ int cmd,
+ ZnPoint **pts,
+ int *num_pts)
+{
+ WindowItem wind = (WindowItem) item;
+
+ if ((cmd == COORDS_ADD) || (cmd == COORDS_ADD_LAST) || (cmd == COORDS_REMOVE)) {
+ Tcl_AppendResult(item->wi->interp,
+ " windows can't add or remove vertices", NULL);
+ return ZN_ERROR;
+ }
+ else if ((cmd == COORDS_REPLACE) || (cmd == COORDS_REPLACE_ALL)) {
+ if (*num_pts == 0) {
+ Tcl_AppendResult(item->wi->interp,
+ " coords command need 1 point on windows", NULL);
+ return ZN_ERROR;
+ }
+ wind->pos = (*pts)[0];
+ ITEM.Invalidate(item, ZN_COORDS_FLAG);
+ }
+ else if ((cmd == COORDS_READ) || (cmd == COORDS_READ_ALL)) {
+ *num_pts = 1;
+ *pts = &wind->pos;
+ }
+ return ZN_OK;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * Exported functions struct --
+ *
+ **********************************************************************************
+ */
+static ItemClassStruct WINDOW_ITEM_CLASS = {
+ sizeof(WindowItemStruct),
+ False, /* has_fields */
+ False, /* has_parts */
+ True, /* has_anchors */
+ "window",
+ wind_attrs,
+ Init,
+ Clone,
+ Destroy,
+ Configure,
+ Query,
+ NULL, /* GetFieldSet */
+ GetAnchor,
+ GetClipVertices,
+ Coords,
+ NULL, /* InsertChars */
+ NULL, /* DeleteChars */
+ NULL, /* Cursor */
+ NULL, /* Index */
+ NULL, /* Selection */
+ NULL, /* Contour */
+ ComputeCoordinates,
+ ToArea,
+ Draw,
+ IsSensitive,
+ Pick,
+ NULL, /* PickVertex */
+ PostScript
+};
+
+ZnItemClassId ZnWind = (ZnItemClassId) &WINDOW_ITEM_CLASS;