1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 /* Lefteris Koutsofios - AT&T Labs Research */
15 
16 #include "common.h"
17 #include "g.h"
18 #include "gcommon.h"
19 #include "mem.h"
20 
GScreatewidget(Gwidget_t * parent,Gwidget_t * widget,int attrn,Gwattr_t * attrp)21 int GScreatewidget (
22     Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp
23 ) {
24     PIXsize_t ps;
25     DWORD wflags;
26     int ai;
27 
28     if (!parent) {
29         Gerr (POS, G_ERRNOPARENTWIDGET);
30         return -1;
31     }
32     wflags = WS_CHILDWINDOW | WS_HSCROLL | WS_VSCROLL;
33     ps.x = ps.y = MINSWSIZE;
34     for (ai = 0; ai < attrn; ai++) {
35         switch (attrp[ai].id) {
36         case G_ATTRSIZE:
37             GETSIZE (attrp[ai].u.s, ps, MINSWSIZE);
38             break;
39         case G_ATTRBORDERWIDTH:
40             wflags |= WS_BORDER;
41             break;
42         case G_ATTRCHILDCENTER:
43             Gerr (POS, G_ERRCANNOTSETATTR1, "childcenter");
44             return -1;
45         case G_ATTRMODE:
46             if (strcmp ("forcebars", attrp[ai].u.t) != 0) {
47                 Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
48                 return -1;
49             }
50             break;
51         case G_ATTRWINDOWID:
52             Gerr (POS, G_ERRCANNOTSETATTR1, "windowid");
53             return -1;
54         case G_ATTRUSERDATA:
55             widget->udata = attrp[ai].u.u;
56             break;
57         default:
58             Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
59             return -1;
60         }
61     }
62     Gadjustwrect (parent, &ps);
63     if (!(widget->w = CreateWindow (
64         "ScrollClass", "scroll", wflags, 0, 0,
65         ps.x, ps.y, parent->w, (HMENU) (widget - &Gwidgets[0]),
66         hinstance, NULL
67     ))) {
68         Gerr (POS, G_ERRCANNOTCREATEWIDGET);
69         return -1;
70     }
71     ShowWindow (widget->w, SW_SHOW);
72     UpdateWindow (widget->w);
73     if (parent && parent->type == G_ARRAYWIDGET)
74         Gawinsertchild (parent, widget);
75     return 0;
76 }
77 
GSsetwidgetattr(Gwidget_t * widget,int attrn,Gwattr_t * attrp)78 int GSsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
79     Gwidget_t *parent, *child;
80     PIXpoint_t po;
81     PIXsize_t ps, pps, cps;
82     RECT r;
83     DWORD wflags1, wflags2;
84     int ai, wi;
85 
86     parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi];
87     wflags1 = SWP_NOMOVE | SWP_NOZORDER;
88     wflags2 = SWP_NOSIZE | SWP_NOZORDER;
89     for (ai = 0; ai < attrn; ai++) {
90         switch (attrp[ai].id) {
91         case G_ATTRSIZE:
92             GETSIZE (attrp[ai].u.s, ps, MINSWSIZE);
93             Gadjustwrect (parent, &ps);
94             SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps.x, ps.y, wflags1);
95             break;
96         case G_ATTRBORDERWIDTH:
97             Gerr (POS, G_ERRCANNOTSETATTR2, "borderwidth");
98             return -1;
99         case G_ATTRCHILDCENTER:
100             for (wi = 0; wi < Gwidgetn; wi++) {
101                 child = &Gwidgets[wi];
102                 if (child->inuse && child->pwi == widget - &Gwidgets[0])
103                     break;
104             }
105             if (wi == Gwidgetn)
106                 return 0;
107             GETORIGIN (attrp[ai].u.p, po);
108             GetClientRect (widget->w, &r);
109             pps.x = r.right - r.left, pps.y = r.bottom - r.top;
110             po.x -= pps.x / 2, po.y -= pps.y / 2;
111             GetWindowRect (child->w, &r);
112             cps.x = r.right - r.left, cps.y = r.bottom - r.top;
113             if (po.x < 0)
114                 po.x = 0;
115             if (po.y < 0)
116                 po.y = 0;
117             if (po.x > cps.x - pps.x)
118                 po.x = cps.x - pps.x;
119             if (po.y > cps.y - pps.y)
120                 po.y = cps.y - pps.y;
121             SetWindowPos (child->w, (HWND) NULL, -po.x, -po.y, 0, 0, wflags2);
122             SetScrollPos (widget->w, SB_HORZ, po.x, TRUE);
123             SetScrollPos (widget->w, SB_VERT, po.y, TRUE);
124             break;
125         case G_ATTRMODE:
126             if (strcmp ("forcebars", attrp[ai].u.t) != 0) {
127                 Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
128                 return -1;
129             }
130             break;
131         case G_ATTRWINDOWID:
132             Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");
133             return -1;
134         case G_ATTRUSERDATA:
135             widget->udata = attrp[ai].u.u;
136             break;
137         default:
138             Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
139             return -1;
140         }
141     }
142     return 0;
143 }
144 
GSgetwidgetattr(Gwidget_t * widget,int attrn,Gwattr_t * attrp)145 int GSgetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
146     Gwidget_t *child;
147     RECT r;
148     int width, height, ai, wi;
149 
150     for (ai = 0; ai < attrn; ai++) {
151         switch (attrp[ai].id) {
152         case G_ATTRSIZE:
153             GetWindowRect (widget->w, &r);
154             attrp[ai].u.s.x = r.right - r.left;
155             attrp[ai].u.s.y = r.bottom - r.top;
156             break;
157         case G_ATTRBORDERWIDTH:
158             Gerr (POS, G_ERRCANNOTGETATTR, "borderwidth");
159             return -1;
160         case G_ATTRCHILDCENTER:
161             for (wi = 0; wi < Gwidgetn; wi++) {
162                 child = &Gwidgets[wi];
163                 if (child->inuse && child->pwi == widget - &Gwidgets[0])
164                     break;
165             }
166             if (wi == Gwidgetn) {
167                 Gerr (POS, G_ERRNOCHILDWIDGET);
168                 return -1;
169             }
170             GetWindowRect (widget->w, &r);
171             width = r.right - r.left;
172             height = r.bottom - r.top;
173             GetWindowRect (widget->w, &r);
174             attrp[ai].u.p.x = width / 2 - r.left;
175             attrp[ai].u.p.y = height / 2 - r.top;
176             break;
177         case G_ATTRMODE:
178             attrp[ai].u.t = "forcebars";
179             break;
180         case G_ATTRWINDOWID:
181             sprintf (&Gbufp[0], "0x%lx", widget->w);
182             attrp[ai].u.t = &Gbufp[0];
183             break;
184         case G_ATTRUSERDATA:
185             attrp[ai].u.u = widget->udata;
186             break;
187         default:
188             Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
189             return -1;
190         }
191     }
192     return 0;
193 }
194 
GSdestroywidget(Gwidget_t * widget)195 int GSdestroywidget (Gwidget_t *widget) {
196     Gwidget_t *parent;
197 
198     parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi];
199     if (parent && parent->type == G_ARRAYWIDGET)
200         Gawdeletechild (parent, widget);
201     DestroyWindow (widget->w);
202     return 0;
203 }
204