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