1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "st_edit.hh"
|
---|
10 | #include "m1_info.hh"
|
---|
11 | #include "window/window.hh"
|
---|
12 | #include "gtext_load.hh"
|
---|
13 | #include "image/image.hh"
|
---|
14 | #include "max_object.hh"
|
---|
15 | #include "window/win_evt.hh"
|
---|
16 | #include "device/kernel.hh"
|
---|
17 | #include "render.hh"
|
---|
18 | #include "app/app.hh"
|
---|
19 | #include "window/wmanager.hh"
|
---|
20 | #include "gui/text_input.hh"
|
---|
21 | #include "tmanage.hh"
|
---|
22 |
|
---|
23 | #define HANDLE_SIZE 3
|
---|
24 | #define SNAP_DISTANCE 5
|
---|
25 |
|
---|
26 | i4_float m1_st_edit_window_class::twidth() const
|
---|
27 | {
|
---|
28 | return (texture)? texture->width()-0.0001 : 255.9999;
|
---|
29 | }
|
---|
30 |
|
---|
31 | i4_float m1_st_edit_window_class::theight() const
|
---|
32 | {
|
---|
33 | return (texture)? texture->height()-0.0001 : 255.9999;
|
---|
34 | }
|
---|
35 |
|
---|
36 | void m1_st_edit_window_class::get_point(int poly, int num, int &x, int &y)
|
---|
37 | {
|
---|
38 | if (m1_info.obj)
|
---|
39 | {
|
---|
40 | g1_quad_class *q=m1_info.obj->quad+poly;
|
---|
41 | float tw=twidth(), th=theight();
|
---|
42 |
|
---|
43 | x=(int)(q->u[num] * tw);
|
---|
44 | y=(int)(q->v[num] * th);
|
---|
45 | }
|
---|
46 | }
|
---|
47 |
|
---|
48 | void m1_st_edit_window_class::draw(i4_draw_context_class &context)
|
---|
49 | {
|
---|
50 | local_image->clear(0, context);
|
---|
51 |
|
---|
52 | if (texture)
|
---|
53 | texture->put_image(local_image, 0,0, context);
|
---|
54 |
|
---|
55 | if (m1_info.obj)
|
---|
56 | {
|
---|
57 | w32 c=0x0000ff; //(254<<16)|(2<<8)|166;
|
---|
58 | int x1,y1,x2,y2;
|
---|
59 |
|
---|
60 | for (int j=0; j<m1_info.obj->num_quad; j++)
|
---|
61 | {
|
---|
62 | if (m1_info.obj->quad[j].get_flags(g1_quad_class::SELECTED))
|
---|
63 | {
|
---|
64 | int i;
|
---|
65 |
|
---|
66 | g1_quad_class *q=&m1_info.obj->quad[j];
|
---|
67 |
|
---|
68 | get_point(j,0,x2,y2);
|
---|
69 | for (i=q->num_verts()-1; i>=0; i--)
|
---|
70 | {
|
---|
71 | get_point(j,i,x1,y1);
|
---|
72 | local_image->line(x1,y1,x2,y2, c, context);
|
---|
73 | x2 = x1; y2 = y1;
|
---|
74 | }
|
---|
75 |
|
---|
76 | for (i=0; i<q->num_verts(); i++)
|
---|
77 | {
|
---|
78 | int x,y;
|
---|
79 | get_point(j,i,x,y);
|
---|
80 | if (m1_info.obj->get_poly_vert_flag(j,1<<i))
|
---|
81 | local_image->bar(x-2,y-2,x+2,y+2, 0xffff00, context);
|
---|
82 | else
|
---|
83 | local_image->bar(x-2,y-2,x+2,y+2, 0x808080, context);
|
---|
84 | }
|
---|
85 | }
|
---|
86 | }
|
---|
87 | if (preselect_x>=0)
|
---|
88 | local_image->bar(preselect_x-2,preselect_y-2,preselect_x+2,preselect_y+2, 0xff00ff, context);
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | void m1_st_edit_window_class::drag_points(int xc, int yc)
|
---|
93 | {
|
---|
94 | m1_poly_object_class *obj=m1_info.obj;
|
---|
95 | if (!obj) return;
|
---|
96 |
|
---|
97 | float tw=twidth(), th=theight();
|
---|
98 | float u_change=xc/tw, v_change=yc/th;
|
---|
99 | i4_bool change=i4_F;
|
---|
100 |
|
---|
101 | for (int i=0; i<m1_info.obj->num_quad; i++)
|
---|
102 | {
|
---|
103 | if (obj->quad[i].get_flags(g1_quad_class::SELECTED))
|
---|
104 | {
|
---|
105 | for (int j=0; j<obj->quad[i].num_verts(); j++)
|
---|
106 | {
|
---|
107 | if (obj->get_poly_vert_flag(i, 1<<j))
|
---|
108 | {
|
---|
109 | obj->quad[i].u[j]+=u_change;
|
---|
110 | if (obj->quad[i].u[j]<0) obj->quad[i].u[j]=0;
|
---|
111 | if (obj->quad[i].u[j]>1) obj->quad[i].u[j]=1;
|
---|
112 |
|
---|
113 | obj->quad[i].v[j]+=v_change;
|
---|
114 | if (obj->quad[i].v[j]<0) obj->quad[i].v[j]=0;
|
---|
115 | if (obj->quad[i].v[j]>1) obj->quad[i].v[j]=1;
|
---|
116 | change=i4_T;
|
---|
117 | }
|
---|
118 | }
|
---|
119 | }
|
---|
120 | }
|
---|
121 |
|
---|
122 | if (change)
|
---|
123 | {
|
---|
124 | obj->calc_texture_scales();
|
---|
125 | request_redraw(i4_F);
|
---|
126 | if (m1_render_window.get())
|
---|
127 | m1_render_window->request_redraw(i4_F);
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | i4_bool m1_st_edit_window_class::verts_are_selected()
|
---|
132 | {
|
---|
133 | if (!m1_info.obj)
|
---|
134 | return 0;
|
---|
135 |
|
---|
136 | for (int j=0; j<m1_info.obj->num_quad; j++)
|
---|
137 | if (m1_info.obj->quad[j].get_flags(g1_quad_class::SELECTED))
|
---|
138 | {
|
---|
139 | for (int i=0; i<m1_info.obj->quad[j].num_verts(); i++)
|
---|
140 | if (m1_info.obj->get_poly_vert_flag(j,1<<i))
|
---|
141 | return i4_T;
|
---|
142 | }
|
---|
143 |
|
---|
144 | return i4_F;
|
---|
145 | }
|
---|
146 |
|
---|
147 | void m1_st_edit_window_class::select_point(int point)
|
---|
148 | {
|
---|
149 | if (!m1_info.obj)
|
---|
150 | return;
|
---|
151 |
|
---|
152 | if (point<0)
|
---|
153 | return;
|
---|
154 |
|
---|
155 | m1_poly_object_class *obj=m1_info.obj;
|
---|
156 |
|
---|
157 | if (!i4_current_app->get_window_manager()->shift_pressed())
|
---|
158 | {
|
---|
159 | for (int j=0; j<obj->num_quad; j++)
|
---|
160 | for (int i=0; i<4; i++)
|
---|
161 | obj->set_poly_vert_flag(j, 1<<i, 0);
|
---|
162 | }
|
---|
163 |
|
---|
164 | for (int j=0; j<obj->num_quad; j++)
|
---|
165 | {
|
---|
166 | g1_quad_class *q=obj->quad+j;
|
---|
167 | if (q->get_flags(g1_quad_class::SELECTED))
|
---|
168 | for (int i=0; i<q->num_verts(); i++)
|
---|
169 | if (q->vertex_ref[i] == point)
|
---|
170 | obj->set_poly_vert_flag(j, 1<<i, 1);
|
---|
171 | }
|
---|
172 |
|
---|
173 | request_redraw();
|
---|
174 | }
|
---|
175 |
|
---|
176 | void m1_st_edit_window_class::change_current_verts()
|
---|
177 | {
|
---|
178 | if (!m1_info.obj)
|
---|
179 | return;
|
---|
180 |
|
---|
181 | int old_px = preselect_x;
|
---|
182 | int old_py = preselect_y;
|
---|
183 |
|
---|
184 | preselect_x = -1;
|
---|
185 |
|
---|
186 | if (m1_info.preselect_point>=0)
|
---|
187 | for (int j=0; j<m1_info.obj->num_quad; j++)
|
---|
188 | if (m1_info.obj->quad[j].get_flags(g1_quad_class::SELECTED))
|
---|
189 | {
|
---|
190 | for (int i=0; i<m1_info.obj->quad[j].num_verts(); i++)
|
---|
191 | if (m1_info.obj->quad[j].vertex_ref[i] == m1_info.preselect_point)
|
---|
192 | get_point(j,i,preselect_x,preselect_y);
|
---|
193 | }
|
---|
194 |
|
---|
195 | if (preselect_x!=old_px || preselect_y!=old_py)
|
---|
196 | request_redraw();
|
---|
197 | }
|
---|
198 |
|
---|
199 | void m1_st_edit_window_class::change_current_texture(i4_const_str new_name)
|
---|
200 | {
|
---|
201 | if (m1_info.obj)
|
---|
202 | {
|
---|
203 | i4_file_class *fp=i4_open(new_name);
|
---|
204 | if (!fp) return;
|
---|
205 | delete fp;
|
---|
206 | int i;
|
---|
207 |
|
---|
208 | for (i=0; i<m1_info.obj->num_quad; i++)
|
---|
209 | if (m1_info.obj->quad[i].get_flags(g1_quad_class::SELECTED))
|
---|
210 | {
|
---|
211 | delete m1_info.obj->texture_names[i];
|
---|
212 | m1_info.obj->texture_names[i]=new i4_str(new_name);
|
---|
213 | }
|
---|
214 |
|
---|
215 | m1_info.texture_list_changed();
|
---|
216 | }
|
---|
217 | }
|
---|
218 |
|
---|
219 |
|
---|
220 | void m1_st_edit_window_class::receive_event(i4_event *ev)
|
---|
221 | {
|
---|
222 | int pre_grab = grab;
|
---|
223 |
|
---|
224 | m1_poly_object_class *obj=m1_info.obj;
|
---|
225 | if (!obj)
|
---|
226 | return ;
|
---|
227 |
|
---|
228 | switch (ev->type())
|
---|
229 | {
|
---|
230 | case i4_event::WINDOW_MESSAGE:
|
---|
231 | {
|
---|
232 | CAST_PTR(wev, i4_window_message_class, ev);
|
---|
233 | if (wev->sub_type==i4_window_message_class::GOT_DROP)
|
---|
234 | i4_kernel.send_event(tname_edit, ev);
|
---|
235 | } break;
|
---|
236 |
|
---|
237 | case i4_event::OBJECT_MESSAGE :
|
---|
238 | {
|
---|
239 | CAST_PTR(tc, i4_text_change_notify_event, ev);
|
---|
240 | if (tc->object==tname_edit && tc->new_text && m1_info.obj)
|
---|
241 | {
|
---|
242 | i4_file_class *fp=i4_open(*tc->new_text);
|
---|
243 | if (!fp) return;
|
---|
244 | delete fp;
|
---|
245 | int i;
|
---|
246 |
|
---|
247 | for (i=0; i<m1_info.obj->num_quad; i++)
|
---|
248 | if (m1_info.obj->quad[i].get_flags(g1_quad_class::SELECTED))
|
---|
249 | m1_info.obj->texture_names[i]=new i4_str(*tc->new_text);
|
---|
250 |
|
---|
251 | m1_info.texture_list_changed();
|
---|
252 | }
|
---|
253 |
|
---|
254 |
|
---|
255 | } break;
|
---|
256 |
|
---|
257 | case i4_event::MOUSE_BUTTON_DOWN :
|
---|
258 | {
|
---|
259 | CAST_PTR(bev, i4_mouse_button_down_event_class, ev);
|
---|
260 |
|
---|
261 | if (bev->left()) grab |= LEFT;
|
---|
262 | if (bev->right()) grab |= RIGHT;
|
---|
263 | if (bev->center()) grab |= MIDDLE;
|
---|
264 |
|
---|
265 | i4_window_request_key_grab_class kgrab(this);
|
---|
266 | i4_kernel.send_event(parent, &kgrab);
|
---|
267 |
|
---|
268 | i4_bool clear_old=i4_T;
|
---|
269 | int sel_poly=-1, sel_vert=-1;
|
---|
270 |
|
---|
271 | if (bev->left() && obj)
|
---|
272 | {
|
---|
273 | for (int j=0; j<obj->num_quad; j++)
|
---|
274 | {
|
---|
275 | g1_quad_class *q=obj->quad+j;
|
---|
276 | if (q->get_flags(g1_quad_class::SELECTED))
|
---|
277 | {
|
---|
278 | for (int i=0; i<q->num_verts(); i++)
|
---|
279 | {
|
---|
280 | int x,y;
|
---|
281 | get_point(j,i,x,y);
|
---|
282 | if (abs(bev->x-x)<HANDLE_SIZE && abs(bev->y-y)<HANDLE_SIZE)
|
---|
283 | {
|
---|
284 | if (obj->get_poly_vert_flag(j, 1<<i))
|
---|
285 | clear_old=i4_F;
|
---|
286 | else
|
---|
287 | obj->set_poly_vert_flag(j, 1<<i, 1);
|
---|
288 |
|
---|
289 | sel_poly=j;
|
---|
290 | sel_vert=i;
|
---|
291 | }
|
---|
292 | }
|
---|
293 | }
|
---|
294 | }
|
---|
295 | }
|
---|
296 |
|
---|
297 | if (clear_old && !i4_current_app->get_window_manager()->shift_pressed())
|
---|
298 | {
|
---|
299 | for (int j=0; j<obj->num_quad; j++)
|
---|
300 | for (int i=0; i<4; i++)
|
---|
301 | obj->set_poly_vert_flag(j, 1<<i, 0);
|
---|
302 |
|
---|
303 | if (sel_poly!=-1)
|
---|
304 | obj->set_poly_vert_flag(sel_poly, 1<<sel_vert, 1);
|
---|
305 | }
|
---|
306 |
|
---|
307 | request_redraw(i4_T);
|
---|
308 | } break;
|
---|
309 |
|
---|
310 | case i4_event::MOUSE_BUTTON_UP :
|
---|
311 | {
|
---|
312 | CAST_PTR(bev, i4_mouse_button_up_event_class, ev);
|
---|
313 |
|
---|
314 | if (bev->left()) grab &= ~LEFT;
|
---|
315 | if (bev->right()) grab &= ~RIGHT;
|
---|
316 | if (bev->center()) grab &= ~MIDDLE;
|
---|
317 | } break;
|
---|
318 |
|
---|
319 | case i4_event::MOUSE_MOVE :
|
---|
320 | {
|
---|
321 | CAST_PTR(mev, i4_mouse_move_event_class, ev);
|
---|
322 |
|
---|
323 | int old_px = preselect_x, old_py = preselect_y;
|
---|
324 |
|
---|
325 | preselect_x = -1;
|
---|
326 |
|
---|
327 | if (m1_info.obj)
|
---|
328 | {
|
---|
329 | if (grab && verts_are_selected())
|
---|
330 | {
|
---|
331 | int snap_x = mev->x, snap_y = mev->y;
|
---|
332 |
|
---|
333 | for (int j=0; j<m1_info.obj->num_quad; j++)
|
---|
334 | {
|
---|
335 | g1_quad_class *q=m1_info.obj->quad+j;
|
---|
336 | if (q->get_flags(g1_quad_class::SELECTED))
|
---|
337 | {
|
---|
338 | for (int i=0; i<q->num_verts(); i++)
|
---|
339 | {
|
---|
340 | if (!m1_info.obj->get_poly_vert_flag(j,1<<i))
|
---|
341 | {
|
---|
342 | int x,y;
|
---|
343 | get_point(j,i,x,y);
|
---|
344 | if (abs(mev->x-x)<SNAP_DISTANCE && abs(mev->y-y)<SNAP_DISTANCE)
|
---|
345 | {
|
---|
346 | snap_x = x;
|
---|
347 | snap_y = y;
|
---|
348 | }
|
---|
349 | }
|
---|
350 | }
|
---|
351 | }
|
---|
352 | }
|
---|
353 |
|
---|
354 | drag_points(snap_x+snap_off_x-mev->lx, snap_y+snap_off_y-mev->ly);
|
---|
355 |
|
---|
356 | snap_off_x = mev->x - snap_x;
|
---|
357 | snap_off_y = mev->y - snap_y;
|
---|
358 | }
|
---|
359 | else
|
---|
360 | {
|
---|
361 | for (int j=0; j<m1_info.obj->num_quad; j++)
|
---|
362 | {
|
---|
363 | g1_quad_class *q=m1_info.obj->quad+j;
|
---|
364 | if (q->get_flags(g1_quad_class::SELECTED))
|
---|
365 | {
|
---|
366 | for (int i=0; i<q->num_verts(); i++)
|
---|
367 | {
|
---|
368 | int x,y;
|
---|
369 | get_point(j,i,x,y);
|
---|
370 | if (abs(mev->x-x)<HANDLE_SIZE && abs(mev->y-y)<HANDLE_SIZE)
|
---|
371 | {
|
---|
372 | preselect_x = x;
|
---|
373 | preselect_y = y;
|
---|
374 | snap_off_x = mev->x - preselect_x;
|
---|
375 | snap_off_y = mev->y - preselect_y;
|
---|
376 | }
|
---|
377 | }
|
---|
378 | }
|
---|
379 | }
|
---|
380 | }
|
---|
381 |
|
---|
382 | if (old_px!=preselect_x || old_py!=preselect_y)
|
---|
383 | request_redraw();
|
---|
384 | }
|
---|
385 |
|
---|
386 | } break;
|
---|
387 |
|
---|
388 | }
|
---|
389 | if (!pre_grab && grab)
|
---|
390 | {
|
---|
391 | i4_window_request_mouse_grab_class grab_ev(this);
|
---|
392 | i4_kernel.send_event(parent,&grab_ev);
|
---|
393 | }
|
---|
394 | if (pre_grab && !grab)
|
---|
395 | {
|
---|
396 | i4_window_request_mouse_ungrab_class grab_ev(this);
|
---|
397 | i4_kernel.send_event(parent,&grab_ev);
|
---|
398 | }
|
---|
399 | }
|
---|
400 |
|
---|
401 |
|
---|
402 |
|
---|
403 | void m1_st_edit_window_class::edit_poly_changed()
|
---|
404 | {
|
---|
405 | if (texture)
|
---|
406 | delete texture;
|
---|
407 | texture=0;
|
---|
408 |
|
---|
409 | if (m1_info.obj)
|
---|
410 | {
|
---|
411 | m1_poly_object_class *obj=m1_info.obj;
|
---|
412 |
|
---|
413 | int sel_poly=-1;
|
---|
414 | for (int j=0; j<obj->num_quad; j++)
|
---|
415 | if (obj->quad[j].get_flags(g1_quad_class::SELECTED))
|
---|
416 | {
|
---|
417 | if (sel_poly==-1)
|
---|
418 | sel_poly=j;
|
---|
419 | else if (sel_poly>=0)
|
---|
420 | if (!(*obj->texture_names[sel_poly] == *obj->texture_names[j]))
|
---|
421 | sel_poly=-2;
|
---|
422 | }
|
---|
423 |
|
---|
424 | if (sel_poly==-1)
|
---|
425 | tname_edit->change_text("<None Selected>");
|
---|
426 | else if (sel_poly==-2)
|
---|
427 | tname_edit->change_text("<Multiple Selected>");
|
---|
428 | else
|
---|
429 | {
|
---|
430 | i4_image_class *im[10];
|
---|
431 | int t=r1_load_gtext(r1_get_texture_id(*obj->texture_names[sel_poly]), im);
|
---|
432 |
|
---|
433 | for (int i=1; i<t; i++)
|
---|
434 | delete im[i];
|
---|
435 |
|
---|
436 | if (t)
|
---|
437 | texture=im[0];
|
---|
438 |
|
---|
439 | if (texture)
|
---|
440 | tname_edit->change_text(*obj->texture_names[sel_poly]);
|
---|
441 | else
|
---|
442 | tname_edit->change_text("<Untextured>");
|
---|
443 | }
|
---|
444 | }
|
---|
445 |
|
---|
446 | request_redraw(i4_F);
|
---|
447 | }
|
---|
448 |
|
---|
449 |
|
---|
450 | m1_st_edit_window_class::m1_st_edit_window_class(w16 w, w16 h,
|
---|
451 | i4_text_input_class *tname_edit)
|
---|
452 | : i4_window_class(w,h),
|
---|
453 | tname_edit(tname_edit)
|
---|
454 | {
|
---|
455 | texture=0;
|
---|
456 | dragging=i4_F;
|
---|
457 | preselect_x = -1;
|
---|
458 | grab=0;
|
---|
459 | }
|
---|
460 |
|
---|
461 | i4_event_handler_reference_class<m1_st_edit_window_class> m1_st_edit;
|
---|
462 |
|
---|
463 |
|
---|
464 |
|
---|