#include "wx/dcscreen.h"
#include "wx/toolbar.h"
#include "wx/image.h"
+ #include "wx/statusbr.h"
#endif
WX_CHECK_BUILD_OPTIONS("wxAUI")
// __WXGTK20__
#include <gtk/gtk.h>
+#include "wx/gtk/private/gtk2-compat.h"
static void
gtk_pseudo_window_realized_callback( GtkWidget *m_widget, void *WXUNUSED(win) )
if ((j*16+8)<amount)
region.Union(0, y, disp.x, 1);
}
- gdk_window_shape_combine_region(m_widget->window, region.GetRegion(), 0, 0);
+ gdk_window_shape_combine_region(gtk_widget_get_window(m_widget), region.GetRegion(), 0, 0);
}
return true;
}
+protected:
+ virtual void DoSetSizeHints( int minW, int minH,
+ int maxW, int maxH,
+ int incW, int incH)
+ {
+ // the real wxFrame method doesn't work for us because we're not really
+ // a top level window so skip it
+ wxWindow::DoSetSizeHints(minW, minH, maxW, maxH, incW, incH);
+ }
+
private:
DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
};
}
+bool wxAuiPaneInfo::IsValid() const
+{
+ // Should this RTTI and function call be rewritten as
+ // sending a new event type to allow other window types
+ // to check the pane settings?
+ wxAuiToolBar* toolbar = wxDynamicCast(window, wxAuiToolBar);
+ return !toolbar || toolbar->IsPaneValid(*this);
+}
+
// -- wxAuiManager class implementation --
EVT_MOUSE_CAPTURE_LOST(wxAuiManager::OnCaptureLost)
EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus)
EVT_AUI_FIND_MANAGER(wxAuiManager::OnFindManager)
- EVT_TIMER(101, wxAuiManager::OnHintFadeTimer)
END_EVENT_TABLE()
// With Core Graphics on Mac, it's not possible to show sash feedback,
// so we'll always use live update instead.
#if defined(__WXMAC__)
+ wxUnusedVar(manager);
return true;
#else
return (manager.GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE;
void wxAuiManager::UpdateHintWindowConfig()
{
- // find out if the the system can do transparent frames
+ // find out if the system can do transparent frames
bool can_do_transparent = false;
wxWindow* w = m_frame;
if (pane_info.IsDocked())
RestoreMaximizedPane();
- m_panes.Add(pane_info);
+ // special case: wxAuiToolBar style interacts with docking flags
+ wxAuiPaneInfo test(pane_info);
+ wxAuiToolBar* toolbar = wxDynamicCast(window, wxAuiToolBar);
+ if (toolbar)
+ {
+ // if pane has default docking flags
+ const unsigned int dockMask = wxAuiPaneInfo::optionLeftDockable |
+ wxAuiPaneInfo::optionRightDockable |
+ wxAuiPaneInfo::optionTopDockable |
+ wxAuiPaneInfo::optionBottomDockable;
+ const unsigned int defaultDock = wxAuiPaneInfo().
+ DefaultPane().state & dockMask;
+ if ((test.state & dockMask) == defaultDock)
+ {
+ // set docking flags based on toolbar style
+ if (toolbar->GetWindowStyleFlag() & wxAUI_TB_VERTICAL)
+ {
+ test.TopDockable(false).BottomDockable(false);
+ }
+ else if (toolbar->GetWindowStyleFlag() & wxAUI_TB_HORIZONTAL)
+ {
+ test.LeftDockable(false).RightDockable(false);
+ }
+ }
+ else
+ {
+ // see whether non-default docking flags are valid
+ test.window = window;
+ wxCHECK_MSG(test.IsValid(), false,
+ "toolbar style and pane docking flags are incompatible");
+ }
+ }
+
+ m_panes.Add(test);
wxAuiPaneInfo& pinfo = m_panes.Last();
if (pinfo.name.empty() || already_exists)
{
pinfo.name.Printf(wxT("%08lx%08x%08x%08lx"),
- wxPtrToUInt(pinfo.window) & 0xffffffff,
+ (unsigned long)(wxPtrToUInt(pinfo.window) & 0xffffffff),
(unsigned int)time(NULL),
#ifdef __WXWINCE__
(unsigned int)GetTickCount(),
{
pinfo.best_size = pinfo.window->GetClientSize();
+#if wxUSE_TOOLBAR
if (pinfo.window->IsKindOf(CLASSINFO(wxToolBar)))
{
// GetClientSize() doesn't get the best size for
// a toolbar under some newer versions of wxWidgets,
// so use GetBestSize()
pinfo.best_size = pinfo.window->GetBestSize();
-
- // for some reason, wxToolBar::GetBestSize() is returning
- // a size that is a pixel shy of the correct amount.
- // I believe this to be the correct action, until
- // wxToolBar::GetBestSize() is fixed. Is this assumption
- // correct?
- // commented out by JACS 2007-9-08 after having added a pixel in wxMSW's wxToolBar::DoGetBestSize()
- // pinfo.best_size.y++;
}
+#endif // wxUSE_TOOLBAR
if (pinfo.min_size != wxDefaultSize)
{
for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i)
{
wxAuiPaneInfo& p = m_panes.Item(i);
- if (!p.IsToolbar())
+ if (!p.IsToolbar() && !p.IsFloating())
{
p.SetFlag(wxAuiPaneInfo::optionHidden,
p.HasFlag(wxAuiPaneInfo::savedHiddenState));
if (part != wxT("layout2"))
return false;
- // mark all panes currently managed as docked and hidden
+ // Mark all panes currently managed as hidden. Also, dock all panes that are dockable.
int pane_i, pane_count = m_panes.GetCount();
for (pane_i = 0; pane_i < pane_count; ++pane_i)
- m_panes.Item(pane_i).Dock().Hide();
+ {
+ wxAuiPaneInfo& p = m_panes.Item(pane_i);
+ if(p.IsDockable())
+ p.Dock();
+ p.Hide();
+ }
// clear out the dock array; this will be reconstructed
m_docks.Clear();
input.Replace(wxT("\\|"), wxT("\a"));
input.Replace(wxT("\\;"), wxT("\b"));
+ m_has_maximized = false;
while (1)
{
wxAuiPaneInfo pane;
LoadPaneInfo(pane_part, pane);
+ if ( pane.IsMaximized() )
+ m_has_maximized = true;
+
wxAuiPaneInfo& p = GetPane(pane.name);
if (!p.IsOk())
{
*/
}
+ // update whether the pane is resizable or not
+ long style = p.frame->GetWindowStyleFlag();
+ if (p.IsFixed())
+ style &= ~wxRESIZE_BORDER;
+ else
+ style |= wxRESIZE_BORDER;
+ p.frame->SetWindowStyleFlag(style);
+
+ if (p.frame->GetLabel() != p.caption)
+ p.frame->SetLabel(p.caption);
+
if (p.frame->IsShown() != p.IsShown())
p.frame->Show(p.IsShown());
}
}
if (allowed)
+ {
target = new_pos;
+ // Should this RTTI and function call be rewritten as
+ // sending a new event type to allow other window types
+ // to vary size based on dock location?
+ wxAuiToolBar* toolbar = wxDynamicCast(target.window, wxAuiToolBar);
+ if (toolbar)
+ {
+ wxSize hintSize = toolbar->GetHintSize(target.dock_direction);
+ if (target.best_size != hintSize)
+ {
+ target.best_size = hintSize;
+ target.floating_size = wxDefaultSize;
+ }
+ }
+ }
return allowed;
}
if (pt.x < layer_insert_offset &&
- pt.x > layer_insert_offset-auiLayerInsertPixels)
+ pt.x > layer_insert_offset-auiLayerInsertPixels &&
+ pt.y > 0 &&
+ pt.y < cli_size.y)
{
int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_LEFT),
GetMaxLayer(docks, wxAUI_DOCK_BOTTOM)),
return ProcessDockResult(target, drop);
}
else if (pt.y < layer_insert_offset &&
- pt.y > layer_insert_offset-auiLayerInsertPixels)
+ pt.y > layer_insert_offset-auiLayerInsertPixels &&
+ pt.x > 0 &&
+ pt.x < cli_size.x)
{
int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_TOP),
GetMaxLayer(docks, wxAUI_DOCK_LEFT)),
return ProcessDockResult(target, drop);
}
else if (pt.x >= cli_size.x - layer_insert_offset &&
- pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels)
+ pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels &&
+ pt.y > 0 &&
+ pt.y < cli_size.y)
{
int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_RIGHT),
GetMaxLayer(docks, wxAUI_DOCK_TOP)),
return ProcessDockResult(target, drop);
}
else if (pt.y >= cli_size.y - layer_insert_offset &&
- pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels)
+ pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels &&
+ pt.x > 0 &&
+ pt.x < cli_size.x)
{
int new_layer = wxMax( wxMax( GetMaxLayer(docks, wxAUI_DOCK_BOTTOM),
GetMaxLayer(docks, wxAUI_DOCK_LEFT)),
// toolbars may only be moved in and to fixed-pane docks,
// otherwise we will try to float the pane. Also, the pane
// should float if being dragged over center pane windows
- if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER)
+ if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER ||
+ pt.x >= cli_size.x || pt.x <= 0 || pt.y >= cli_size.y || pt.y <= 0)
{
if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y ))
{
}
else
{
- if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) &&
- (drop.IsFloatable() ||
- (part->dock->dock_direction != wxAUI_DOCK_CENTER &&
- part->dock->dock_direction != wxAUI_DOCK_NONE)))
+ if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && drop.IsFloatable())
{
- if (drop.IsFloatable())
- drop.Float();
+ drop.Float();
}
m_skipping = false;
if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax)
{
m_hint_fadetimer.Stop();
+ Disconnect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+ wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
return;
}
if (m_hint_fadeamt != m_hint_fademax) // Only fade if we need to
{
// start fade in timer
- m_hint_fadetimer.SetOwner(this, 101);
+ m_hint_fadetimer.SetOwner(this);
m_hint_fadetimer.Start(5);
+ Connect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+ wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
}
}
else // Not using a transparent hint window...
wxAuiPaneInfo& pane = m_panes.Item(i);
if (pane.IsFloating() &&
- pane.frame->IsShown())
+ pane.frame &&
+ pane.frame->IsShown())
{
wxRect rect = pane.frame->GetRect();
#ifdef __WXGTK__
m_hint_wnd->Show(false);
m_hint_wnd->SetTransparent(0);
m_hint_fadetimer.Stop();
+ // In case this is called while a hint fade is going, we need to
+ // disconnect the event handler.
+ Disconnect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+ wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
m_last_hint = wxRect();
return;
}
// Do nothing so this event isn't handled in the base handlers.
// Letting the hint window activate without this handler can lead to
- // weird behavior on Mac where the menu is switched out to the top
+ // weird behaviour on Mac where the menu is switched out to the top
// window's menu in MDI applications when it shouldn't be. So since
// we don't want user interaction with the hint window anyway, we just
// prevent it from activating here.
m_action_window = pane_window;
m_action_offset = offset;
m_frame->CaptureMouse();
+
+ if (pane.frame)
+ {
+ wxRect window_rect = pane.frame->GetRect();
+ wxRect client_rect = pane.frame->GetClientRect();
+ wxPoint client_pt = pane.frame->ClientToScreen(client_rect.GetTopLeft());
+ wxPoint origin_pt = client_pt - window_rect.GetTopLeft();
+ m_action_offset += origin_pt;
+ }
}
// CalculateHintRect() calculates the drop hint rectangle. The method
// first calls DoDrop() to determine the exact position the pane would
// be at were if dropped. If the pane would indeed become docked at the
-// specified drop point, the the rectangle hint will be returned in
+// specified drop point, the rectangle hint will be returned in
// screen coordinates. Otherwise, an empty rectangle is returned.
// |pane_window| is the window pointer of the pane being dragged, |pt| is
// the mouse position, in client coordinates. |offset| describes the offset
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ if(!pane.frame)
+ return;
+
if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
pane.frame->SetTransparent(150);
}
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ if(!pane.frame)
+ return;
+
wxPoint pt = ::wxGetMousePosition();
#if 0
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ if(!pane.frame)
+ return;
+
wxPoint pt = ::wxGetMousePosition();
#if 0
HideHint();
}
-void wxAuiManager::OnFloatingPaneResized(wxWindow* wnd, const wxSize& size)
+void wxAuiManager::OnFloatingPaneResized(wxWindow* wnd, const wxRect& rect)
{
// try to find the pane
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
- pane.floating_size = size;
+ pane.FloatingSize(rect.GetWidth(), rect.GetHeight());
+
+ // the top-left position may change as well as the size
+ pane.FloatingPosition(rect.x, rect.y);
}
// Render() fire a render event, which is normally handled by
// wxAuiManager::OnRender(). This allows the render function to
// be overridden via the render event. This can be useful for paintin
-// custom graphics in the main window. Default behavior can be
+// custom graphics in the main window. Default behaviour can be
// invoked in the overridden function by calling OnRender()
void wxAuiManager::Render(wxDC* dc)
// resize the dock or the pane
if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer)
{
+ // first, we must calculate the maximum size the dock may be
+ int sash_size = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
+
+ int used_width = 0, used_height = 0;
+
+ wxSize client_size = m_frame->GetClientSize();
+
+ size_t dock_i, dock_count = m_docks.GetCount();
+ for (dock_i = 0; dock_i < dock_count; ++dock_i)
+ {
+ wxAuiDockInfo& dock = m_docks.Item(dock_i);
+ if (dock.dock_direction == wxAUI_DOCK_TOP ||
+ dock.dock_direction == wxAUI_DOCK_BOTTOM)
+ {
+ used_height += dock.size;
+ }
+ if (dock.dock_direction == wxAUI_DOCK_LEFT ||
+ dock.dock_direction == wxAUI_DOCK_RIGHT)
+ {
+ used_width += dock.size;
+ }
+ if (dock.resizable)
+ used_width += sash_size;
+ }
+
+
+ int available_width = client_size.GetWidth() - used_width;
+ int available_height = client_size.GetHeight() - used_height;
+
+
+#if wxUSE_STATUSBAR
+ // if there's a status control, the available
+ // height decreases accordingly
+ if (m_frame && m_frame->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* frame = static_cast<wxFrame*>(m_frame);
+ wxStatusBar* status = frame->GetStatusBar();
+ if (status)
+ {
+ wxSize status_client_size = status->GetClientSize();
+ available_height -= status_client_size.GetHeight();
+ }
+ }
+#endif
+
wxRect& rect = m_action_part->dock->rect;
wxPoint new_pos(event.m_x - m_action_offset.x,
event.m_y - m_action_offset.y);
+ int new_size, old_size = m_action_part->dock->size;
switch (m_action_part->dock->dock_direction)
{
case wxAUI_DOCK_LEFT:
- m_action_part->dock->size = new_pos.x - rect.x;
+ new_size = new_pos.x - rect.x;
+ if (new_size-old_size > available_width)
+ new_size = old_size+available_width;
+ m_action_part->dock->size = new_size;
break;
case wxAUI_DOCK_TOP:
- m_action_part->dock->size = new_pos.y - rect.y;
+ new_size = new_pos.y - rect.y;
+ if (new_size-old_size > available_height)
+ new_size = old_size+available_height;
+ m_action_part->dock->size = new_size;
break;
case wxAUI_DOCK_RIGHT:
- m_action_part->dock->size = rect.x + rect.width -
- new_pos.x - m_action_part->rect.GetWidth();
+ new_size = rect.x + rect.width - new_pos.x -
+ m_action_part->rect.GetWidth();
+ if (new_size-old_size > available_width)
+ new_size = old_size+available_width;
+ m_action_part->dock->size = new_size;
break;
case wxAUI_DOCK_BOTTOM:
- m_action_part->dock->size = rect.y + rect.height -
+ new_size = rect.y + rect.height -
new_pos.y - m_action_part->rect.GetHeight();
+ if (new_size-old_size > available_height)
+ new_size = old_size+available_height;
+ m_action_part->dock->size = new_size;
break;
}
}
}
+ // new size can never be more than the number of dock pixels
+ if (new_pixsize > dock_pixels)
+ new_pixsize = dock_pixels;
+
+
// find a pane in our dock to 'steal' space from or to 'give'
// space to -- this is essentially what is done when a pane is
// resized; the pane should usually be the first non-fixed pane
int prop_diff = new_proportion - pane.dock_proportion;
// borrow the space from our neighbor pane to the
- // right or bottom (depending on orientation)
- dock.panes.Item(borrow_pane)->dock_proportion -= prop_diff;
+ // right or bottom (depending on orientation);
+ // also make sure we don't make the neighbor too small
+ int prop_borrow = dock.panes.Item(borrow_pane)->dock_proportion;
+
+ if (prop_borrow - prop_diff < 0)
+ {
+ // borrowing from other pane would make it too small,
+ // so cancel the resize operation
+ prop_borrow = min_proportion;
+ }
+ else
+ {
+ prop_borrow -= prop_diff;
+ }
+
+
+ dock.panes.Item(borrow_pane)->dock_proportion = prop_borrow;
pane.dock_proportion = new_proportion;
+
// repaint
Update();
Repaint(NULL);
wxScreenDC dc;
if (!m_action_hintrect.IsEmpty())
+ {
+ // remove old resize hint
DrawResizeHint(dc, m_action_hintrect);
- DrawResizeHint(dc, rect);
- m_action_hintrect = rect;
+ m_action_hintrect = wxRect();
+ }
+
+ // draw new resize hint, if it's inside the managed frame
+ wxRect frame_screen_rect = m_frame->GetScreenRect();
+ if (frame_screen_rect.Contains(rect))
+ {
+ DrawResizeHint(dc, rect);
+ m_action_hintrect = rect;
+ }
}
}
}
{
if (m_action_window)
{
+ // We can't move the child window so we need to get the frame that
+ // we want to be really moving. This is probably not the best place
+ // to do this but at least it fixes the bug (#13177) for now.
+ if (!m_action_window->IsKindOf(CLASSINFO(wxAuiFloatingFrame)))
+ {
+ wxAuiPaneInfo& pane = GetPane(m_action_window);
+ m_action_window = pane.frame;
+ }
+
wxPoint pt = m_frame->ClientToScreen(event.GetPosition());
m_action_window->Move(pt.x - m_action_offset.x,
pt.y - m_action_offset.y);