]> git.saurik.com Git - wxWidgets.git/blame - utils/dialoged/src/dlghndlr.cpp
Doc mods, sash window bug
[wxWidgets.git] / utils / dialoged / src / dlghndlr.cpp
CommitLineData
457814b5
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: dlghndlr.cpp
3// Purpose: Dialog handler
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include <ctype.h>
28#include <stdlib.h>
29#include <math.h>
30#include <string.h>
31
203feea8 32#if wxUSE_IOSTREAMH
2049ba38 33#if defined(__WXMSW__) && !defined(__GNUWIN32__)
457814b5
JS
34#include <strstrea.h>
35#else
36#include <strstream.h>
37#endif
203feea8
UU
38#else
39#include <strstream>
40#endif
457814b5
JS
41
42#include "reseditr.h"
43#include "winprop.h"
457814b5 44#include "dlghndlr.h"
ae8351fc 45#include "edlist.h"
457814b5
JS
46
47IMPLEMENT_CLASS(wxResourceEditorDialogHandler, wxEvtHandler)
48IMPLEMENT_CLASS(wxResourceEditorControlHandler, wxEvtHandler)
49
50BEGIN_EVENT_TABLE(wxResourceEditorDialogHandler, wxEvtHandler)
51 EVT_PAINT(wxResourceEditorDialogHandler::OnPaint)
52 EVT_MOUSE_EVENTS(wxResourceEditorDialogHandler::OnMouseEvent)
fd71308f 53 EVT_SIZE(wxResourceEditorDialogHandler::OnSize)
457814b5
JS
54END_EVENT_TABLE()
55
56BEGIN_EVENT_TABLE(wxResourceEditorControlHandler, wxEvtHandler)
57 EVT_MOUSE_EVENTS(wxResourceEditorControlHandler::OnMouseEvent)
58END_EVENT_TABLE()
59
60/*
61 * Dialog box event handler
62 */
63
64wxResourceEditorDialogHandler::wxResourceEditorDialogHandler(wxPanel *dialog, wxItemResource *resource,
65 wxEvtHandler *oldHandler, wxResourceManager *manager)
66{
67 handlerDialog = dialog;
68 handlerResource = resource;
69 handlerOldHandler = oldHandler;
70 resourceManager = manager;
71
72 dragMode = wxDRAG_MODE_NONE;
73 dragType = wxDRAG_TYPE_NONE;
74 dragItem = NULL;
75 firstDragX = 0;
76 firstDragY = 0;
77 oldDragX = 0;
78 oldDragY = 0;
79 dragTolerance = 3;
80 checkTolerance = TRUE;
ae8351fc
JS
81 m_mouseCaptured = FALSE;
82// m_treeItem = 0;
83}
84
85wxResourceEditorDialogHandler::~wxResourceEditorDialogHandler(void)
86{
457814b5
JS
87}
88
89void wxResourceEditorDialogHandler::OnItemSelect(wxControl *item, bool select)
90{
91 if (select)
92 resourceManager->AddSelection(item);
93 else
94 resourceManager->RemoveSelection(item);
95}
96
b127f301 97void wxResourceEditorDialogHandler::OnPaint(wxPaintEvent& WXUNUSED(event))
457814b5
JS
98{
99 wxPaintDC dc(handlerDialog);
100
101 PaintSelectionHandles(dc);
102}
103
104// Add event handlers for all children
105void wxResourceEditorDialogHandler::AddChildHandlers(void)
106{
c030b70f 107 wxNode *node = handlerDialog->GetChildren().First();
457814b5
JS
108 while ( node )
109 {
110 wxControl *child = (wxControl *)node->Data();
111 wxEvtHandler *childHandler = child->GetEventHandler();
112 if ( child->IsKindOf(CLASSINFO(wxControl)) && childHandler == child )
113 child->PushEventHandler(new wxResourceEditorControlHandler(child, childHandler));
114 node = node->Next();
115 }
116}
117
118void wxResourceEditorDialogHandler::OnLeftClick(int x, int y, int keys)
119{
120 if (keys & wxKEY_CTRL)
121 {
ae8351fc
JS
122 wxResourceManager::GetCurrentResourceManager()->EditWindow(handlerDialog);
123 return;
124 }
125
126 // Deselect all items if click on panel
127 if (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection() == RESED_POINTER)
128 {
129 int needsRefresh = 0;
c030b70f 130 wxNode *node = handlerDialog->GetChildren().First();
ae8351fc
JS
131 while (node)
132 {
133 wxControl *item = (wxControl *)node->Data();
134 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
135 if (item->IsKindOf(CLASSINFO(wxControl)) && childHandler->IsSelected())
136 {
137 needsRefresh ++;
138 OnItemSelect(item, FALSE);
139 childHandler->SelectItem(FALSE);
140 }
141 node = node->Next();
142 }
143 if (needsRefresh > 0)
144 {
145 wxClientDC dc(handlerDialog);
146 dc.Clear();
147 handlerDialog->Refresh();
148 }
149 return;
150 }
151
e3a43801
JS
152 // Round down to take account of dialog units
153 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerDialog);
154 if (resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
155 {
156 wxPoint pt = handlerDialog->ConvertPixelsToDialog(wxPoint(x, y));
157
158 // Convert back so we've rounded down
159 pt = handlerDialog->ConvertDialogToPixels(pt);
160 pt = handlerDialog->ConvertPixelsToDialog(pt);
161 pt = handlerDialog->ConvertDialogToPixels(pt);
162 x = pt.x;
163 y = pt.y;
164 }
165
ae8351fc
JS
166 switch (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection())
167 {
168 case RESED_BUTTON:
169 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxButton", x, y);
170 break;
171 case RESED_BMPBUTTON:
172 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxBitmapButton", x, y, TRUE);
173 break;
174 case RESED_STATICTEXT:
175 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticText", x, y);
176 break;
177 case RESED_STATICBMP:
178 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticBitmap", x, y, TRUE);
179 break;
180 case RESED_TEXTCTRL_SINGLE:
181 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxTextCtrl (single-line)", x, y);
182 break;
183 case RESED_TEXTCTRL_MULTIPLE:
184 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxTextCtrl (multi-line)", x, y);
185 break;
186 case RESED_CHOICE:
187 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxChoice", x, y);
188 break;
9c331ded
JS
189 case RESED_COMBOBOX:
190 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxComboBox", x, y);
191 break;
ae8351fc
JS
192 case RESED_CHECKBOX:
193 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxCheckBox", x, y);
194 break;
195 case RESED_RADIOBOX:
196 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxRadioBox", x, y);
197 break;
03f68f12
JS
198 case RESED_RADIOBUTTON:
199 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxRadioButton", x, y);
200 break;
ae8351fc
JS
201 case RESED_LISTBOX:
202 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxListBox", x, y);
203 break;
204 case RESED_SLIDER:
205 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxSlider", x, y);
206 break;
207 case RESED_GAUGE:
208 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxGauge", x, y);
209 break;
210 case RESED_STATICBOX:
211 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticBox", x, y);
212 break;
213 case RESED_SCROLLBAR:
214 resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxScrollBar", x, y);
215 break;
216 default:
217 break;
218 }
219
220 // Now switch pointer on.
221 if (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection() != RESED_POINTER)
222 {
223 wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->SetItemState(RESED_POINTER, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
224 }
225}
226
b127f301 227void wxResourceEditorDialogHandler::OnRightClick(int x, int y, int WXUNUSED(keys))
457814b5
JS
228{
229 wxMenu *menu = resourceManager->GetPopupMenu();
230 menu->SetClientData((char *)handlerDialog);
457814b5 231 handlerDialog->PopupMenu(menu, x, y);
457814b5
JS
232}
233
560b92f5 234void wxResourceEditorDialogHandler::OnItemLeftClick(wxControl *item, int WXUNUSED(x), int WXUNUSED(y), int keys)
457814b5
JS
235{
236 if (keys & wxKEY_CTRL)
237 {
ae8351fc 238 wxResourceManager::GetCurrentResourceManager()->EditWindow(item);
457814b5
JS
239 return;
240 }
03f68f12
JS
241
242/*
457814b5
JS
243 // If this is a wxStaticBox and the pointer isn't an arrow, chances
244 // are that we really meant to place an item on the panel.
245 // Fake this event.
246 if ((item->GetClassInfo() == CLASSINFO(wxStaticBox)) && resourceManager->GetEditorPalette()->currentlySelected != PALETTE_ARROW)
247 {
248 OnLeftClick(x, y, keys);
249 return;
250 }
03f68f12 251*/
457814b5
JS
252
253 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
254
255 if (childHandler->IsSelected())
256 {
257 childHandler->SelectItem(FALSE);
258 OnItemSelect(item, FALSE);
259
260 wxClientDC dc(handlerDialog);
261 dc.Clear();
262 handlerDialog->Refresh();
263 }
264 else
265 {
266 childHandler->SelectItem(TRUE);
267 OnItemSelect(item, TRUE);
268
269 // Deselect other items if shift is not pressed
270 int needsRefresh = 0;
271 if (!(keys & wxKEY_SHIFT))
272 {
c030b70f 273 wxNode *node = item->GetParent()->GetChildren().First();
457814b5
JS
274 while (node)
275 {
276 wxControl *child = (wxControl *)node->Data();
277 wxResourceEditorControlHandler *childHandler2 = (wxResourceEditorControlHandler *)child->GetEventHandler();
278 if (child->IsKindOf(CLASSINFO(wxControl)) && childHandler2->IsSelected() && child != item)
279 {
280 childHandler2->SelectItem(FALSE);
281 OnItemSelect(child, FALSE);
282 needsRefresh ++;
283 }
284 node = node->Next();
285 }
286 }
287
288 wxClientDC dc(handlerDialog);
289 childHandler->DrawSelectionHandles(dc);
290
291 if (needsRefresh > 0)
292 {
293 dc.Clear();
294 handlerDialog->Refresh();
295 }
296 }
297}
298
b127f301 299void wxResourceEditorDialogHandler::OnItemRightClick(wxControl *item, int x, int y, int WXUNUSED(keys))
457814b5
JS
300{
301/*
302 if (keys & wxKEY_CTRL)
303 {
304 wxDebugMsg("Item %s, selected = %d\n", item->GetName(), item->IsSelected());
305 return;
306 }
307*/
308
309 wxMenu *menu = resourceManager->GetPopupMenu();
310 menu->SetClientData((char *)item);
457814b5 311 handlerDialog->PopupMenu(menu, x, y);
457814b5
JS
312}
313
fd71308f
JS
314// Under Windows 95, you can resize a panel interactively depending on
315// window styles.
316void wxResourceEditorDialogHandler::OnSize(wxSizeEvent& event)
317{
318 // Update the associated resource
319 int w, h;
320 handlerDialog->GetClientSize(& w, & h);
321
322 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerDialog);
323 if (resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
324 {
325 wxSize sz = handlerDialog->ConvertPixelsToDialog(wxSize(w, h));
326 w = sz.x; h = sz.y;
327 }
328 resource->SetSize(resource->GetX(), resource->GetY(), w, h);
329}
330
457814b5
JS
331// An event outside any items: may be a drag event.
332void wxResourceEditorDialogHandler::OnMouseEvent(wxMouseEvent& event)
333{
334 if (GetEvtHandlerEnabled())
335 {
336 // If we're dragging an item or selection handle,
337 // continue dragging.
338 if (dragMode != wxDRAG_MODE_NONE)
339 {
340 ProcessItemEvent(dragItem, event, dragType);
341 return;
342 }
343
344 long x, y;
345 event.Position(&x, &y);
346
347 // Find which selection handle we're on, if any
c030b70f 348 wxNode *node = handlerDialog->GetChildren().First();
457814b5
JS
349 while (node)
350 {
351 wxWindow *win = (wxWindow *)node->Data();
352 if (win->IsKindOf(CLASSINFO(wxControl)))
353 {
354 wxControl *item = (wxControl *)win;
355 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
356 int selHandle = childHandler->SelectionHandleHitTest(x, y);
357 if (selHandle > 0)
358 {
359 ProcessItemEvent(item, event, selHandle);
360 return;
361 }
362 }
363 node = node->Next();
364 }
365
366 // We're not on an item or selection handle.
367 // so... check for a left or right click event
368 // to send to the application.
369 int keys = 0;
370 if (event.ShiftDown()) keys = keys | wxKEY_SHIFT;
371 if (event.ControlDown()) keys = keys | wxKEY_CTRL;
372
373 if (event.LeftUp())
ae8351fc
JS
374 {
375 if (m_mouseCaptured)
376 {
377 handlerDialog->ReleaseMouse();
378 m_mouseCaptured = FALSE;
379 }
380
381 OnLeftClick(x, y, keys);
382 }
560b92f5 383 else if (event.RightDown())
ae8351fc
JS
384 {
385 if (m_mouseCaptured)
386 {
387 handlerDialog->ReleaseMouse();
388 m_mouseCaptured = FALSE;
389 }
390
391 OnRightClick(x, y, keys);
392 }
fd71308f
JS
393 else if (event.LeftDClick())
394 {
395 if (m_mouseCaptured)
396 {
397 handlerDialog->ReleaseMouse();
398 m_mouseCaptured = FALSE;
399 }
400 wxResourceManager::GetCurrentResourceManager()->EditWindow(handlerDialog);
401 }
457814b5
JS
402 }
403 else
404 event.Skip();
405}
406
407void wxResourceEditorDialogHandler::OnItemEvent(wxControl *item, wxMouseEvent& event)
408{
409 if (!GetEvtHandlerEnabled())
410 return;
411
412 // Not a selection handle event: just a normal item event.
413 // Transform to panel coordinates.
414 int x, y;
415 item->GetPosition(&x, &y);
416
417 event.m_x = event.m_x + x;
418 event.m_y = event.m_y + y;
d84eb083 419
457814b5
JS
420 ProcessItemEvent(item, event, dragType);
421}
422
423void wxResourceEditorDialogHandler::ProcessItemEvent(wxControl *item, wxMouseEvent& event, int selectionHandle)
424{
425 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
d84eb083 426
457814b5
JS
427 long x, y;
428 event.Position(&x, &y);
429 int keys = 0;
430 if (event.ShiftDown()) keys = keys | wxKEY_SHIFT;
431 if (event.ControlDown()) keys = keys | wxKEY_CTRL;
432 bool dragging = event.Dragging();
433 if (dragging)
434 {
435 int dx = (int)abs((x - firstDragX));
436 int dy = (int)abs((y - firstDragY));
437 if (checkTolerance && (dx <= dragTolerance) && (dy <= dragTolerance))
438 {
439 return;
440 }
441 else
442 // If we've ignored the tolerance once, then ALWAYS ignore
443 // tolerance in this drag, even if we come back within
444 // the tolerance range.
445 {
446 checkTolerance = FALSE;
447 }
448 }
ae8351fc
JS
449 if (event.LeftDClick())
450 {
451 if (m_mouseCaptured)
452 {
453 handlerDialog->ReleaseMouse();
454 m_mouseCaptured = FALSE;
455 }
456
457 wxResourceManager::GetCurrentResourceManager()->EditWindow(item);
458 }
459 else if (dragging && dragItem && dragMode == wxDRAG_MODE_START_LEFT)
457814b5
JS
460 {
461 dragMode = wxDRAG_MODE_CONTINUE_LEFT;
462 wxClientDC dc(handlerDialog);
463 childHandler->OnDragBegin(x, y, keys, dc, selectionHandle);
464 oldDragX = x; oldDragY = y;
ae8351fc
JS
465 if (!m_mouseCaptured)
466 {
467 handlerDialog->CaptureMouse();
468 m_mouseCaptured = TRUE;
469 }
457814b5
JS
470 }
471 else if (dragging && dragItem && dragMode == wxDRAG_MODE_CONTINUE_LEFT)
472 {
473 wxClientDC dc(handlerDialog);
474 childHandler->OnDragContinue(FALSE, oldDragX, oldDragY, keys, dc, selectionHandle);
475 childHandler->OnDragContinue(TRUE, x, y, keys, dc, selectionHandle);
476 oldDragX = x; oldDragY = y;
477 }
478 else if (event.LeftUp() && dragItem && dragMode == wxDRAG_MODE_CONTINUE_LEFT)
479 {
480 wxClientDC dc(handlerDialog);
481 dragMode = wxDRAG_MODE_NONE;
482 checkTolerance = TRUE;
ae8351fc 483
457814b5
JS
484 childHandler->OnDragContinue(FALSE, oldDragX, oldDragY, keys, dc, selectionHandle);
485 childHandler->OnDragEnd(x, y, keys, dc, selectionHandle);
ae8351fc 486
457814b5
JS
487 dragItem = NULL;
488 dragType = wxDRAG_TYPE_NONE;
ae8351fc
JS
489
490 if (m_mouseCaptured)
491 {
492 handlerDialog->ReleaseMouse();
493 m_mouseCaptured = FALSE;
494 }
457814b5
JS
495 }
496 else if (dragging && dragItem && dragMode == wxDRAG_MODE_START_RIGHT)
497 {
498 wxClientDC dc(handlerDialog);
499 dragMode = wxDRAG_MODE_CONTINUE_RIGHT;
500 childHandler->OnDragBegin(x, y, keys, dc, selectionHandle);
501 oldDragX = x; oldDragY = y;
ae8351fc
JS
502
503 if (!m_mouseCaptured)
504 {
505 handlerDialog->CaptureMouse();
506 m_mouseCaptured = TRUE;
507 }
457814b5
JS
508 }
509 else if (dragging && dragItem && dragMode == wxDRAG_MODE_CONTINUE_RIGHT)
510 {
511 oldDragX = x; oldDragY = y;
512 }
560b92f5 513 // Obsolete; no longer try to right-drag
457814b5
JS
514 else if (event.RightUp() && dragItem && dragMode == wxDRAG_MODE_CONTINUE_RIGHT)
515 {
516 dragMode = wxDRAG_MODE_NONE;
517 checkTolerance = TRUE;
518 dragItem = NULL;
519 dragType = wxDRAG_TYPE_NONE;
ae8351fc
JS
520
521 if (m_mouseCaptured)
522 {
523 handlerDialog->ReleaseMouse();
524 m_mouseCaptured = FALSE;
525 }
457814b5
JS
526 }
527 else if (event.IsButton())
528 {
529 checkTolerance = TRUE;
530
531 if (event.LeftDown())
532 {
533 dragItem = item;
534 dragMode = wxDRAG_MODE_START_LEFT;
535 firstDragX = x;
536 firstDragY = y;
537 dragType = selectionHandle;
ae8351fc
JS
538
539 if (!m_mouseCaptured)
540 {
541 handlerDialog->CaptureMouse();
542 m_mouseCaptured = TRUE;
543 }
457814b5
JS
544 }
545 else if (event.RightDown())
546 {
560b92f5
JS
547 if (m_mouseCaptured)
548 {
549 handlerDialog->ReleaseMouse();
550 m_mouseCaptured = FALSE;
551 }
552
553 if (item)
554 childHandler->OnRightClick(x, y, keys);
555 else
556 OnRightClick(x, y, keys);
557
558 dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
559
560 /*
457814b5
JS
561 dragItem = item;
562 dragMode = wxDRAG_MODE_START_RIGHT;
563 firstDragX = x;
564 firstDragY = y;
565 dragType = selectionHandle;
ae8351fc
JS
566
567 if (!m_mouseCaptured)
568 {
569 handlerDialog->CaptureMouse();
570 m_mouseCaptured = TRUE;
571 }
560b92f5 572 */
457814b5
JS
573 }
574 else if (event.LeftUp())
575 {
576 if (dragItem)
577 childHandler->OnLeftClick(x, y, keys);
578 else
579 OnLeftClick(x, y, keys);
580
581 dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
ae8351fc
JS
582
583 if (m_mouseCaptured)
584 {
585 handlerDialog->ReleaseMouse();
586 m_mouseCaptured = FALSE;
587 }
457814b5
JS
588 }
589 else if (event.RightUp())
590 {
560b92f5 591 /*
457814b5
JS
592 if (dragItem)
593 childHandler->OnRightClick(x, y, keys);
594 else
595 OnRightClick(x, y, keys);
596
597 dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
ae8351fc
JS
598
599 if (m_mouseCaptured)
600 {
601 handlerDialog->ReleaseMouse();
602 m_mouseCaptured = FALSE;
603 }
560b92f5 604 */
457814b5
JS
605 }
606 }
607}
608
609// Calls DrawSelectionHandles for all items if
610// edit mode is on.
611void wxResourceEditorDialogHandler::PaintSelectionHandles(wxDC& dc)
612{
613 if (!GetEvtHandlerEnabled())
614 return;
615
616 dc.BeginDrawing();
617
c030b70f 618 wxNode *node = handlerDialog->GetChildren().First();
457814b5
JS
619 while (node)
620 {
621 wxWindow *win = (wxWindow *)node->Data();
622 if (win->IsKindOf(CLASSINFO(wxControl)))
623 {
624 wxControl *item = (wxControl *)win;
625 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
626
627 // Don't draw handles for an item that's being moved: it'll
628 // smear.
629 if (childHandler->IsSelected() && (item != dragItem))
630 childHandler->DrawSelectionHandles(dc);
631 }
632 node = node->Next();
633 }
634 dc.EndDrawing();
635}
636
637/*
638 * Event handler for controls
639 */
640
641int wxResourceEditorControlHandler::dragOffsetX = 0;
642int wxResourceEditorControlHandler::dragOffsetY = 0;
643
644wxResourceEditorControlHandler::wxResourceEditorControlHandler(wxControl *control,
645 wxEvtHandler *oldHandler)
646{
647 handlerControl = control;
648 handlerOldHandler = oldHandler;
649
650 handleSize = 6;
651 handleMargin = 1;
652 isSelected = FALSE;
653 dragOffsetX = 0;
654 dragOffsetY = 0;
ae8351fc
JS
655// m_treeItem = 0;
656}
657
658wxResourceEditorControlHandler::~wxResourceEditorControlHandler(void)
659{
457814b5
JS
660}
661
662/*
663 * Manipulation and drawing of items in Edit Mode
664 */
665
666void wxResourceEditorControlHandler::SelectItem(bool select)
667{
668 isSelected = select;
669}
670
671// Returns TRUE or FALSE
672bool wxResourceEditorControlHandler::HitTest(int x, int y)
673{
674 int xpos, ypos, width, height;
675 handlerControl->GetPosition(&xpos, &ypos);
676 handlerControl->GetSize(&width, &height);
677
678 return ((x >= xpos) && (x <= (xpos + width)) && (y >= ypos) && (y <= (ypos + height)));
679}
680
681// Calculate position of the 8 handles
682void wxResourceEditorControlHandler::CalcSelectionHandles(int *hx, int *hy)
683{
684 int xpos, ypos, width, height;
685 handlerControl->GetPosition(&xpos, &ypos);
686 handlerControl->GetSize(&width, &height);
687 int middleX = (xpos + (width/2));
688 int middleY = (ypos + (height/2));
689
690 // Start from top middle, clockwise.
691/*
692 7 0 1
693
694 6 2
695
696 5 4 3
697*/
698
699 hx[0] = (int)(middleX - (handleSize/2));
700 hy[0] = ypos - handleSize - handleMargin;
701
702 hx[1] = xpos + width + handleMargin;
703 hy[1] = ypos - handleSize - handleMargin;
704
705 hx[2] = xpos + width + handleMargin;
706 hy[2] = (int)(middleY - (handleSize/2));
707
708 hx[3] = xpos + width + handleMargin;
709 hy[3] = ypos + height + handleMargin;
710
711 hx[4] = (int)(middleX - (handleSize/2));
712 hy[4] = ypos + height + handleMargin;
713
714 hx[5] = xpos - handleSize - handleMargin;
715 hy[5] = ypos + height + handleMargin;
716
717 hx[6] = xpos - handleSize - handleMargin;
718 hy[6] = (int)(middleY - (handleSize/2));
719
720 hx[7] = xpos - handleSize - handleMargin;
721 hy[7] = ypos - handleSize - handleMargin;
722}
723
724// Returns 0 (no hit), 1 - 8 for which selection handle
725// (clockwise from top middle)
726int wxResourceEditorControlHandler::SelectionHandleHitTest(int x, int y)
727{
728 // Handle positions
729 int hx[8];
730 int hy[8];
731 CalcSelectionHandles(hx, hy);
732
733 int i;
734 for (i = 0; i < 8; i++)
735 {
736 if ((x >= hx[i]) && (x <= (hx[i] + handleSize)) && (y >= hy[i]) && (y <= (hy[i] + handleSize)))
737 return (i + 1);
738 }
739 return 0;
740}
741
742void wxResourceEditorControlHandler::DrawSelectionHandles(wxDC& dc, bool WXUNUSED(erase))
743{
744 dc.SetOptimization(FALSE);
745
746 dc.SetLogicalFunction(wxCOPY);
c030b70f
JS
747 dc.SetPen(* wxBLACK_PEN);
748 dc.SetBrush(* wxBLACK_BRUSH);
457814b5
JS
749
750 dc.SetOptimization(TRUE);
751
752 // Handle positions
753 int hx[8];
754 int hy[8];
755 CalcSelectionHandles(hx, hy);
756
757 int i;
758 for (i = 0; i < 8; i++)
759 {
760 dc.DrawRectangle(hx[i], hy[i], handleSize, handleSize);
761 }
762}
763
764void wxResourceEditorControlHandler::DrawBoundingBox(wxDC& dc, int x, int y, int w, int h)
765{
766 dc.DrawRectangle(x, y, w, h);
767}
768
769// If selectionHandle is zero, not dragging the selection handle.
770void wxResourceEditorControlHandler::OnDragBegin(int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
771{
772 int xpos, ypos, width, height;
773 handlerControl->GetPosition(&xpos, &ypos);
774 handlerControl->GetSize(&width, &height);
775
776 dc.BeginDrawing();
777
778// dc.DestroyClippingRegion();
779
780 wxPanel *panel = (wxPanel *)handlerControl->GetParent();
457814b5
JS
781
782 // Erase selection handles
783// DrawSelectionHandles(dc, TRUE);
784
785 dc.SetOptimization(FALSE);
786
787 dc.SetLogicalFunction(wxXOR);
788
ae8351fc
JS
789 wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
790 dc.SetPen(pen);
c030b70f 791 dc.SetBrush(* wxTRANSPARENT_BRUSH);
457814b5
JS
792
793 dc.SetOptimization(TRUE);
794
795 if (selectionHandle > 0)
796 {
797 panel->Refresh();
798
799 DrawBoundingBox(dc, xpos, ypos, width, height);
800 }
801 else
802 {
803 panel->Refresh();
804
805 dragOffsetX = (x - xpos);
806 dragOffsetY = (y - ypos);
807
808 DrawBoundingBox(dc, xpos, ypos, width, height);
809
810 // Also draw bounding boxes for other selected items
c030b70f 811 wxNode *node = panel->GetChildren().First();
457814b5
JS
812 while (node)
813 {
814 wxWindow *win = (wxWindow *)node->Data();
815 if (win->IsKindOf(CLASSINFO(wxControl)))
816 {
817 wxControl *item = (wxControl *)win;
818 wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
819 if ((item != handlerControl) && handler->IsSelected())
820 {
821 int x1, y1, w1, h1;
822 item->GetPosition(&x1, &y1);
823 item->GetSize(&w1, &h1);
824 handler->DrawBoundingBox(dc, x1, y1, w1, h1);
825 }
826 }
827 node = node->Next();
828 }
829 }
830 dc.EndDrawing();
831}
832
560b92f5 833void wxResourceEditorControlHandler::OnDragContinue(bool WXUNUSED(paintIt), int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
457814b5
JS
834{
835 wxPanel *panel = (wxPanel *)handlerControl->GetParent();
457814b5
JS
836 int xpos, ypos, width, height;
837 handlerControl->GetPosition(&xpos, &ypos);
838 handlerControl->GetSize(&width, &height);
839
840 if (selectionHandle > 0)
841 {
842/*
843 8 1 2
844
845 7 3
846
847 6 5 4
848*/
849
850 int x1, y1, width1, height1;
851
852 switch (selectionHandle)
853 {
854 case 1:
855 x1 = xpos;
856 y1 = y;
857 width1 = width;
858 height1 = (ypos + height) - y;
859 break;
860 case 5:
861 x1 = xpos;
862 y1 = ypos;
863 width1 = width;
864 height1 = (y - ypos);
865 break;
866 case 3:
867 x1 = xpos;
868 y1 = ypos;
869 width1 = (x - xpos);
870 height1 = height;
871 break;
872 case 7:
873 x1 = x;
874 y1 = ypos;
875 width1 = (xpos + width) - x;
876 height1 = height;
877 break;
878 case 2:
879 x1 = xpos;
880 y1 = y;
881 width1 = (x - xpos);
882 height1 = (ypos + height) - y;
883 break;
884 case 4:
885 x1 = xpos;
886 y1 = ypos;
887 width1 = (x - xpos);
888 height1 = (y - ypos);
889 break;
890 case 6:
891 x1 = x;
892 y1 = ypos;
893 width1 = (xpos + width) - x;
894 height1 = y - ypos;
895 break;
896 case 8:
897 x1 = x;
898 y1 = y;
899 width1 = (xpos + width) - x;
900 height1 = (ypos + height) - y;
901 break;
902 }
903 dc.BeginDrawing();
904
905 dc.SetLogicalFunction(wxXOR);
ae8351fc
JS
906 wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
907 dc.SetPen(pen);
c030b70f 908 dc.SetBrush(* wxTRANSPARENT_BRUSH);
457814b5
JS
909
910 DrawBoundingBox(dc, x1, y1, width1, height1);
911
912 dc.EndDrawing();
913 }
914 else
915 {
916 dc.BeginDrawing();
457814b5 917 dc.SetLogicalFunction(wxXOR);
ae8351fc
JS
918 wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
919 dc.SetPen(pen);
c030b70f 920 dc.SetBrush(* wxTRANSPARENT_BRUSH);
457814b5
JS
921
922 DrawBoundingBox(dc, (int)(x - dragOffsetX), (int)(y - dragOffsetY), width, height);
923
924 // Also draw bounding boxes for other selected items
c030b70f 925 wxNode *node = panel->GetChildren().First();
457814b5
JS
926 while (node)
927 {
928 wxWindow *win = (wxWindow *)node->Data();
929 if (win->IsKindOf(CLASSINFO(wxControl)))
930 {
931 wxControl *item = (wxControl *)win;
932 wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
933 if ((item != handlerControl) && handler->IsSelected())
934 {
935 int x1, y1, w1, h1;
936 item->GetPosition(&x1, &y1);
937 item->GetSize(&w1, &h1);
938 int x2 = (int)(x1 + (x - dragOffsetX) - xpos);
939 int y2 = (int)(y1 + (y - dragOffsetY) - ypos);
940 handler->DrawBoundingBox(dc, x2, y2, w1, h1);
941 }
942 }
943 node = node->Next();
944 }
457814b5
JS
945 dc.EndDrawing();
946 }
947}
948
949void wxResourceEditorControlHandler::OnDragEnd(int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
950{
951 wxPanel *panel = (wxPanel *)handlerControl->GetParent();
457814b5
JS
952
953 dc.BeginDrawing();
954
955 int xpos, ypos, width, height;
956 handlerControl->GetPosition(&xpos, &ypos);
957 handlerControl->GetSize(&width, &height);
958
fd71308f
JS
959 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerControl);
960 wxItemResource* parentResource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerControl->GetParent());
961
457814b5
JS
962 if (selectionHandle > 0)
963 {
964 int x1, y1, width1, height1;
965
966 switch (selectionHandle)
967 {
968 case 1:
969 x1 = xpos;
970 y1 = y;
971 width1 = width;
972 height1 = (ypos + height) - y;
973 break;
974 case 5:
975 x1 = xpos;
976 y1 = ypos;
977 width1 = width;
978 height1 = (y - ypos);
979 break;
980 case 3:
981 x1 = xpos;
982 y1 = ypos;
983 width1 = (x - xpos);
984 height1 = height;
985 break;
986 case 7:
987 x1 = x;
988 y1 = ypos;
989 width1 = (xpos + width) - x;
990 height1 = height;
991 break;
992 case 2:
993 x1 = xpos;
994 y1 = y;
995 width1 = (x - xpos);
996 height1 = (ypos + height) - y;
997 break;
998 case 4:
999 x1 = xpos;
1000 y1 = ypos;
1001 width1 = (x - xpos);
1002 height1 = (y - ypos);
1003 break;
1004 case 6:
1005 x1 = x;
1006 y1 = ypos;
1007 width1 = (xpos + width) - x;
1008 height1 = y - ypos;
1009 break;
1010 case 8:
1011 x1 = x;
1012 y1 = y;
1013 width1 = (xpos + width) - x;
1014 height1 = (ypos + height) - y;
1015 break;
1016 }
e3a43801 1017 // Update the associated resource
fd71308f
JS
1018 // We need to convert to dialog units if this is not a dialog or panel, but
1019 // the parent resource specifies dialog units.
e3a43801
JS
1020 int resourceX = x1;
1021 int resourceY = y1;
1022 int resourceWidth = width1;
1023 int resourceHeight = height1;
1024
fd71308f
JS
1025 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1026 {
1027 wxPoint pt = handlerControl->GetParent()->ConvertPixelsToDialog(wxPoint(x1, y1));
fd71308f 1028 wxSize sz = handlerControl->GetParent()->ConvertPixelsToDialog(wxSize(width1, height1));
e3a43801
JS
1029
1030 // Convert back so we've rounded down
1031 sz = handlerControl->GetParent()->ConvertDialogToPixels(sz);
1032 sz = handlerControl->GetParent()->ConvertPixelsToDialog(sz);
1033 resourceWidth = sz.x; resourceHeight = sz.y;
1034
1035 sz = handlerControl->GetParent()->ConvertDialogToPixels(sz);
1036 width1 = sz.x;
1037 height1 = sz.y;
1038
1039 pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
1040 pt = handlerControl->GetParent()->ConvertPixelsToDialog(pt);
1041 resourceX = pt.x; resourceY = pt.y;
1042
1043 pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
1044 x1 = pt.x;
1045 y1 = pt.y;
fd71308f 1046 }
e3a43801
JS
1047 handlerControl->SetSize(x1, y1, width1, height1);
1048 resource->SetSize(resourceX, resourceY, resourceWidth, resourceHeight);
457814b5
JS
1049 }
1050 else
1051 {
e3a43801
JS
1052 // Correction 31/12/98. We need to round down the values to take into account
1053 // the fact that several pixels map to the same dialog unit.
1054
fd71308f
JS
1055 int newX = (int)(x - dragOffsetX);
1056 int newY = (int)(y - dragOffsetY);
e3a43801
JS
1057 int resourceX = newX;
1058 int resourceY = newY;
fd71308f 1059
e3a43801 1060 // Update the associated resource
fd71308f
JS
1061 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1062 {
1063 wxPoint pt = handlerControl->GetParent()->ConvertPixelsToDialog(wxPoint(newX, newY));
e3a43801
JS
1064 pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
1065 pt = handlerControl->GetParent()->ConvertPixelsToDialog(pt);
1066 resourceX = pt.x; resourceY = pt.y;
1067 pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
1068
1069 // Having converted it several times, we know it'll map to dialog units exactly.
1070 newX = pt.x;
1071 newY = pt.y;
fd71308f 1072 }
e3a43801
JS
1073 handlerControl->Move(newX, newY);
1074 OldOnMove(newX, newY);
1075
1076 resource->SetSize(resourceX, resourceY, resource->GetWidth(), resource->GetHeight());
457814b5
JS
1077
1078 // Also move other selected items
c030b70f 1079 wxNode *node = panel->GetChildren().First();
457814b5
JS
1080 while (node)
1081 {
1082 wxWindow *win = (wxWindow *)node->Data();
1083 if (win->IsKindOf(CLASSINFO(wxControl)))
1084 {
1085 wxControl *item = (wxControl *)win;
1086 wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
1087 if ((item != handlerControl) && handler->IsSelected())
1088 {
1089 int x1, y1;
1090 item->GetPosition(&x1, &y1);
1091 int x2 = (int)(x1 + (x - dragOffsetX) - xpos);
1092 int y2 = (int)(y1 + (y - dragOffsetY) - ypos);
fd71308f 1093
e3a43801 1094 // Update the associated resource
fd71308f
JS
1095 resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item);
1096 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1097 {
e3a43801
JS
1098 wxPoint pt = item->GetParent()->ConvertPixelsToDialog(wxPoint(x2, y2));
1099 pt = item->GetParent()->ConvertDialogToPixels(pt);
1100 pt = item->GetParent()->ConvertPixelsToDialog(pt);
1101
1102 resourceX = pt.x; resourceY = pt.y;
1103 pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
1104
1105 // Having converted it several times, we know it'll map to dialog units exactly
1106 x2 = pt.x;
1107 y2 = pt.y;
fd71308f 1108 }
e3a43801
JS
1109
1110 item->Move(x2, y2);
1111 ((wxResourceEditorControlHandler *)item->GetEventHandler())->OldOnMove(x2, y2);
1112 ((wxResourceEditorControlHandler *)item->GetEventHandler())->DrawSelectionHandles(dc);
1113
1114 resource->SetSize(resourceX, resourceY, resource->GetWidth(), resource->GetHeight());
fd71308f 1115
457814b5
JS
1116 }
1117 }
1118 node = node->Next();
1119 }
1120 }
457814b5
JS
1121 dc.SetOptimization(FALSE);
1122
1123 dc.SetLogicalFunction(wxCOPY);
c030b70f
JS
1124 dc.SetPen(* wxBLACK_PEN);
1125 dc.SetBrush(* wxBLACK_BRUSH);
457814b5
JS
1126
1127 dc.SetOptimization(TRUE);
1128
1129 // Force it to repaint the selection handles (if any)
1130 // since the panel thinks we're still within a drag and
1131 // won't paint the handles.
1132 if (IsSelected())
1133 DrawSelectionHandles(dc);
1134
1135 dc.EndDrawing();
1136
1137 panel->Refresh();
1138}
1139
1140// These functions call OnItemEvent, OnItemMove and OnItemSize
1141// by default.
1142void wxResourceEditorControlHandler::OnMouseEvent(wxMouseEvent& event)
1143{
ae8351fc 1144/*
457814b5
JS
1145 if ((event.m_eventType == wxEVENT_TYPE_LEFT_DCLICK) ||
1146 (event.m_eventType == wxEVENT_TYPE_RIGHT_DCLICK))
1147 return;
ae8351fc 1148*/
457814b5
JS
1149 wxWindow *panel = handlerControl->GetParent();
1150 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1151 return;
1152 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1153 if ( !panelHandler->GetEvtHandlerEnabled() )
1154 {
1155 event.Skip();
1156 return;
1157 }
1158
1159 panelHandler->OnItemEvent(handlerControl, event);
1160}
1161
1162void wxResourceEditorControlHandler::OldOnMove(int x, int y)
1163{
1164 wxWindow *panel = handlerControl->GetParent();
1165 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1166 return;
1167
1168 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1169 panelHandler->OnItemMove(handlerControl, x, y);
1170}
1171
1172void wxResourceEditorControlHandler::OldOnSize(int w, int h)
1173{
1174 wxWindow *panel = handlerControl->GetParent();
1175 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1176 return;
1177
1178 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1179 panelHandler->OnItemSize(handlerControl, w, h);
1180}
1181
1182void wxResourceEditorControlHandler::OnSelect(bool select)
1183{
1184 wxWindow *panel = handlerControl->GetParent();
1185 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1186 return;
1187
1188 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1189 panelHandler->OnItemSelect(handlerControl, select);
1190}
1191
1192void wxResourceEditorControlHandler::OnLeftClick(int x, int y, int keys)
1193{
1194 wxWindow *panel = handlerControl->GetParent();
1195 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1196 return;
1197
1198 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1199 panelHandler->OnItemLeftClick(handlerControl, x, y, keys);
1200}
1201
1202void wxResourceEditorControlHandler::OnRightClick(int x, int y, int keys)
1203{
1204 wxWindow *panel = handlerControl->GetParent();
1205 if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
1206 return;
1207
1208 wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
1209 panelHandler->OnItemRightClick(handlerControl, x, y, keys);
1210}
1211
1212