git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7237 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1206 lines
37 KiB
C++
1206 lines
37 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: dlghndlr.cpp
|
|
// Purpose: Dialog handler
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 04/01/98
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows license
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __GNUG__
|
|
#pragma implementation
|
|
#endif
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include "reseditr.h"
|
|
#include "winprop.h"
|
|
#include "dlghndlr.h"
|
|
#include "edlist.h"
|
|
|
|
IMPLEMENT_CLASS(wxResourceEditorDialogHandler, wxEvtHandler)
|
|
IMPLEMENT_CLASS(wxResourceEditorControlHandler, wxEvtHandler)
|
|
|
|
BEGIN_EVENT_TABLE(wxResourceEditorDialogHandler, wxEvtHandler)
|
|
EVT_PAINT(wxResourceEditorDialogHandler::OnPaint)
|
|
EVT_MOUSE_EVENTS(wxResourceEditorDialogHandler::OnMouseEvent)
|
|
EVT_SIZE(wxResourceEditorDialogHandler::OnSize)
|
|
END_EVENT_TABLE()
|
|
|
|
BEGIN_EVENT_TABLE(wxResourceEditorControlHandler, wxEvtHandler)
|
|
EVT_MOUSE_EVENTS(wxResourceEditorControlHandler::OnMouseEvent)
|
|
END_EVENT_TABLE()
|
|
|
|
/*
|
|
* Dialog box event handler
|
|
*/
|
|
|
|
wxResourceEditorDialogHandler::wxResourceEditorDialogHandler(wxPanel *dialog, wxItemResource *resource,
|
|
wxEvtHandler *oldHandler, wxResourceManager *manager)
|
|
{
|
|
handlerDialog = dialog;
|
|
handlerResource = resource;
|
|
handlerOldHandler = oldHandler;
|
|
resourceManager = manager;
|
|
|
|
dragMode = wxDRAG_MODE_NONE;
|
|
dragType = wxDRAG_TYPE_NONE;
|
|
dragItem = NULL;
|
|
firstDragX = 0;
|
|
firstDragY = 0;
|
|
oldDragX = 0;
|
|
oldDragY = 0;
|
|
dragTolerance = 3;
|
|
checkTolerance = TRUE;
|
|
m_mouseCaptured = FALSE;
|
|
// m_treeItem = 0;
|
|
}
|
|
|
|
wxResourceEditorDialogHandler::~wxResourceEditorDialogHandler(void)
|
|
{
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnItemSelect(wxControl *item, bool select)
|
|
{
|
|
if (select)
|
|
resourceManager->AddSelection(item);
|
|
else
|
|
resourceManager->RemoveSelection(item);
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(handlerDialog);
|
|
|
|
PaintSelectionHandles(dc);
|
|
}
|
|
|
|
// Add event handlers for all children
|
|
void wxResourceEditorDialogHandler::AddChildHandlers(void)
|
|
{
|
|
wxNode *node = handlerDialog->GetChildren().First();
|
|
while ( node )
|
|
{
|
|
wxControl *child = (wxControl *)node->Data();
|
|
wxEvtHandler *childHandler = child->GetEventHandler();
|
|
if ( child->IsKindOf(CLASSINFO(wxControl)) && childHandler == child )
|
|
child->PushEventHandler(new wxResourceEditorControlHandler(child, childHandler));
|
|
node = node->Next();
|
|
}
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnLeftClick(int x, int y, int keys)
|
|
{
|
|
if (keys & wxKEY_CTRL)
|
|
{
|
|
wxResourceManager::GetCurrentResourceManager()->EditWindow(handlerDialog);
|
|
return;
|
|
}
|
|
|
|
// Deselect all items if click on panel
|
|
if (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection() == RESED_POINTER)
|
|
{
|
|
int needsRefresh = 0;
|
|
wxNode *node = handlerDialog->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxControl *item = (wxControl *)node->Data();
|
|
wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
if (item->IsKindOf(CLASSINFO(wxControl)) && childHandler->IsSelected())
|
|
{
|
|
needsRefresh ++;
|
|
OnItemSelect(item, FALSE);
|
|
childHandler->SelectItem(FALSE);
|
|
}
|
|
node = node->Next();
|
|
}
|
|
if (needsRefresh > 0)
|
|
{
|
|
wxClientDC dc(handlerDialog);
|
|
dc.Clear();
|
|
handlerDialog->Refresh();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Round down to take account of dialog units
|
|
wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerDialog);
|
|
if (resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
|
|
{
|
|
wxPoint pt = handlerDialog->ConvertPixelsToDialog(wxPoint(x, y));
|
|
|
|
// Convert back so we've rounded down
|
|
pt = handlerDialog->ConvertDialogToPixels(pt);
|
|
pt = handlerDialog->ConvertPixelsToDialog(pt);
|
|
pt = handlerDialog->ConvertDialogToPixels(pt);
|
|
x = pt.x;
|
|
y = pt.y;
|
|
}
|
|
|
|
switch (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection())
|
|
{
|
|
case RESED_BUTTON:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxButton", x, y);
|
|
break;
|
|
case RESED_BMPBUTTON:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxBitmapButton", x, y, TRUE);
|
|
break;
|
|
case RESED_STATICTEXT:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticText", x, y);
|
|
break;
|
|
case RESED_STATICBMP:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticBitmap", x, y, TRUE);
|
|
break;
|
|
case RESED_TEXTCTRL_SINGLE:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxTextCtrl (single-line)", x, y);
|
|
break;
|
|
case RESED_TEXTCTRL_MULTIPLE:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxTextCtrl (multi-line)", x, y);
|
|
break;
|
|
case RESED_CHOICE:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxChoice", x, y);
|
|
break;
|
|
case RESED_COMBOBOX:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxComboBox", x, y);
|
|
break;
|
|
case RESED_CHECKBOX:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxCheckBox", x, y);
|
|
break;
|
|
case RESED_RADIOBOX:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxRadioBox", x, y);
|
|
break;
|
|
case RESED_RADIOBUTTON:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxRadioButton", x, y);
|
|
break;
|
|
case RESED_LISTBOX:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxListBox", x, y);
|
|
break;
|
|
case RESED_SLIDER:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxSlider", x, y);
|
|
break;
|
|
case RESED_GAUGE:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxGauge", x, y);
|
|
break;
|
|
case RESED_STATICBOX:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxStaticBox", x, y);
|
|
break;
|
|
case RESED_SCROLLBAR:
|
|
resourceManager->CreatePanelItem(handlerResource, handlerDialog, "wxScrollBar", x, y);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Now switch pointer on.
|
|
if (wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->GetSelection() != RESED_POINTER)
|
|
{
|
|
wxResourceManager::GetCurrentResourceManager()->GetEditorControlList()->SetItemState(RESED_POINTER, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnRightClick(int x, int y, int WXUNUSED(keys))
|
|
{
|
|
wxMenu *menu = resourceManager->GetPopupMenu();
|
|
menu->SetClientData((char *)handlerDialog);
|
|
handlerDialog->PopupMenu(menu, x, y);
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnItemLeftClick(wxControl *item, int WXUNUSED(x), int WXUNUSED(y), int keys)
|
|
{
|
|
if (keys & wxKEY_CTRL)
|
|
{
|
|
wxResourceManager::GetCurrentResourceManager()->EditWindow(item);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
// If this is a wxStaticBox and the pointer isn't an arrow, chances
|
|
// are that we really meant to place an item on the panel.
|
|
// Fake this event.
|
|
if ((item->GetClassInfo() == CLASSINFO(wxStaticBox)) && resourceManager->GetEditorPalette()->currentlySelected != PALETTE_ARROW)
|
|
{
|
|
OnLeftClick(x, y, keys);
|
|
return;
|
|
}
|
|
*/
|
|
|
|
wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
|
|
if (childHandler->IsSelected())
|
|
{
|
|
childHandler->SelectItem(FALSE);
|
|
OnItemSelect(item, FALSE);
|
|
|
|
wxClientDC dc(handlerDialog);
|
|
dc.Clear();
|
|
handlerDialog->Refresh();
|
|
}
|
|
else
|
|
{
|
|
childHandler->SelectItem(TRUE);
|
|
OnItemSelect(item, TRUE);
|
|
|
|
// Deselect other items if shift is not pressed
|
|
int needsRefresh = 0;
|
|
if (!(keys & wxKEY_SHIFT))
|
|
{
|
|
wxNode *node = item->GetParent()->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxControl *child = (wxControl *)node->Data();
|
|
wxResourceEditorControlHandler *childHandler2 = (wxResourceEditorControlHandler *)child->GetEventHandler();
|
|
if (child->IsKindOf(CLASSINFO(wxControl)) && childHandler2->IsSelected() && child != item)
|
|
{
|
|
childHandler2->SelectItem(FALSE);
|
|
OnItemSelect(child, FALSE);
|
|
needsRefresh ++;
|
|
}
|
|
node = node->Next();
|
|
}
|
|
}
|
|
|
|
wxClientDC dc(handlerDialog);
|
|
childHandler->DrawSelectionHandles(dc);
|
|
|
|
if (needsRefresh > 0)
|
|
{
|
|
dc.Clear();
|
|
handlerDialog->Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnItemRightClick(wxControl *item, int x, int y, int WXUNUSED(keys))
|
|
{
|
|
/*
|
|
if (keys & wxKEY_CTRL)
|
|
{
|
|
wxDebugMsg("Item %s, selected = %d\n", item->GetName(), item->IsSelected());
|
|
return;
|
|
}
|
|
*/
|
|
|
|
wxMenu *menu = resourceManager->GetPopupMenu();
|
|
menu->SetClientData((char *)item);
|
|
handlerDialog->PopupMenu(menu, x, y);
|
|
}
|
|
|
|
// Under Windows 95, you can resize a panel interactively depending on
|
|
// window styles.
|
|
void wxResourceEditorDialogHandler::OnSize(wxSizeEvent& event)
|
|
{
|
|
// Update the associated resource
|
|
int w, h;
|
|
handlerDialog->GetClientSize(& w, & h);
|
|
|
|
wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerDialog);
|
|
if (resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
|
|
{
|
|
wxSize sz = handlerDialog->ConvertPixelsToDialog(wxSize(w, h));
|
|
w = sz.x; h = sz.y;
|
|
}
|
|
resource->SetSize(resource->GetX(), resource->GetY(), w, h);
|
|
}
|
|
|
|
// An event outside any items: may be a drag event.
|
|
void wxResourceEditorDialogHandler::OnMouseEvent(wxMouseEvent& event)
|
|
{
|
|
if (GetEvtHandlerEnabled())
|
|
{
|
|
// If we're dragging an item or selection handle,
|
|
// continue dragging.
|
|
if (dragMode != wxDRAG_MODE_NONE)
|
|
{
|
|
ProcessItemEvent(dragItem, event, dragType);
|
|
return;
|
|
}
|
|
|
|
wxCoord x, y;
|
|
event.GetPosition(&x, &y);
|
|
|
|
// Find which selection handle we're on, if any
|
|
wxNode *node = handlerDialog->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxWindow *win = (wxWindow *)node->Data();
|
|
if (win->IsKindOf(CLASSINFO(wxControl)))
|
|
{
|
|
wxControl *item = (wxControl *)win;
|
|
wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
int selHandle = childHandler->SelectionHandleHitTest(x, y);
|
|
if (selHandle > 0)
|
|
{
|
|
ProcessItemEvent(item, event, selHandle);
|
|
return;
|
|
}
|
|
}
|
|
node = node->Next();
|
|
}
|
|
|
|
// We're not on an item or selection handle.
|
|
// so... check for a left or right click event
|
|
// to send to the application.
|
|
int keys = 0;
|
|
if (event.ShiftDown()) keys = keys | wxKEY_SHIFT;
|
|
if (event.ControlDown()) keys = keys | wxKEY_CTRL;
|
|
|
|
if (event.LeftUp())
|
|
{
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
|
|
OnLeftClick(x, y, keys);
|
|
}
|
|
else if (event.RightDown())
|
|
{
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
|
|
OnRightClick(x, y, keys);
|
|
}
|
|
else if (event.LeftDClick())
|
|
{
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
wxResourceManager::GetCurrentResourceManager()->EditWindow(handlerDialog);
|
|
}
|
|
}
|
|
else
|
|
event.Skip();
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::OnItemEvent(wxControl *item, wxMouseEvent& event)
|
|
{
|
|
if (!GetEvtHandlerEnabled())
|
|
return;
|
|
|
|
// Not a selection handle event: just a normal item event.
|
|
// Transform to panel coordinates.
|
|
wxCoord x, y;
|
|
item->GetPosition(&x, &y);
|
|
|
|
event.m_x = event.m_x + x;
|
|
event.m_y = event.m_y + y;
|
|
|
|
ProcessItemEvent(item, event, dragType);
|
|
}
|
|
|
|
void wxResourceEditorDialogHandler::ProcessItemEvent(wxControl *item, wxMouseEvent& event, int selectionHandle)
|
|
{
|
|
wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
|
|
wxCoord x, y;
|
|
event.GetPosition(&x, &y);
|
|
int keys = 0;
|
|
if (event.ShiftDown()) keys = keys | wxKEY_SHIFT;
|
|
if (event.ControlDown()) keys = keys | wxKEY_CTRL;
|
|
bool dragging = event.Dragging();
|
|
if (dragging)
|
|
{
|
|
int dx = (int)abs((x - firstDragX));
|
|
int dy = (int)abs((y - firstDragY));
|
|
if (checkTolerance && (dx <= dragTolerance) && (dy <= dragTolerance))
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
// If we've ignored the tolerance once, then ALWAYS ignore
|
|
// tolerance in this drag, even if we come back within
|
|
// the tolerance range.
|
|
{
|
|
checkTolerance = FALSE;
|
|
}
|
|
}
|
|
if (event.LeftDClick())
|
|
{
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
|
|
wxResourceManager::GetCurrentResourceManager()->EditWindow(item);
|
|
}
|
|
else if (dragging && dragItem && dragMode == wxDRAG_MODE_START_LEFT)
|
|
{
|
|
dragMode = wxDRAG_MODE_CONTINUE_LEFT;
|
|
wxClientDC dc(handlerDialog);
|
|
childHandler->OnDragBegin(x, y, keys, dc, selectionHandle);
|
|
oldDragX = x; oldDragY = y;
|
|
if (!m_mouseCaptured)
|
|
{
|
|
handlerDialog->CaptureMouse();
|
|
m_mouseCaptured = TRUE;
|
|
}
|
|
}
|
|
else if (dragging && dragItem && dragMode == wxDRAG_MODE_CONTINUE_LEFT)
|
|
{
|
|
wxClientDC dc(handlerDialog);
|
|
childHandler->OnDragContinue(FALSE, oldDragX, oldDragY, keys, dc, selectionHandle);
|
|
childHandler->OnDragContinue(TRUE, x, y, keys, dc, selectionHandle);
|
|
oldDragX = x; oldDragY = y;
|
|
}
|
|
else if (event.LeftUp() && dragItem && dragMode == wxDRAG_MODE_CONTINUE_LEFT)
|
|
{
|
|
wxClientDC dc(handlerDialog);
|
|
dragMode = wxDRAG_MODE_NONE;
|
|
checkTolerance = TRUE;
|
|
|
|
childHandler->OnDragContinue(FALSE, oldDragX, oldDragY, keys, dc, selectionHandle);
|
|
childHandler->OnDragEnd(x, y, keys, dc, selectionHandle);
|
|
|
|
dragItem = NULL;
|
|
dragType = wxDRAG_TYPE_NONE;
|
|
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
}
|
|
else if (dragging && dragItem && dragMode == wxDRAG_MODE_START_RIGHT)
|
|
{
|
|
wxClientDC dc(handlerDialog);
|
|
dragMode = wxDRAG_MODE_CONTINUE_RIGHT;
|
|
childHandler->OnDragBegin(x, y, keys, dc, selectionHandle);
|
|
oldDragX = x; oldDragY = y;
|
|
|
|
if (!m_mouseCaptured)
|
|
{
|
|
handlerDialog->CaptureMouse();
|
|
m_mouseCaptured = TRUE;
|
|
}
|
|
}
|
|
else if (dragging && dragItem && dragMode == wxDRAG_MODE_CONTINUE_RIGHT)
|
|
{
|
|
oldDragX = x; oldDragY = y;
|
|
}
|
|
// Obsolete; no longer try to right-drag
|
|
else if (event.RightUp() && dragItem && dragMode == wxDRAG_MODE_CONTINUE_RIGHT)
|
|
{
|
|
dragMode = wxDRAG_MODE_NONE;
|
|
checkTolerance = TRUE;
|
|
dragItem = NULL;
|
|
dragType = wxDRAG_TYPE_NONE;
|
|
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
}
|
|
else if (event.IsButton())
|
|
{
|
|
checkTolerance = TRUE;
|
|
|
|
if (event.LeftDown())
|
|
{
|
|
dragItem = item;
|
|
dragMode = wxDRAG_MODE_START_LEFT;
|
|
firstDragX = x;
|
|
firstDragY = y;
|
|
dragType = selectionHandle;
|
|
|
|
if (!m_mouseCaptured)
|
|
{
|
|
handlerDialog->CaptureMouse();
|
|
m_mouseCaptured = TRUE;
|
|
}
|
|
}
|
|
else if (event.RightDown())
|
|
{
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
|
|
if (item)
|
|
childHandler->OnRightClick(x, y, keys);
|
|
else
|
|
OnRightClick(x, y, keys);
|
|
|
|
dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
|
|
|
|
/*
|
|
dragItem = item;
|
|
dragMode = wxDRAG_MODE_START_RIGHT;
|
|
firstDragX = x;
|
|
firstDragY = y;
|
|
dragType = selectionHandle;
|
|
|
|
if (!m_mouseCaptured)
|
|
{
|
|
handlerDialog->CaptureMouse();
|
|
m_mouseCaptured = TRUE;
|
|
}
|
|
*/
|
|
}
|
|
else if (event.LeftUp())
|
|
{
|
|
if (dragItem)
|
|
childHandler->OnLeftClick(x, y, keys);
|
|
else
|
|
OnLeftClick(x, y, keys);
|
|
|
|
dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
|
|
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
}
|
|
else if (event.RightUp())
|
|
{
|
|
/*
|
|
if (dragItem)
|
|
childHandler->OnRightClick(x, y, keys);
|
|
else
|
|
OnRightClick(x, y, keys);
|
|
|
|
dragItem = NULL; dragMode = wxDRAG_MODE_NONE; dragType = wxDRAG_TYPE_NONE;
|
|
|
|
if (m_mouseCaptured)
|
|
{
|
|
handlerDialog->ReleaseMouse();
|
|
m_mouseCaptured = FALSE;
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
// Calls DrawSelectionHandles for all items if
|
|
// edit mode is on.
|
|
void wxResourceEditorDialogHandler::PaintSelectionHandles(wxDC& dc)
|
|
{
|
|
if (!GetEvtHandlerEnabled())
|
|
return;
|
|
|
|
dc.BeginDrawing();
|
|
|
|
wxNode *node = handlerDialog->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxWindow *win = (wxWindow *)node->Data();
|
|
if (win->IsKindOf(CLASSINFO(wxControl)))
|
|
{
|
|
wxControl *item = (wxControl *)win;
|
|
wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
|
|
// Don't draw handles for an item that's being moved: it'll
|
|
// smear.
|
|
if (childHandler->IsSelected() && (item != dragItem))
|
|
childHandler->DrawSelectionHandles(dc);
|
|
}
|
|
node = node->Next();
|
|
}
|
|
dc.EndDrawing();
|
|
}
|
|
|
|
/*
|
|
* Event handler for controls
|
|
*/
|
|
|
|
int wxResourceEditorControlHandler::dragOffsetX = 0;
|
|
int wxResourceEditorControlHandler::dragOffsetY = 0;
|
|
|
|
wxResourceEditorControlHandler::wxResourceEditorControlHandler(wxControl *control,
|
|
wxEvtHandler *oldHandler)
|
|
{
|
|
handlerControl = control;
|
|
handlerOldHandler = oldHandler;
|
|
|
|
handleSize = 6;
|
|
handleMargin = 1;
|
|
isSelected = FALSE;
|
|
dragOffsetX = 0;
|
|
dragOffsetY = 0;
|
|
// m_treeItem = 0;
|
|
}
|
|
|
|
wxResourceEditorControlHandler::~wxResourceEditorControlHandler(void)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Manipulation and drawing of items in Edit Mode
|
|
*/
|
|
|
|
void wxResourceEditorControlHandler::SelectItem(bool select)
|
|
{
|
|
isSelected = select;
|
|
}
|
|
|
|
// Returns TRUE or FALSE
|
|
bool wxResourceEditorControlHandler::HitTest(int x, int y)
|
|
{
|
|
int xpos, ypos, width, height;
|
|
handlerControl->GetPosition(&xpos, &ypos);
|
|
handlerControl->GetSize(&width, &height);
|
|
|
|
return ((x >= xpos) && (x <= (xpos + width)) && (y >= ypos) && (y <= (ypos + height)));
|
|
}
|
|
|
|
// Calculate position of the 8 handles
|
|
void wxResourceEditorControlHandler::CalcSelectionHandles(int *hx, int *hy)
|
|
{
|
|
int xpos, ypos, width, height;
|
|
handlerControl->GetPosition(&xpos, &ypos);
|
|
handlerControl->GetSize(&width, &height);
|
|
int middleX = (xpos + (width/2));
|
|
int middleY = (ypos + (height/2));
|
|
|
|
// Start from top middle, clockwise.
|
|
/*
|
|
7 0 1
|
|
|
|
6 2
|
|
|
|
5 4 3
|
|
*/
|
|
|
|
hx[0] = (int)(middleX - (handleSize/2));
|
|
hy[0] = ypos - handleSize - handleMargin;
|
|
|
|
hx[1] = xpos + width + handleMargin;
|
|
hy[1] = ypos - handleSize - handleMargin;
|
|
|
|
hx[2] = xpos + width + handleMargin;
|
|
hy[2] = (int)(middleY - (handleSize/2));
|
|
|
|
hx[3] = xpos + width + handleMargin;
|
|
hy[3] = ypos + height + handleMargin;
|
|
|
|
hx[4] = (int)(middleX - (handleSize/2));
|
|
hy[4] = ypos + height + handleMargin;
|
|
|
|
hx[5] = xpos - handleSize - handleMargin;
|
|
hy[5] = ypos + height + handleMargin;
|
|
|
|
hx[6] = xpos - handleSize - handleMargin;
|
|
hy[6] = (int)(middleY - (handleSize/2));
|
|
|
|
hx[7] = xpos - handleSize - handleMargin;
|
|
hy[7] = ypos - handleSize - handleMargin;
|
|
}
|
|
|
|
// Returns 0 (no hit), 1 - 8 for which selection handle
|
|
// (clockwise from top middle)
|
|
int wxResourceEditorControlHandler::SelectionHandleHitTest(int x, int y)
|
|
{
|
|
// Handle positions
|
|
int hx[8];
|
|
int hy[8];
|
|
CalcSelectionHandles(hx, hy);
|
|
|
|
int i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if ((x >= hx[i]) && (x <= (hx[i] + handleSize)) && (y >= hy[i]) && (y <= (hy[i] + handleSize)))
|
|
return (i + 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::DrawSelectionHandles(wxDC& dc, bool WXUNUSED(erase))
|
|
{
|
|
dc.SetOptimization(FALSE);
|
|
|
|
dc.SetLogicalFunction(wxCOPY);
|
|
dc.SetPen(* wxBLACK_PEN);
|
|
dc.SetBrush(* wxBLACK_BRUSH);
|
|
|
|
dc.SetOptimization(TRUE);
|
|
|
|
// Handle positions
|
|
int hx[8];
|
|
int hy[8];
|
|
CalcSelectionHandles(hx, hy);
|
|
|
|
int i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
dc.DrawRectangle(hx[i], hy[i], handleSize, handleSize);
|
|
}
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::DrawBoundingBox(wxDC& dc, int x, int y, int w, int h)
|
|
{
|
|
dc.DrawRectangle(x, y, w, h);
|
|
}
|
|
|
|
// If selectionHandle is zero, not dragging the selection handle.
|
|
void wxResourceEditorControlHandler::OnDragBegin(int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
|
|
{
|
|
int xpos, ypos, width, height;
|
|
handlerControl->GetPosition(&xpos, &ypos);
|
|
handlerControl->GetSize(&width, &height);
|
|
|
|
dc.BeginDrawing();
|
|
|
|
// dc.DestroyClippingRegion();
|
|
|
|
wxPanel *panel = (wxPanel *)handlerControl->GetParent();
|
|
|
|
// Erase selection handles
|
|
// DrawSelectionHandles(dc, TRUE);
|
|
|
|
dc.SetOptimization(FALSE);
|
|
|
|
dc.SetLogicalFunction(wxINVERT);
|
|
|
|
wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
|
|
dc.SetPen(pen);
|
|
dc.SetBrush(* wxTRANSPARENT_BRUSH);
|
|
|
|
dc.SetOptimization(TRUE);
|
|
|
|
if (selectionHandle > 0)
|
|
{
|
|
panel->Refresh();
|
|
|
|
DrawBoundingBox(dc, xpos, ypos, width, height);
|
|
}
|
|
else
|
|
{
|
|
panel->Refresh();
|
|
|
|
dragOffsetX = (x - xpos);
|
|
dragOffsetY = (y - ypos);
|
|
|
|
DrawBoundingBox(dc, xpos, ypos, width, height);
|
|
|
|
// Also draw bounding boxes for other selected items
|
|
wxNode *node = panel->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxWindow *win = (wxWindow *)node->Data();
|
|
if (win->IsKindOf(CLASSINFO(wxControl)))
|
|
{
|
|
wxControl *item = (wxControl *)win;
|
|
wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
if ((item != handlerControl) && handler->IsSelected())
|
|
{
|
|
int x1, y1, w1, h1;
|
|
item->GetPosition(&x1, &y1);
|
|
item->GetSize(&w1, &h1);
|
|
handler->DrawBoundingBox(dc, x1, y1, w1, h1);
|
|
}
|
|
}
|
|
node = node->Next();
|
|
}
|
|
}
|
|
dc.EndDrawing();
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OnDragContinue(bool WXUNUSED(paintIt), int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
|
|
{
|
|
wxPanel *panel = (wxPanel *)handlerControl->GetParent();
|
|
int xpos, ypos, width, height;
|
|
handlerControl->GetPosition(&xpos, &ypos);
|
|
handlerControl->GetSize(&width, &height);
|
|
|
|
if (selectionHandle > 0)
|
|
{
|
|
/*
|
|
8 1 2
|
|
|
|
7 3
|
|
|
|
6 5 4
|
|
*/
|
|
|
|
int x1, y1, width1, height1;
|
|
|
|
switch (selectionHandle)
|
|
{
|
|
case 1:
|
|
x1 = xpos;
|
|
y1 = y;
|
|
width1 = width;
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
case 5:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = width;
|
|
height1 = (y - ypos);
|
|
break;
|
|
case 3:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = (x - xpos);
|
|
height1 = height;
|
|
break;
|
|
case 7:
|
|
x1 = x;
|
|
y1 = ypos;
|
|
width1 = (xpos + width) - x;
|
|
height1 = height;
|
|
break;
|
|
case 2:
|
|
x1 = xpos;
|
|
y1 = y;
|
|
width1 = (x - xpos);
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
case 4:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = (x - xpos);
|
|
height1 = (y - ypos);
|
|
break;
|
|
case 6:
|
|
x1 = x;
|
|
y1 = ypos;
|
|
width1 = (xpos + width) - x;
|
|
height1 = y - ypos;
|
|
break;
|
|
case 8:
|
|
x1 = x;
|
|
y1 = y;
|
|
width1 = (xpos + width) - x;
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
}
|
|
dc.BeginDrawing();
|
|
|
|
dc.SetLogicalFunction(wxINVERT);
|
|
wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
|
|
dc.SetPen(pen);
|
|
dc.SetBrush(* wxTRANSPARENT_BRUSH);
|
|
|
|
DrawBoundingBox(dc, x1, y1, width1, height1);
|
|
|
|
dc.EndDrawing();
|
|
}
|
|
else
|
|
{
|
|
dc.BeginDrawing();
|
|
dc.SetLogicalFunction(wxINVERT);
|
|
wxPen pen(wxColour(0, 0, 0), 1, wxDOT);
|
|
dc.SetPen(pen);
|
|
dc.SetBrush(* wxTRANSPARENT_BRUSH);
|
|
|
|
DrawBoundingBox(dc, (int)(x - dragOffsetX), (int)(y - dragOffsetY), width, height);
|
|
|
|
// Also draw bounding boxes for other selected items
|
|
wxNode *node = panel->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxWindow *win = (wxWindow *)node->Data();
|
|
if (win->IsKindOf(CLASSINFO(wxControl)))
|
|
{
|
|
wxControl *item = (wxControl *)win;
|
|
wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
if ((item != handlerControl) && handler->IsSelected())
|
|
{
|
|
int x1, y1, w1, h1;
|
|
item->GetPosition(&x1, &y1);
|
|
item->GetSize(&w1, &h1);
|
|
int x2 = (int)(x1 + (x - dragOffsetX) - xpos);
|
|
int y2 = (int)(y1 + (y - dragOffsetY) - ypos);
|
|
handler->DrawBoundingBox(dc, x2, y2, w1, h1);
|
|
}
|
|
}
|
|
node = node->Next();
|
|
}
|
|
dc.EndDrawing();
|
|
}
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OnDragEnd(int x, int y, int WXUNUSED(keys), wxDC& dc, int selectionHandle)
|
|
{
|
|
wxPanel *panel = (wxPanel *)handlerControl->GetParent();
|
|
|
|
dc.BeginDrawing();
|
|
|
|
int xpos, ypos, width, height;
|
|
handlerControl->GetPosition(&xpos, &ypos);
|
|
handlerControl->GetSize(&width, &height);
|
|
|
|
wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerControl);
|
|
wxItemResource* parentResource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(handlerControl->GetParent());
|
|
|
|
if (selectionHandle > 0)
|
|
{
|
|
int x1, y1, width1, height1;
|
|
|
|
switch (selectionHandle)
|
|
{
|
|
case 1:
|
|
x1 = xpos;
|
|
y1 = y;
|
|
width1 = width;
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
case 5:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = width;
|
|
height1 = (y - ypos);
|
|
break;
|
|
case 3:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = (x - xpos);
|
|
height1 = height;
|
|
break;
|
|
case 7:
|
|
x1 = x;
|
|
y1 = ypos;
|
|
width1 = (xpos + width) - x;
|
|
height1 = height;
|
|
break;
|
|
case 2:
|
|
x1 = xpos;
|
|
y1 = y;
|
|
width1 = (x - xpos);
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
case 4:
|
|
x1 = xpos;
|
|
y1 = ypos;
|
|
width1 = (x - xpos);
|
|
height1 = (y - ypos);
|
|
break;
|
|
case 6:
|
|
x1 = x;
|
|
y1 = ypos;
|
|
width1 = (xpos + width) - x;
|
|
height1 = y - ypos;
|
|
break;
|
|
case 8:
|
|
x1 = x;
|
|
y1 = y;
|
|
width1 = (xpos + width) - x;
|
|
height1 = (ypos + height) - y;
|
|
break;
|
|
}
|
|
// Update the associated resource
|
|
// We need to convert to dialog units if this is not a dialog or panel, but
|
|
// the parent resource specifies dialog units.
|
|
int resourceX = x1;
|
|
int resourceY = y1;
|
|
int resourceWidth = width1;
|
|
int resourceHeight = height1;
|
|
|
|
if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
|
|
{
|
|
wxPoint pt = handlerControl->GetParent()->ConvertPixelsToDialog(wxPoint(x1, y1));
|
|
wxSize sz = handlerControl->GetParent()->ConvertPixelsToDialog(wxSize(width1, height1));
|
|
|
|
// Convert back so we've rounded down
|
|
sz = handlerControl->GetParent()->ConvertDialogToPixels(sz);
|
|
sz = handlerControl->GetParent()->ConvertPixelsToDialog(sz);
|
|
resourceWidth = sz.x; resourceHeight = sz.y;
|
|
|
|
sz = handlerControl->GetParent()->ConvertDialogToPixels(sz);
|
|
width1 = sz.x;
|
|
height1 = sz.y;
|
|
|
|
pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
|
|
pt = handlerControl->GetParent()->ConvertPixelsToDialog(pt);
|
|
resourceX = pt.x; resourceY = pt.y;
|
|
|
|
pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
|
|
x1 = pt.x;
|
|
y1 = pt.y;
|
|
}
|
|
handlerControl->SetSize(x1, y1, width1, height1);
|
|
resource->SetSize(resourceX, resourceY, resourceWidth, resourceHeight);
|
|
}
|
|
else
|
|
{
|
|
// Correction 31/12/98. We need to round down the values to take into account
|
|
// the fact that several pixels map to the same dialog unit.
|
|
|
|
int newX = (int)(x - dragOffsetX);
|
|
int newY = (int)(y - dragOffsetY);
|
|
int resourceX = newX;
|
|
int resourceY = newY;
|
|
|
|
// Update the associated resource
|
|
if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
|
|
{
|
|
wxPoint pt = handlerControl->GetParent()->ConvertPixelsToDialog(wxPoint(newX, newY));
|
|
pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
|
|
pt = handlerControl->GetParent()->ConvertPixelsToDialog(pt);
|
|
resourceX = pt.x; resourceY = pt.y;
|
|
pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
|
|
|
|
// Having converted it several times, we know it'll map to dialog units exactly.
|
|
newX = pt.x;
|
|
newY = pt.y;
|
|
}
|
|
handlerControl->Move(newX, newY);
|
|
OldOnMove(newX, newY);
|
|
|
|
resource->SetSize(resourceX, resourceY, resource->GetWidth(), resource->GetHeight());
|
|
|
|
// Also move other selected items
|
|
wxNode *node = panel->GetChildren().First();
|
|
while (node)
|
|
{
|
|
wxWindow *win = (wxWindow *)node->Data();
|
|
if (win->IsKindOf(CLASSINFO(wxControl)))
|
|
{
|
|
wxControl *item = (wxControl *)win;
|
|
wxResourceEditorControlHandler *handler = (wxResourceEditorControlHandler *)item->GetEventHandler();
|
|
if ((item != handlerControl) && handler->IsSelected())
|
|
{
|
|
int x1, y1;
|
|
item->GetPosition(&x1, &y1);
|
|
int x2 = (int)(x1 + (x - dragOffsetX) - xpos);
|
|
int y2 = (int)(y1 + (y - dragOffsetY) - ypos);
|
|
|
|
resourceX = x2;
|
|
resourceY = y2;
|
|
|
|
// Update the associated resource
|
|
resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item);
|
|
if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
|
|
{
|
|
wxPoint pt = item->GetParent()->ConvertPixelsToDialog(wxPoint(x2, y2));
|
|
pt = item->GetParent()->ConvertDialogToPixels(pt);
|
|
pt = item->GetParent()->ConvertPixelsToDialog(pt);
|
|
|
|
resourceX = pt.x; resourceY = pt.y;
|
|
pt = handlerControl->GetParent()->ConvertDialogToPixels(pt);
|
|
|
|
// Having converted it several times, we know it'll map to dialog units exactly
|
|
x2 = pt.x;
|
|
y2 = pt.y;
|
|
}
|
|
|
|
item->Move(x2, y2);
|
|
((wxResourceEditorControlHandler *)item->GetEventHandler())->OldOnMove(x2, y2);
|
|
((wxResourceEditorControlHandler *)item->GetEventHandler())->DrawSelectionHandles(dc);
|
|
|
|
resource->SetSize(resourceX, resourceY, resource->GetWidth(), resource->GetHeight());
|
|
|
|
}
|
|
}
|
|
node = node->Next();
|
|
}
|
|
}
|
|
dc.SetOptimization(FALSE);
|
|
|
|
dc.SetLogicalFunction(wxCOPY);
|
|
dc.SetPen(* wxBLACK_PEN);
|
|
dc.SetBrush(* wxBLACK_BRUSH);
|
|
|
|
dc.SetOptimization(TRUE);
|
|
|
|
// Force it to repaint the selection handles (if any)
|
|
// since the panel thinks we're still within a drag and
|
|
// won't paint the handles.
|
|
if (IsSelected())
|
|
DrawSelectionHandles(dc);
|
|
|
|
dc.EndDrawing();
|
|
|
|
panel->Refresh();
|
|
}
|
|
|
|
// These functions call OnItemEvent, OnItemMove and OnItemSize
|
|
// by default.
|
|
void wxResourceEditorControlHandler::OnMouseEvent(wxMouseEvent& event)
|
|
{
|
|
/*
|
|
if ((event.m_eventType == wxEVENT_TYPE_LEFT_DCLICK) ||
|
|
(event.m_eventType == wxEVENT_TYPE_RIGHT_DCLICK))
|
|
return;
|
|
*/
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
if ( !panelHandler->GetEvtHandlerEnabled() )
|
|
{
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
panelHandler->OnItemEvent(handlerControl, event);
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OldOnMove(int x, int y)
|
|
{
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
panelHandler->OnItemMove(handlerControl, x, y);
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OldOnSize(int w, int h)
|
|
{
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
panelHandler->OnItemSize(handlerControl, w, h);
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OnSelect(bool select)
|
|
{
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
panelHandler->OnItemSelect(handlerControl, select);
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OnLeftClick(int x, int y, int keys)
|
|
{
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
panelHandler->OnItemLeftClick(handlerControl, x, y, keys);
|
|
}
|
|
|
|
void wxResourceEditorControlHandler::OnRightClick(int x, int y, int keys)
|
|
{
|
|
wxWindow *panel = handlerControl->GetParent();
|
|
if ( !panel->GetEventHandler()->IsKindOf(CLASSINFO(wxResourceEditorDialogHandler)) )
|
|
return;
|
|
|
|
wxResourceEditorDialogHandler *panelHandler = (wxResourceEditorDialogHandler *)panel->GetEventHandler();
|
|
panelHandler->OnItemRightClick(handlerControl, x, y, keys);
|
|
}
|
|
|
|
|