1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/animate.c,v 1.6 2011/05/16 16:21:56 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_ANIMATE_C_
22 
23 #include "tgifdefs.h"
24 
25 #include "animate.e"
26 #include "color.e"
27 #include "dialog.e"
28 #include "msg.e"
29 #include "poly.e"
30 #include "raster.e"
31 #include "select.e"
32 #include "setup.e"
33 #include "strtbl.e"
34 
35 #define SEND_SPEED 8
36 
37 #define TOKEN_R 8
38 
39 static XPoint	savedToken[5];
40 
AnimateSend(PolyPtr,Speed,Pixel)41 void AnimateSend(PolyPtr, Speed, Pixel)
42    struct PolyRec *PolyPtr;
43    int Speed, Pixel;
44 {
45    register int delta, i;
46    register XPoint *token;
47    int x, y, num_pts, j, x_dist, y_dist;
48    IntPoint *v;
49    struct BBRec bbox;
50    double slope, delta_x, delta_y;
51    XGCValues values;
52 
53    values.foreground = Pixel;
54    values.function = GXxor;
55    values.line_style = FillSolid;
56 #ifdef NO_THIN_LINE
57    values.line_width = 1;
58 #else
59    values.line_width = 0;
60 #endif
61    XChangeGC(mainDisplay, drawGC,
62          GCForeground | GCFunction | GCLineStyle | GCLineWidth, &values);
63 
64    bbox.ltx = 0; bbox.lty = 0; bbox.rbx = 2*TOKEN_R; bbox.rby = 2*TOKEN_R;
65 
66    num_pts = PolyPtr->n;
67    v = PolyPtr->vlist;
68    token = (XPoint *)malloc(5*sizeof(XPoint));
69    if (token == NULL) FailAllocMessage();
70 
71    for (j = 0; j < num_pts-1; j++) {
72       x = OFFSET_X(v[j].x);
73       y = OFFSET_Y(v[j].y);
74       token[0].x = (short)(x - TOKEN_R); token[0].y = (short)(y - TOKEN_R);
75       token[1].x = (short)(x + TOKEN_R); token[1].y = (short)(y - TOKEN_R);
76       token[2].x = (short)(x + TOKEN_R); token[2].y = (short)(y + TOKEN_R);
77       token[3].x = (short)(x - TOKEN_R); token[3].y = (short)(y + TOKEN_R);
78       token[4].x = (short)(x - TOKEN_R); token[4].y = (short)(y - TOKEN_R);
79       XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
80             CoordModeOrigin);
81       if (v[j].x == v[j+1].x) {
82          /* moving vertical */
83          if ((y_dist = ZOOMED_SIZE(v[j+1].y-v[j].y)) > 0) {
84             /* moving down */
85             for (delta = 0; delta < y_dist; delta += Speed) {
86                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
87                      CoordModeOrigin);
88                for (i = 0; i < 5; i++) token[i].y += Speed;
89                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
90                      CoordModeOrigin);
91             }
92          } else {
93             /* moving up */
94             for (delta = y_dist; delta < 0; delta += Speed) {
95                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
96                      CoordModeOrigin);
97                for (i = 0; i < 5; i++) token[i].y -= Speed;
98                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
99                      CoordModeOrigin);
100             }
101          }
102       } else if (v[j].y == v[j+1].y) {
103          /* moving horizontal */
104          if ((x_dist = ZOOMED_SIZE(v[j+1].x-v[j].x)) > 0) {
105             /* moving right */
106             for (delta = 0; delta < x_dist; delta += Speed) {
107                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
108                      CoordModeOrigin);
109                for (i = 0; i < 5; i++) token[i].x += Speed;
110                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
111                      CoordModeOrigin);
112             }
113          } else {
114             /* moving left */
115             for (delta = x_dist; delta < 0; delta += Speed) {
116                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
117                      CoordModeOrigin);
118                for (i = 0; i < 5; i++) token[i].x -= Speed;
119                XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
120                      CoordModeOrigin);
121             }
122          }
123       } else {
124          /* moving diagonally */
125          x_dist = ZOOMED_SIZE(v[j+1].x-v[j].x);
126          y_dist = ZOOMED_SIZE(v[j+1].y-v[j].y);
127          for (i = 0; i < 5; i++) {
128             savedToken[i].x = token[i].x;
129             savedToken[i].y = token[i].y;
130          }
131          if (abs(x_dist) > abs(y_dist)) {
132             /* moving in the x direction */
133             slope = ((double)y_dist) / ((double)x_dist);
134             if (x_dist > 0) {
135                /* moving right */
136                for (delta = 0; delta < x_dist; delta += Speed) {
137                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
138                         Convex, CoordModeOrigin);
139                   delta_y = slope * ((double)delta);
140                   for (i = 0; i < 5; i++) {
141                      token[i].x = savedToken[i].x + delta;
142                      token[i].y = savedToken[i].y + delta_y;
143                   }
144                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
145                         Convex, CoordModeOrigin);
146                }
147             } else {
148                /* moving left */
149                for (delta = 0; delta > x_dist; delta -= Speed) {
150                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
151                         Convex, CoordModeOrigin);
152                   delta_y = slope * ((double)delta);
153                   for (i = 0; i < 5; i++) {
154                      token[i].x = savedToken[i].x + delta;
155                      token[i].y = savedToken[i].y + delta_y;
156                   }
157                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
158                         Convex, CoordModeOrigin);
159                }
160             }
161          } else {
162             /* moving in the y direction */
163             slope = ((double)x_dist) / ((double)y_dist);
164             if (y_dist > 0) {
165                /* moving down */
166                for (delta = 0; delta < y_dist; delta += Speed) {
167                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
168                         Convex, CoordModeOrigin);
169                   delta_x = slope * ((double)delta);
170                   for (i = 0; i < 5; i++) {
171                      token[i].x = savedToken[i].x + delta_x;
172                      token[i].y = savedToken[i].y + delta;
173                   }
174                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
175                         Convex, CoordModeOrigin);
176                }
177             } else {
178                /* moving up */
179                for (delta = 0; delta > y_dist; delta -= Speed) {
180                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
181                         Convex, CoordModeOrigin);
182                   delta_x = slope * ((double)delta);
183                   for (i = 0; i < 5; i++) {
184                      token[i].x = savedToken[i].x + delta_x;
185                      token[i].y = savedToken[i].y + delta;
186                   }
187                   XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5,
188                         Convex, CoordModeOrigin);
189                }
190             }
191          }
192       }
193       XFillPolygon(mainDisplay, drawWindow, drawGC, token, 5, Convex,
194             CoordModeOrigin);
195    }
196    free(token);
197 }
198 
AnimateSel()199 void AnimateSel()
200 {
201    if (topSel != botSel || topSel == NULL || topSel->obj->type != OBJ_POLY) {
202       MsgBox(TgLoadString(STID_SELECT_ONLY_ONE_POLY), TOOL_NAME, INFO_MB);
203       return;
204    }
205    AnimateSend(topSel->obj->detail.p, SEND_SPEED,
206          xorColorPixels[topSel->obj->color]);
207 }
208 
AnimateFlashColor(ObjPtr,ColorIndex)209 void AnimateFlashColor(ObjPtr, ColorIndex)
210    struct ObjRec *ObjPtr;
211    int ColorIndex;
212 {
213    int saved_color_index = ObjPtr->color;
214 
215    ObjPtr->color = ColorIndex;
216    DrawPolyObj(drawWindow, drawOrigX, drawOrigY, ObjPtr);
217    ObjPtr->color = saved_color_index;
218    DrawPolyObj(drawWindow, drawOrigX, drawOrigY, ObjPtr);
219 }
220 
FlashSelColor()221 void FlashSelColor()
222    /* This routine is kind of stupid.  It's left for compatibity reason. */
223 {
224    register int i;
225 
226    if (topSel != botSel || topSel == NULL || topSel->obj->type != OBJ_POLY) {
227       MsgBox(TgLoadString(STID_SELECT_ONLY_ONE_POLY), TOOL_NAME, INFO_MB);
228       return;
229    }
230    for (i = 0; i < maxColors; i++) {
231       if (strcmp("white", colorMenuItems[i]) == 0) {
232          break;
233       }
234    }
235    AnimateFlashColor(topSel->obj, i);
236 }
237