X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0603bb285cd5784b3ee92aaff47cc1a9ba0d0103..f5766910b6731eb03e82371416e9778203396ce7:/src/aui/framemanager.cpp?ds=sidebyside diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index b5cc99fa93..6822196ead 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -30,6 +30,7 @@ #include "wx/aui/floatpane.h" #ifndef WX_PRECOMP + #include "wx/panel.h" #include "wx/settings.h" #include "wx/app.h" #include "wx/dcclient.h" @@ -64,6 +65,135 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER) IMPLEMENT_DYNAMIC_CLASS(wxFrameManagerEvent, wxEvent) +class wxPseudoTransparentFrame : public wxFrame +{ +public: + wxPseudoTransparentFrame(wxWindow* parent = NULL, + wxWindowID id = wxID_ANY, + const wxString& title = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE, + const wxString &name = wxT("frame")) + : wxFrame(parent, id, title, pos, size, style | wxFRAME_SHAPED, name) + { + SetBackgroundStyle(wxBG_STYLE_CUSTOM); + m_Amount=0; + m_MaxWidth=0; + m_MaxHeight=0; + m_lastWidth=0; + m_lastHeight=0; +#ifdef __WXGTK__ + m_CanSetShape = false; // have to wait for window create event on GTK +#else + m_CanSetShape = true; +#endif + m_Region = wxRegion(0, 0, 0, 0); + SetTransparent(0); + } + + virtual bool SetTransparent(wxByte alpha) + { + if (m_CanSetShape) + { + int w=100; // some defaults + int h=100; + GetClientSize(&w, &h); + + m_MaxWidth = w; + m_MaxHeight = h; + m_Amount = alpha; + m_Region.Clear(); +// m_Region.Union(0, 0, 1, m_MaxWidth); + if (m_Amount) + { + for (int y=0; yrect.Inside(x,y)) + if (item->rect.Contains(x,y)) result = item; } @@ -495,24 +632,23 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame) } #endif - // Make a window to use for a translucent hint -#if defined(__WXMSW__) - m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1), + // Make a window to use for a transparent hint +#if defined(__WXMSW__) || defined(__WXGTK__) + m_hint_wnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(1,1), wxFRAME_TOOL_WINDOW | wxFRAME_FLOAT_ON_PARENT | wxFRAME_NO_TASKBAR | wxNO_BORDER); m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); - + #elif defined(__WXMAC__) // Using a miniframe with float and tool styles keeps the parent // frame activated and highlighted as such... - m_hint_wnd = new wxMiniFrame(m_frame, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1), + m_hint_wnd = new wxMiniFrame(m_frame, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(1,1), wxFRAME_FLOAT_ON_PARENT - | wxFRAME_TOOL_WINDOW - | wxCAPTION ); - + | wxFRAME_TOOL_WINDOW ); + // Can't set the bg colour of a Frame in wxMac wxPanel* p = new wxPanel(m_hint_wnd); @@ -523,11 +659,30 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame) p->SetBackgroundColour(*wxBLUE); #endif - if (m_hint_wnd && !m_hint_wnd->CanSetTranslucency()) + m_hint_fademax=50; + + if (m_hint_wnd + // CanSetTransparent is only present in the 2.7.0 ABI. To allow this file to be easily used + // in a backported environment, conditionally compile this in. +#if wxCHECK_VERSION(2,7,0) + && !m_hint_wnd->CanSetTransparent() +#endif + ) { + m_hint_wnd->Close(); + m_hint_wnd->Destroy(); m_hint_wnd = NULL; - } + + // If we can convert it to a PseudoTransparent window, do so + m_hint_wnd = new wxPseudoTransparentFrame (m_frame, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + + m_hint_fademax = 128; + } } @@ -675,11 +830,11 @@ bool wxFrameManager::AddPane(wxWindow* window, { if (!AddPane(window, pane_info)) return false; - + wxPaneInfo& pane = GetPane(window); - + DoDrop(m_docks, m_panes, pane, drop_pos, wxPoint(0,0)); - + return true; } @@ -756,7 +911,9 @@ bool wxFrameManager::DetachPane(wxWindow* window) // reduce flicker p.window->SetSize(1,1); - p.frame->Show(false); + + if (p.frame->IsShown()) + p.frame->Show(false); // reparent to m_frame and destroy the pane p.window->Reparent(m_frame); @@ -764,6 +921,24 @@ bool wxFrameManager::DetachPane(wxWindow* window) p.frame->Destroy(); p.frame = NULL; } + + // make sure there are no references to this pane in our uiparts, + // just in case the caller doesn't call Update() immediately after + // the DetachPane() call. This prevets obscure crashes which would + // happen at window repaint if the caller forgets to call Update() + int pi, part_count; + for (pi = 0, part_count = (int)m_uiparts.GetCount(); pi < part_count; ++pi) + { + wxDockUIPart& part = m_uiparts.Item(pi); + if (part.pane == &p) + { + m_uiparts.RemoveAt(pi); + part_count--; + pi--; + continue; + } + } + m_panes.RemoveAt(i); return true; } @@ -771,6 +946,40 @@ bool wxFrameManager::DetachPane(wxWindow* window) return false; } +// ClosePane() destroys or hides the pane depending on its +// flags +void wxFrameManager::ClosePane(wxPaneInfo& pane_info) +{ + // first, hide the window + if (pane_info.window && pane_info.window->IsShown()) { + pane_info.window->Show(false); + } + + // make sure that we are the parent of this window + if(pane_info.window && pane_info.window->GetParent() != m_frame) { + pane_info.window->Reparent(m_frame); + } + + // if we have a frame, destroy it + if(pane_info.frame) { + pane_info.frame->Destroy(); + pane_info.frame = NULL; + } + + // now we need to either destroy or hide the pane + if(pane_info.IsDestroyOnClose()) + { + wxWindow * window = pane_info.window; + DetachPane(window); + if(window) { + window->Destroy(); + } + } + else + { + pane_info.Hide(); + } +} // EscapeDelimiters() changes ";" into "\;" and "|" into "\|" // in the input string. This is an internal functions which is @@ -790,6 +999,112 @@ static wxString EscapeDelimiters(const wxString& s) return result; } +wxString wxFrameManager::SavePaneInfo(wxPaneInfo& pane) +{ + wxString result = wxT("name="); + result += EscapeDelimiters(pane.name); + result += wxT(";"); + + result += wxT("caption="); + result += EscapeDelimiters(pane.caption); + result += wxT(";"); + + result += wxString::Format(wxT("state=%u;"), pane.state); + result += wxString::Format(wxT("dir=%d;"), pane.dock_direction); + result += wxString::Format(wxT("layer=%d;"), pane.dock_layer); + result += wxString::Format(wxT("row=%d;"), pane.dock_row); + result += wxString::Format(wxT("pos=%d;"), pane.dock_pos); + result += wxString::Format(wxT("prop=%d;"), pane.dock_proportion); + result += wxString::Format(wxT("bestw=%d;"), pane.best_size.x); + result += wxString::Format(wxT("besth=%d;"), pane.best_size.y); + result += wxString::Format(wxT("minw=%d;"), pane.min_size.x); + result += wxString::Format(wxT("minh=%d;"), pane.min_size.y); + result += wxString::Format(wxT("maxw=%d;"), pane.max_size.x); + result += wxString::Format(wxT("maxh=%d;"), pane.max_size.y); + result += wxString::Format(wxT("floatx=%d;"), pane.floating_pos.x); + result += wxString::Format(wxT("floaty=%d;"), pane.floating_pos.y); + result += wxString::Format(wxT("floatw=%d;"), pane.floating_size.x); + result += wxString::Format(wxT("floath=%d"), pane.floating_size.y); + + return result; +} + +// Load a "pane" with the pane infor settings in pane_part +void wxFrameManager::LoadPaneInfo(wxString pane_part, wxPaneInfo &pane) +{ + // replace escaped characters so we can + // split up the string easily + pane_part.Replace(wxT("\\|"), wxT("\a")); + pane_part.Replace(wxT("\\;"), wxT("\b")); + + while(1) + { + wxString val_part = pane_part.BeforeFirst(wxT(';')); + pane_part = pane_part.AfterFirst(wxT(';')); + wxString val_name = val_part.BeforeFirst(wxT('=')); + wxString value = val_part.AfterFirst(wxT('=')); + val_name.MakeLower(); + val_name.Trim(true); + val_name.Trim(false); + value.Trim(true); + value.Trim(false); + + if (val_name.empty()) + break; + + if (val_name == wxT("name")) + pane.name = value; + else if (val_name == wxT("caption")) + pane.caption = value; + else if (val_name == wxT("state")) + pane.state = (unsigned int)wxAtoi(value.c_str()); + else if (val_name == wxT("dir")) + pane.dock_direction = wxAtoi(value.c_str()); + else if (val_name == wxT("layer")) + pane.dock_layer = wxAtoi(value.c_str()); + else if (val_name == wxT("row")) + pane.dock_row = wxAtoi(value.c_str()); + else if (val_name == wxT("pos")) + pane.dock_pos = wxAtoi(value.c_str()); + else if (val_name == wxT("prop")) + pane.dock_proportion = wxAtoi(value.c_str()); + else if (val_name == wxT("bestw")) + pane.best_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("besth")) + pane.best_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("minw")) + pane.min_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("minh")) + pane.min_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("maxw")) + pane.max_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("maxh")) + pane.max_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("floatx")) + pane.floating_pos.x = wxAtoi(value.c_str()); + else if (val_name == wxT("floaty")) + pane.floating_pos.y = wxAtoi(value.c_str()); + else if (val_name == wxT("floatw")) + pane.floating_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("floath")) + pane.floating_size.y = wxAtoi(value.c_str()); + else { + wxFAIL_MSG(wxT("Bad Perspective String")); + } + } + + // replace escaped characters so we can + // split up the string easily + pane.name.Replace(wxT("\a"), wxT("|")); + pane.name.Replace(wxT("\b"), wxT(";")); + pane.caption.Replace(wxT("\a"), wxT("|")); + pane.caption.Replace(wxT("\b"), wxT(";")); + pane_part.Replace(wxT("\a"), wxT("|")); + pane_part.Replace(wxT("\b"), wxT(";")); + + return; +} + // SavePerspective() saves all pane information as a single string. // This string may later be fed into LoadPerspective() to restore @@ -806,32 +1121,7 @@ wxString wxFrameManager::SavePerspective() for (pane_i = 0; pane_i < pane_count; ++pane_i) { wxPaneInfo& pane = m_panes.Item(pane_i); - - result += wxT("name="); - result += EscapeDelimiters(pane.name); - result += wxT(";"); - - result += wxT("caption="); - result += EscapeDelimiters(pane.caption); - result += wxT(";"); - - result += wxString::Format(wxT("state=%u;"), pane.state); - result += wxString::Format(wxT("dir=%d;"), pane.dock_direction); - result += wxString::Format(wxT("layer=%d;"), pane.dock_layer); - result += wxString::Format(wxT("row=%d;"), pane.dock_row); - result += wxString::Format(wxT("pos=%d;"), pane.dock_pos); - result += wxString::Format(wxT("prop=%d;"), pane.dock_proportion); - result += wxString::Format(wxT("bestw=%d;"), pane.best_size.x); - result += wxString::Format(wxT("besth=%d;"), pane.best_size.y); - result += wxString::Format(wxT("minw=%d;"), pane.min_size.x); - result += wxString::Format(wxT("minh=%d;"), pane.min_size.y); - result += wxString::Format(wxT("maxw=%d;"), pane.max_size.x); - result += wxString::Format(wxT("maxh=%d;"), pane.max_size.y); - result += wxString::Format(wxT("floatx=%d;"), pane.floating_pos.x); - result += wxString::Format(wxT("floaty=%d;"), pane.floating_pos.y); - result += wxString::Format(wxT("floatw=%d;"), pane.floating_size.x); - result += wxString::Format(wxT("floath=%d"), pane.floating_size.y); - result += wxT("|"); + result += SavePaneInfo(pane)+wxT("|"); } int dock_i, dock_count = m_docks.GetCount(); @@ -863,7 +1153,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) if (part != wxT("layout1")) return false; - // mark all panes currently managed as docked and hidden int pane_i, pane_count = m_panes.GetCount(); for (pane_i = 0; pane_i < pane_count; ++pane_i) @@ -889,7 +1178,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) if (pane_part.empty()) break; - if (pane_part.Left(9) == wxT("dock_size")) { wxString val_name = pane_part.BeforeFirst(wxT('=')); @@ -913,68 +1201,12 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) continue; } - while (1) - { - wxString val_part = pane_part.BeforeFirst(wxT(';')); - pane_part = pane_part.AfterFirst(wxT(';')); - wxString val_name = val_part.BeforeFirst(wxT('=')); - wxString value = val_part.AfterFirst(wxT('=')); - val_name.MakeLower(); - val_name.Trim(true); - val_name.Trim(false); - value.Trim(true); - value.Trim(false); - - if (val_name.empty()) - break; + // Undo our escaping as LoadPaneInfo needs to take an unescaped + // name so it can be called by external callers + pane_part.Replace(wxT("\a"), wxT("|")); + pane_part.Replace(wxT("\b"), wxT(";")); - if (val_name == wxT("name")) - pane.name = value; - else if (val_name == wxT("caption")) - pane.caption = value; - else if (val_name == wxT("state")) - pane.state = (unsigned int)wxAtoi(value.c_str()); - else if (val_name == wxT("dir")) - pane.dock_direction = wxAtoi(value.c_str()); - else if (val_name == wxT("layer")) - pane.dock_layer = wxAtoi(value.c_str()); - else if (val_name == wxT("row")) - pane.dock_row = wxAtoi(value.c_str()); - else if (val_name == wxT("pos")) - pane.dock_pos = wxAtoi(value.c_str()); - else if (val_name == wxT("prop")) - pane.dock_proportion = wxAtoi(value.c_str()); - else if (val_name == wxT("bestw")) - pane.best_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("besth")) - pane.best_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("minw")) - pane.min_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("minh")) - pane.min_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("maxw")) - pane.max_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("maxh")) - pane.max_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("floatx")) - pane.floating_pos.x = wxAtoi(value.c_str()); - else if (val_name == wxT("floaty")) - pane.floating_pos.y = wxAtoi(value.c_str()); - else if (val_name == wxT("floatw")) - pane.floating_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("floath")) - pane.floating_size.y = wxAtoi(value.c_str()); - else { - wxFAIL_MSG(wxT("Bad Perspective String")); - } - } - - // replace escaped characters so we can - // split up the string easily - pane.name.Replace(wxT("\a"), wxT("|")); - pane.name.Replace(wxT("\b"), wxT(";")); - pane.caption.Replace(wxT("\a"), wxT("|")); - pane.caption.Replace(wxT("\b"), wxT(";")); + LoadPaneInfo(pane_part, pane); wxPaneInfo& p = GetPane(pane.name); if (!p.IsOk()) @@ -984,10 +1216,8 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) return false; } - pane.window = p.window; - pane.frame = p.frame; - pane.buttons = p.buttons; - p = pane; + p.SafeSet(pane); + } if (update) @@ -996,7 +1226,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) return true; } - void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, wxArrayInt& positions, wxArrayInt& sizes) @@ -1787,7 +2016,9 @@ void wxFrameManager::Update() // reduce flicker p.window->SetSize(1,1); - p.frame->Show(false); + + if (p.frame->IsShown()) + p.frame->Show(false); // reparent to m_frame and destroy the pane p.window->Reparent(m_frame); @@ -1813,24 +2044,22 @@ void wxFrameManager::Update() { // we need to create a frame for this // pane, which has recently been floated - wxFloatingPane* frame = new wxFloatingPane(m_frame, - this, - p); + wxFloatingPane* frame = CreateFloatingFrame(m_frame, p); +#if wxCHECK_VERSION(2,7,0) // on MSW and Mac, if the owner desires transparent dragging, and // the dragging is happening right now, then the floating // window should have this style by default if (m_action == actionDragFloatingPane && (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)) - frame->SetTranslucency(150); + frame->SetTransparent(150); +#endif frame->SetPaneWindow(p); p.frame = frame; - if (p.IsShown()) - { + if (p.IsShown() && !frame->IsShown()) frame->Show(); - } } else { @@ -1844,12 +2073,14 @@ void wxFrameManager::Update() //p.frame->Move(p.floating_pos.x, p.floating_pos.y); } - p.frame->Show(p.IsShown()); + if (p.frame->IsShown() != p.IsShown()) + p.frame->Show(p.IsShown()); } } else { - p.window->Show(p.IsShown()); + if (p.window->IsShown() != p.IsShown()) + p.window->Show(p.IsShown()); } // if "active panes" are no longer allowed, clear @@ -2121,11 +2352,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, if (pt.x < layer_insert_offset && pt.x > layer_insert_offset-auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_LEFT), - GetMaxLayer(docks, wxAUI_DOCK_BOTTOM)), - GetMaxLayer(docks, wxAUI_DOCK_TOP)) + 1; drop.Dock().Left(). - Layer(new_layer). Row(0). Position(pt.y - GetDockPixelOffset(drop) - offset.y); return ProcessDockResult(target, drop); @@ -2133,11 +2360,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, else if (pt.y < layer_insert_offset && pt.y > layer_insert_offset-auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_TOP), - GetMaxLayer(docks, wxAUI_DOCK_LEFT)), - GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; drop.Dock().Top(). - Layer(new_layer). Row(0). Position(pt.x - GetDockPixelOffset(drop) - offset.x); return ProcessDockResult(target, drop); @@ -2145,11 +2368,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, else if (pt.x >= cli_size.x - layer_insert_offset && pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_RIGHT), - GetMaxLayer(docks, wxAUI_DOCK_TOP)), - GetMaxLayer(docks, wxAUI_DOCK_BOTTOM)) + 1; drop.Dock().Right(). - Layer(new_layer). Row(0). Position(pt.y - GetDockPixelOffset(drop) - offset.y); return ProcessDockResult(target, drop); @@ -2157,9 +2376,10 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, else if (pt.y >= cli_size.y - layer_insert_offset && pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_BOTTOM), - GetMaxLayer(docks, wxAUI_DOCK_LEFT)), - GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; + int new_layer = wxMax( wxMax( GetMaxLayer(docks, wxAUI_DOCK_BOTTOM), + GetMaxLayer(docks, wxAUI_DOCK_LEFT)), + GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; + drop.Dock().Bottom(). Layer(new_layer). Row(0). @@ -2167,7 +2387,6 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, return ProcessDockResult(target, drop); } - wxDockUIPart* part = HitTest(pt.x, pt.y); @@ -2176,7 +2395,6 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, if (!part || !part->dock) return false; - // calculate the offset from where the dock begins // to the point where the user dropped the pane int dock_drop_offset = 0; @@ -2191,16 +2409,39 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, // should float if being dragged over center pane windows if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER) { - if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && + if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y )) + { + m_skipping = true; + } + else + { + if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && (drop.IsFloatable() || (part->dock->dock_direction != wxAUI_DOCK_CENTER && part->dock->dock_direction != wxAUI_DOCK_NONE))) - { - drop.Float(); + { + drop.Float(); + } + + m_skipping = false; + + return ProcessDockResult(target, drop); } + drop.Position(pt.x - GetDockPixelOffset(drop) - offset.x); + return ProcessDockResult(target, drop); } + else + { + m_skipping = false; + } + + if (!m_skipping) + { + m_last_rect = part->dock->rect; + m_last_rect.Inflate( 15, 15 ); + } drop.Dock(). Direction(part->dock->dock_direction). @@ -2209,15 +2450,26 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, Position(dock_drop_offset); if (( - ((pt.y < part->dock->rect.y + 2) && part->dock->IsHorizontal()) || - ((pt.x < part->dock->rect.x + 2) && part->dock->IsVertical()) + ((pt.y < part->dock->rect.y + 1) && part->dock->IsHorizontal()) || + ((pt.x < part->dock->rect.x + 1) && part->dock->IsVertical()) ) && part->dock->panes.GetCount() > 1) { - int row = drop.dock_row; - DoInsertDockRow(panes, part->dock->dock_direction, - part->dock->dock_layer, - part->dock->dock_row); - drop.dock_row = row; + if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || + (part->dock->dock_direction == wxAUI_DOCK_LEFT)) + { + int row = drop.dock_row; + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row); + drop.dock_row = row; + } + else + { + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row+1); + drop.dock_row = part->dock->dock_row+1; + } } if (( @@ -2225,10 +2477,22 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, ((pt.x > part->dock->rect.x + part->dock->rect.width - 2 ) && part->dock->IsVertical()) ) && part->dock->panes.GetCount() > 1) { - DoInsertDockRow(panes, part->dock->dock_direction, - part->dock->dock_layer, - part->dock->dock_row+1); - drop.dock_row = part->dock->dock_row+1; + if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || + (part->dock->dock_direction == wxAUI_DOCK_LEFT)) + { + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row+1); + drop.dock_row = part->dock->dock_row+1; + } + else + { + int row = drop.dock_row; + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row); + drop.dock_row = row; + } } return ProcessDockResult(target, drop); @@ -2443,27 +2707,42 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) { - if (!m_hint_wnd || m_hint_fadeamt >= 50) + if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax) { m_hint_fadetimer.Stop(); return; } - m_hint_fadeamt += 5; - m_hint_wnd->SetTranslucency(m_hint_fadeamt); + m_hint_fadeamt += 4; +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(m_hint_fadeamt); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(m_hint_fadeamt); +#endif } void wxFrameManager::ShowHint(const wxRect& rect) { - if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 && m_hint_wnd) + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 + && m_hint_wnd + // Finally, don't use a venetian blind effect if it's been specifically disabled + && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) && + (m_flags & wxAUI_MGR_DISABLE_VENETIAN_BLINDS)) + ) { if (m_last_hint == rect) return; m_last_hint = rect; - int initial_fade = 50; - if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) - initial_fade = 0; + m_hint_fadeamt = m_hint_fademax; + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) + && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) && + (m_flags & wxAUI_MGR_DISABLE_VENETIAN_BLINDS_FADE)) + ) + m_hint_fadeamt = 0; + + m_hint_wnd->SetSize(rect); if (! m_hint_wnd->IsShown()) m_hint_wnd->Show(); @@ -2473,23 +2752,26 @@ void wxFrameManager::ShowHint(const wxRect& rect) if (m_action == actionDragFloatingPane && m_action_window) m_action_window->SetFocus(); - m_hint_wnd->SetTranslucency(initial_fade); - m_hint_wnd->SetSize(rect); +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(m_hint_fadeamt); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(m_hint_fadeamt); +#endif m_hint_wnd->Raise(); - - if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) + + if (m_hint_fadeamt != m_hint_fademax) // Only fade if we need to { // start fade in timer - m_hint_fadeamt = 0; m_hint_fadetimer.SetOwner(this, 101); m_hint_fadetimer.Start(5); } } - else // Not using a translucent hint window... + else // Not using a transparent hint window... { - + if (m_last_hint != rect) { // remove the last hint rectangle @@ -2522,6 +2804,11 @@ void wxFrameManager::ShowHint(const wxRect& rect) } } + // As we can only hide the hint by redrawing the managed window, we + // need to clip the region to the managed window too or we get + // nasty redrawn problems. + clip.Intersect(m_frame->GetRect()); + screendc.SetClippingRegion(clip); wxBitmap stipple = wxPaneCreateStippleBitmap(); @@ -2541,7 +2828,14 @@ void wxFrameManager::HideHint() // hides a transparent window hint, if there is one if (m_hint_wnd) { - m_hint_wnd->SetTranslucency(0); + if (m_hint_wnd->IsShown()) + m_hint_wnd->Show(false); +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(0); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(0); +#endif m_hint_fadetimer.Stop(); m_last_hint = wxRect(); return; @@ -2647,17 +2941,56 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd) wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); +#if wxCHECK_VERSION(2,7,0) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) - pane.frame->SetTranslucency(150); + pane.frame->SetTransparent(150); +#endif } -void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) +void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir) { // try to find the pane wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); wxPoint pt = ::wxGetMousePosition(); + +#if 0 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 5; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#else + wxUnusedVar(dir); +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); // calculate the offset from the upper left-hand corner @@ -2717,13 +3050,50 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) m_frame->Update(); } -void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) +void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir) { // try to find the pane wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); wxPoint pt = ::wxGetMousePosition(); + +#if 0 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 10; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#else + wxUnusedVar(dir); +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); // calculate the offset from the upper left-hand corner @@ -2739,15 +3109,17 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) // do the drop calculation DoDrop(m_docks, m_panes, pane, client_pt, action_offset); } - + // if the pane is still floating, update it's floating // position (that we store) if (pane.IsFloating()) { pane.floating_pos = pane.frame->GetPosition(); +#if wxCHECK_VERSION(2,7,0) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) - pane.frame->SetTranslucency(255); + pane.frame->SetTransparent(255); +#endif } Update(); @@ -2783,14 +3155,9 @@ void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) evt.Veto(); return; } - else + else { - // reparent the pane window back to us and - // prepare the frame window for destruction - pane.window->Show(false); - pane.window->Reparent(m_frame); - pane.frame = NULL; - pane.Hide(); + ClosePane(pane); } } @@ -2815,7 +3182,7 @@ void wxFrameManager::OnFloatingPaneActivated(wxWindow* wnd) void wxFrameManager::OnRender(wxFrameManagerEvent& evt) { wxDC* dc = evt.GetDC(); - + #ifdef __WXMAC__ dc->Clear() ; #endif @@ -2833,22 +3200,22 @@ void wxFrameManager::OnRender(wxFrameManagerEvent& evt) { case wxDockUIPart::typeDockSizer: case wxDockUIPart::typePaneSizer: - m_art->DrawSash(*dc, part.orientation, part.rect); + m_art->DrawSash(*dc, m_frame, part.orientation, part.rect); break; case wxDockUIPart::typeBackground: - m_art->DrawBackground(*dc, part.orientation, part.rect); + m_art->DrawBackground(*dc, m_frame, part.orientation, part.rect); break; case wxDockUIPart::typeCaption: - m_art->DrawCaption(*dc, part.pane->caption, part.rect, *part.pane); + m_art->DrawCaption(*dc, m_frame, part.pane->caption, part.rect, *part.pane); break; case wxDockUIPart::typeGripper: - m_art->DrawGripper(*dc, part.rect, *part.pane); + m_art->DrawGripper(*dc, m_frame, part.rect, *part.pane); break; case wxDockUIPart::typePaneBorder: - m_art->DrawBorder(*dc, part.rect, *part.pane); + m_art->DrawBorder(*dc, m_frame, part.rect, *part.pane); break; case wxDockUIPart::typePaneButton: - m_art->DrawPaneButton(*dc, part.button->button_id, + m_art->DrawPaneButton(*dc, m_frame, part.button->button_id, wxAUI_BUTTON_STATE_NORMAL, part.rect, *part.pane); break; } @@ -2921,13 +3288,14 @@ void wxFrameManager::OnEraseBackground(wxEraseEvent& event) #endif } -void wxFrameManager::OnSize(wxSizeEvent& WXUNUSED(event)) +void wxFrameManager::OnSize(wxSizeEvent& event) { if (m_frame) { DoFrameLayout(); Repaint(); } + event.Skip(); } @@ -2998,7 +3366,7 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, if (pt.x != 0 || pt.y != 0) cdc.SetDeviceOrigin(pt.x, pt.y); - m_art->DrawPaneButton(cdc, + m_art->DrawPaneButton(cdc, m_frame, button_ui_part->button->button_id, state, button_ui_part->rect, @@ -3502,6 +3870,8 @@ void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) m_frame->Refresh(); } } + + event.Skip(); } @@ -3522,7 +3892,7 @@ void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) if (!e.GetVeto()) { - pane.Hide(); + ClosePane(pane); Update(); } }