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;
+#ifdef __WXGTK__
+ m_CanSetShape = false; // have to wait for window create event on GTK
+#else
+ m_CanSetShape = true;
+#endif
+ SetTransparent(0);
+ }
+
+ virtual bool SetTransparent(wxByte alpha)
+ {
+ if (m_CanSetShape)
+ {
+ int w=100; // some defaults
+ int h=100;
+ GetClientSize(&w, &h);
+ if ((alpha != m_Amount) || (m_MaxWidth<w) | (m_MaxHeight<h))
+ {
+ // Make the region at least double the height and width so we don't have
+ // to rebuild if the size changes.
+ m_MaxWidth=w*2;
+ m_MaxHeight=h*2;
+ m_Amount = alpha;
+ m_Region.Clear();
+// m_Region.Union(0, 0, 1, m_MaxWidth);
+ if (m_Amount)
+ {
+ for (int y=0; y<m_MaxHeight; y++)
+ {
+ // Reverse the order of the bottom 4 bits
+ int j=((y&8)?1:0)|((y&4)?2:0)|((y&2)?4:0)|((y&1)?8:0);
+ if ((j*16+8)<m_Amount)
+ m_Region.Union(0, y, m_MaxWidth, 1);
+ }
+ }
+ SetShape(m_Region);
+ Refresh();
+ }
+ }
+ return true;
+ }
+
+ void OnPaint(wxPaintEvent& WXUNUSED(event))
+ {
+ wxPaintDC dc(this);
+
+ dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
+ dc.SetPen(*wxTRANSPARENT_PEN);
+
+ wxRegionIterator upd(GetUpdateRegion()); // get the update rect list
+
+ while (upd)
+ {
+ wxRect rect(upd.GetRect());
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+
+ upd++;
+ }
+ }
+
+#ifdef __WXGTK__
+ void OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event)) {m_CanSetShape=true; SetTransparent(0);}
+#endif
+
+private:
+ int m_Amount;
+ int m_MaxWidth;
+ int m_MaxHeight;
+ bool m_CanSetShape;
+
+ wxRegion m_Region;
+
+ DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
+ DECLARE_EVENT_TABLE()
+};
+
+
+IMPLEMENT_DYNAMIC_CLASS( wxPseudoTransparentFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame)
+ EVT_PAINT(wxPseudoTransparentFrame::OnPaint)
+#ifdef __WXGTK__
+ EVT_WINDOW_CREATE(wxPseudoTransparentFrame::OnWindowCreate)
+#endif
+END_EVENT_TABLE()
+
// -- static utility functions --
#endif
// Make a window to use for a transparent hint
-#if defined(__WXMSW__)
- m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1),
+#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 );
-
+
// Can't set the bg colour of a Frame in wxMac
wxPanel* p = new wxPanel(m_hint_wnd);
p->SetBackgroundColour(*wxBLUE);
#endif
- if (m_hint_wnd && !m_hint_wnd->CanSetTransparent())
+ 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;
+ }
}
{
if (!AddPane(window, pane_info))
return false;
-
+
wxPaneInfo& pane = GetPane(window);
-
+
DoDrop(m_docks, m_panes, pane, drop_pos, wxPoint(0,0));
-
+
return true;
}
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
continue;
}
}
-
+
m_panes.RemoveAt(i);
return true;
}
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
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();
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)
if (pane_part.empty())
break;
-
if (pane_part.Left(9) == wxT("dock_size"))
{
wxString val_name = pane_part.BeforeFirst(wxT('='));
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);
+ // 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.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(";"));
+ LoadPaneInfo(pane_part, pane);
wxPaneInfo& p = GetPane(pane.name);
if (!p.IsOk())
return false;
}
- pane.window = p.window;
- pane.frame = p.frame;
- pane.buttons = p.buttons;
- p = pane;
+ p.SafeSet(pane);
+
}
if (update)
return true;
}
-
void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock,
wxArrayInt& positions,
wxArrayInt& sizes)
this,
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->SetTransparent(150);
+#endif
frame->SetPaneWindow(p);
p.frame = frame;
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_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;
- wxByte 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;
if (! m_hint_wnd->IsShown())
m_hint_wnd->Show();
if (m_action == actionDragFloatingPane && m_action_window)
m_action_window->SetFocus();
- m_hint_wnd->SetTransparent(initial_fade);
+#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->SetSize(rect);
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 transparent hint window...
{
-
+
if (m_last_hint != rect)
{
// remove the last hint rectangle
}
}
+ // 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();
// hides a transparent window hint, if there is one
if (m_hint_wnd)
{
+ 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;
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->SetTransparent(150);
+#endif
}
void wxFrameManager::OnFloatingPaneMoving(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->SetTransparent(255);
+#endif
}
Update();
void wxFrameManager::OnRender(wxFrameManagerEvent& evt)
{
wxDC* dc = evt.GetDC();
-
+
#ifdef __WXMAC__
dc->Clear() ;
#endif
m_frame->Refresh();
}
}
-
+
event.Skip();
}