32#include <wx/msw/wrapwin.h>
33#include <wx/msw/private.h>
41static wxBitmap wxOPaneCreateStippleBitmap() {
42 unsigned char data[] = {0, 0, 0, 192, 192, 192, 192, 192, 192, 0, 0, 0};
43 wxImage img(2, 2, data,
true);
47static void ODrawResizeHint(wxDC& dc,
const wxRect& rect) {
49 wxBitmap stipple = wxOPaneCreateStippleBitmap();
50 wxBrush brush(stipple);
53 wxMSWDCImpl* impl = (wxMSWDCImpl*)dc.GetImpl();
54 PatBlt(GetHdcOf(*impl), rect.GetX(), rect.GetY(), rect.GetWidth(),
55 rect.GetHeight(), PATINVERT);
57 dc.SetPen(*wxTRANSPARENT_PEN);
59 dc.SetLogicalFunction(wxXOR);
60 dc.DrawRectangle(rect);
66static bool OAuiManager_HasLiveResize(wxAuiManager& manager) {
73 return (manager.GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE;
80EVT_AUI_PANE_BUTTON(wxAuiManager::OnPaneButton)
81EVT_AUI_RENDER(wxAuiManager::OnRender)
82EVT_PAINT(OCPN_AUIManager::OnPaint)
83EVT_ERASE_BACKGROUND(OCPN_AUIManager::OnEraseBackground)
84EVT_SIZE(OCPN_AUIManager::OnSize)
85EVT_SET_CURSOR(OCPN_AUIManager::OnSetCursor)
86EVT_LEFT_DOWN(OCPN_AUIManager::OnLeftDown)
87EVT_LEFT_UP(OCPN_AUIManager::OnLeftUp)
88EVT_MOTION(OCPN_AUIManager::OnMotionx)
89EVT_LEAVE_WINDOW(OCPN_AUIManager::OnLeaveWindow)
90EVT_MOUSE_CAPTURE_LOST(OCPN_AUIManager::OnCaptureLost)
91EVT_CHILD_FOCUS(OCPN_AUIManager::OnChildFocus)
92EVT_AUI_FIND_MANAGER(OCPN_AUIManager::OnFindManager)
96 : wxAuiManager(managed_wnd, flags)
100OCPN_AUIManager::~OCPN_AUIManager() {}
102void OCPN_AUIManager::OnMotionx(wxMouseEvent& event) {
109 wxPoint mouse_pos =
event.GetPosition();
110 if (m_lastMouseMove == mouse_pos)
return;
111 m_lastMouseMove = mouse_pos;
113 if (m_action == actionResize) {
116 if (m_currentDragItem != -1)
117 m_actionPart = &(m_uiParts.Item(m_currentDragItem));
119 m_currentDragItem = m_uiParts.Index(*m_actionPart);
122 wxPoint pos = m_actionPart->rect.GetPosition();
123 if (m_actionPart->orientation == wxHORIZONTAL)
124 pos.y = wxMax(0, event.m_y - m_actionOffset.y);
126 pos.x = wxMax(0, event.m_x - m_actionOffset.x);
128 wxSize client_size = m_frame->GetClientSize();
129 int used_width = 0, used_height = 0;
131 size_t dock_i, dock_count = m_docks.GetCount();
132 for (dock_i = 0; dock_i < dock_count; ++dock_i) {
133 wxAuiDockInfo& dock = m_docks.Item(dock_i);
134 if (dock.dock_direction == wxAUI_DOCK_TOP ||
135 dock.dock_direction == wxAUI_DOCK_BOTTOM) {
136 used_height += dock.size;
138 if (dock.dock_direction == wxAUI_DOCK_LEFT ||
139 dock.dock_direction == wxAUI_DOCK_RIGHT) {
140 used_width += dock.size;
146 if (OAuiManager_HasLiveResize(*
this)) {
147 m_frame->ReleaseMouse();
148 if ((used_width < client_size.x * 9 / 10) &&
149 (used_width > client_size.x * 1 / 10))
150 DoEndResizeAction(event);
152 m_frame->CaptureMouse();
154 bool bhasMouse = m_frame->HasCapture();
156 if (bhasMouse) m_frame->ReleaseMouse();
161 wxRect rect(m_frame->ClientToScreen(pos), m_actionPart->rect.GetSize());
164 if (!m_0actionHintRect.IsEmpty()) {
166 ODrawResizeHint(dc, m_0actionHintRect);
167 m_0actionHintRect = wxRect();
170 wxRect frameScreenRect = m_frame->GetScreenRect();
173 wxMax(rect.x, frameScreenRect.x + frameScreenRect.width * 1 / 10);
175 wxMin(rect.x, frameScreenRect.x + frameScreenRect.width * 9 / 10);
179 ODrawResizeHint(dc, rect);
180 m_0actionHintRect = rect;
183 if (bhasMouse) m_frame->CaptureMouse();
191bool OCPN_AUIManager::DoEndResizeAction(wxMouseEvent& event) {
193 if (m_actionPart && m_actionPart->type == wxAuiDockUIPart::typeDockSizer) {
195 int sashSize = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
197 int used_width = 0, used_height = 0;
199 wxSize client_size = m_frame->GetClientSize();
201 size_t dock_i, dock_count = m_docks.GetCount();
202 for (dock_i = 0; dock_i < dock_count; ++dock_i) {
203 wxAuiDockInfo& dock = m_docks.Item(dock_i);
204 if (dock.dock_direction == wxAUI_DOCK_TOP ||
205 dock.dock_direction == wxAUI_DOCK_BOTTOM) {
206 used_height += dock.size;
208 if (dock.dock_direction == wxAUI_DOCK_LEFT ||
209 dock.dock_direction == wxAUI_DOCK_RIGHT) {
210 used_width += dock.size;
212 if (dock.resizable) used_width += sashSize;
215 int available_width = client_size.GetWidth() - used_width;
216 int available_height = client_size.GetHeight() - used_height;
221 if (
dynamic_cast<wxFrame*
>(m_frame)) {
222 wxFrame* frame =
static_cast<wxFrame*
>(m_frame);
223 wxStatusBar* status = frame->GetStatusBar();
225 wxSize status_client_size = status->GetClientSize();
226 available_height -= status_client_size.GetHeight();
231 wxRect& rect = m_actionPart->dock->rect;
233 wxPoint new_pos(event.m_x - m_actionOffset.x, event.m_y - m_actionOffset.y);
234 int new_size, old_size = m_actionPart->dock->size;
236 switch (m_actionPart->dock->dock_direction) {
237 case wxAUI_DOCK_LEFT:
238 new_size = new_pos.x - rect.x;
239 if (new_size - old_size > available_width)
240 new_size = old_size + available_width;
241 m_actionPart->dock->size = new_size;
244 new_size = new_pos.y - rect.y;
245 if (new_size - old_size > available_height)
246 new_size = old_size + available_height;
247 m_actionPart->dock->size = new_size;
249 case wxAUI_DOCK_RIGHT:
251 rect.x + rect.width - new_pos.x - m_actionPart->rect.GetWidth();
252 if (new_size - old_size > available_width)
253 new_size = old_size + available_width;
254 m_actionPart->dock->size = new_size;
256 m_actionPart->dock->size =
257 wxMax(m_actionPart->dock->size, client_size.x * 1 / 10);
258 m_actionPart->dock->size =
259 wxMin(m_actionPart->dock->size, client_size.x * 9 / 10);
262 case wxAUI_DOCK_BOTTOM:
264 rect.y + rect.height - new_pos.y - m_actionPart->rect.GetHeight();
265 if (new_size - old_size > available_height)
266 new_size = old_size + available_height;
267 m_actionPart->dock->size = new_size;
273 }
else if (m_actionPart &&
274 m_actionPart->type == wxAuiDockUIPart::typePaneSizer) {
275 wxAuiDockInfo& dock = *m_actionPart->dock;
276 wxAuiPaneInfo& pane = *m_actionPart->pane;
278 int total_proportion = 0;
282 int caption_size = m_art->GetMetric(wxAUI_DOCKART_CAPTION_SIZE);
283 int pane_borderSize = m_art->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
284 int sashSize = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
286 wxPoint new_pos(event.m_x - m_actionOffset.x, event.m_y - m_actionOffset.y);
289 wxAuiDockUIPart* pane_part = GetPanePart(pane.window);
290 wxASSERT_MSG(pane_part,
"Pane border part not found -- shouldn't happen");
294 if (dock.IsHorizontal())
295 new_pixsize = new_pos.x - pane_part->rect.x;
297 new_pixsize = new_pos.y - pane_part->rect.y;
300 if (dock.IsHorizontal())
301 dock_pixels = dock.rect.GetWidth();
303 dock_pixels = dock.rect.GetHeight();
308 int i, dock_pane_count = dock.panes.GetCount();
309 int pane_position = -1;
310 for (i = 0; i < dock_pane_count; ++i) {
311 wxAuiPaneInfo& p = *dock.panes.Item(i);
312 if (p.window == pane.window) pane_position = i;
317 if (i > 0) dock_pixels -= sashSize;
323 if (dock.IsHorizontal())
324 dock_pixels -= p.best_size.x;
326 dock_pixels -= p.best_size.y;
328 total_proportion += p.dock_proportion;
333 if (new_pixsize > dock_pixels) new_pixsize = dock_pixels;
339 int borrow_pane = -1;
340 for (i = pane_position + 1; i < dock_pane_count; ++i) {
341 wxAuiPaneInfo& p = *dock.panes.Item(i);
350 wxASSERT_MSG(pane_position != -1,
"Pane not found in dock");
353 if (dock_pixels == 0 || total_proportion == 0 || borrow_pane == -1) {
354 m_action = actionNone;
359 int new_proportion = (new_pixsize * total_proportion) / dock_pixels;
368 if (pane.min_size.IsFullySpecified()) {
371 if (pane.HasBorder()) min_size += (pane_borderSize * 2);
374 if (pane_part->orientation == wxVERTICAL) {
375 min_size += pane.min_size.y;
376 if (pane.HasCaption()) min_size += caption_size;
378 min_size += pane.min_size.x;
388 int min_proportion = (min_size * total_proportion) / dock_pixels;
390 if (new_proportion < min_proportion) new_proportion = min_proportion;
392 int prop_diff = new_proportion - pane.dock_proportion;
397 int prop_borrow = dock.panes.Item(borrow_pane)->dock_proportion;
399 if (prop_borrow - prop_diff < 0) {
402 prop_borrow = min_proportion;
404 prop_borrow -= prop_diff;
407 dock.panes.Item(borrow_pane)->dock_proportion = prop_borrow;
408 pane.dock_proportion = new_proportion;
418void OCPN_AUIManager::OnLeftUp(wxMouseEvent& event) {
419 if (m_action == actionResize) {
420 m_frame->ReleaseMouse();
422 if (!OAuiManager_HasLiveResize(*
this)) {
425 ODrawResizeHint(dc, m_0actionHintRect);
427 if (m_currentDragItem != -1 && OAuiManager_HasLiveResize(*
this))
428 m_actionPart = &(m_uiParts.Item(m_currentDragItem));
430 DoEndResizeAction(event);
432 m_currentDragItem = -1;
434 }
else if (m_action == actionClickButton) {
435 m_hoverButton = NULL;
436 m_frame->ReleaseMouse();
439 UpdateButtonOnScreen(m_actionPart, event);
442 if (m_actionPart == HitTest(event.GetX(), event.GetY())) {
444 wxAuiManagerEvent e(wxEVT_AUI_PANE_BUTTON);
446 e.SetPane(m_actionPart->pane);
448#if wxCHECK_VERSION(3, 1, 4)
449 e.SetButton(m_actionPart->button);
451 e.SetButton(m_actionPart->button->button_id);
456 }
else if (m_action == actionClickCaption) {
457 m_frame->ReleaseMouse();
458 }
else if (m_action == actionDragFloatingPane) {
459 m_frame->ReleaseMouse();
462 else if (m_action == actionDragToolbarPane)
464 m_frame->ReleaseMouse();
466 wxAuiPaneInfo& pane = GetPane(m_actionWindow);
467 wxASSERT_MSG(pane.IsOk(),
"Pane window not found");
470 wxAuiDockInfoPtrArray docks;
471 FindDocks(m_docks, pane.dock_direction,
472 pane.dock_layer, pane.dock_row, docks);
473 if (docks.GetCount() == 1)
475 wxAuiDockInfo& dock = *docks.Item(0);
477 wxArrayInt pane_positions, pane_sizes;
478 GetPanePositionsAndSizes(dock, pane_positions, pane_sizes);
480 int i, dock_pane_count = dock.panes.GetCount();
481 for (i = 0; i < dock_pane_count; ++i)
482 dock.panes.Item(i)->dock_pos = pane_positions[i];
485 pane.state &= ~wxAuiPaneInfo::actionPane;
493 m_action = actionNone;
494 m_lastMouseMove = wxPoint();
500static void OCPNFindDocks(wxAuiDockInfoArray& docks,
int dock_direction,
501 int dock_layer,
int dock_row,
502 wxAuiDockInfoPtrArray& arr) {
503 int begin_layer = dock_layer;
504 int end_layer = dock_layer;
505 int begin_row = dock_row;
506 int end_row = dock_row;
507 int dock_count = docks.GetCount();
508 int layer, row, i, max_row = 0, max_layer = 0;
511 for (i = 0; i < dock_count; ++i) {
512 max_row = wxMax(max_row, docks.Item(i).dock_row);
513 max_layer = wxMax(max_layer, docks.Item(i).dock_layer);
517 if (dock_layer == -1) {
519 end_layer = max_layer;
523 if (dock_row == -1) {
530 for (layer = begin_layer; layer <= end_layer; ++layer)
531 for (row = begin_row; row <= end_row; ++row)
532 for (i = 0; i < dock_count; ++i) {
533 wxAuiDockInfo& d = docks.Item(i);
534 if (dock_direction == -1 || dock_direction == d.dock_direction) {
535 if (d.dock_layer == layer && d.dock_row == row) arr.Add(&d);
540wxAuiDockInfo* OCPN_AUIManager::FindDock(wxAuiPaneInfo& pane) {
541 wxAuiDockInfoPtrArray arr;
542 OCPNFindDocks(m_docks, pane.dock_direction, pane.dock_layer, pane.dock_row,
550void OCPN_AUIManager::SetDockSize(wxAuiDockInfo* dock,
int size) {
557bool OCPN_AUIManager::ProcessDockResult(wxAuiPaneInfo& target,
558 const wxAuiPaneInfo& new_pos) {
565 if (new_pos.window->GetName().IsSameAs(
"panel")) {
567 if ( (new_pos.dock_direction ==
575 if (new_pos.dock_layer == 0)
return false;
580 return wxAuiManager::ProcessDockResult(target, new_pos);
OCPN_AUIManager * g_pauimgr
Global instance.
PlugIn Object Definition/API.
int GetCanvasCount()
Gets total number of chart canvases.
int GetCanvasIndexUnderMouse()
Gets index of chart canvas under mouse cursor.