#include "wx/dcscreen.h"
#include "wx/toolbar.h"
#include "wx/mdi.h"
+ #include "wx/image.h"
#endif
-//#include "wx/dcbuffer.h"
-
-#include "wx/image.h"
-
WX_CHECK_BUILD_OPTIONS("wxAUI")
#include "wx/arrimpl.cpp"
wxPaneInfo wxNullPaneInfo;
wxDockInfo wxNullDockInfo;
DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANECLOSE)
+DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER)
#ifdef __WXMAC__
// a few defines to avoid nameclashes
#include "wx/mac/private.h"
#endif
+IMPLEMENT_DYNAMIC_CLASS(wxFrameManagerEvent, wxEvent)
+
// -- static utility functions --
dc.DrawRectangle(rect);
}
-#ifdef __WXMSW__
-// on supported windows systems (Win2000 and greater), this function
+// on supported windows systems (Win2000 and greater, Mac), this function
// will make a frame window transparent by a certain amount
static void MakeWindowTransparent(wxWindow* wnd, int amount)
{
+#if defined(__WXMSW__)
// this API call is not in all SDKs, only the newer ones, so
// we will runtime bind this
typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
if (!pSetLayeredWindowAttributes)
{
pSetLayeredWindowAttributes =
- (PSETLAYEREDWINDOWATTR)GetProcAddress(h,"SetLayeredWindowAttributes");
+ (PSETLAYEREDWINDOWATTR)GetProcAddress(h,
+#ifdef __WXWINCE__
+ wxT("SetLayeredWindowAttributes")
+#else
+ "SetLayeredWindowAttributes"
+#endif
+ );
}
if (pSetLayeredWindowAttributes == NULL)
SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | 0x80000 /*WS_EX_LAYERED*/);
pSetLayeredWindowAttributes(hwnd, 0, (BYTE)amount, 2 /*LWA_ALPHA*/);
-}
+#elif defined(__WXMAC__)
+
+ WindowRef handle = GetControlOwner((OpaqueControlRef*)wnd->GetHandle());
+ SetWindowAlpha(handle, float(amount)/ 255.0);
+
+#else
+ wxUnusedVar(wnd);
+ wxUnusedVar(amount);
#endif
+}
+
// CopyDocksAndPanes() - this utility function creates copies of
}
-
+// SetActivePane() sets the active pane, as well as cycles through
+// every other pane and makes sure that all others' active flags
+// are turned off
static void SetActivePane(wxPaneInfoArray& panes, wxWindow* active_pane)
{
int i, pane_count;
BEGIN_EVENT_TABLE(wxFrameManager, wxEvtHandler)
EVT_AUI_PANEBUTTON(wxFrameManager::OnPaneButton)
+ EVT_AUI_RENDER(wxFrameManager::OnRender)
EVT_PAINT(wxFrameManager::OnPaint)
EVT_ERASE_BACKGROUND(wxFrameManager::OnEraseBackground)
EVT_SIZE(wxFrameManager::OnSize)
END_EVENT_TABLE()
-wxFrameManager::wxFrameManager(wxFrame* frame, unsigned int flags)
+wxFrameManager::wxFrameManager(wxWindow* managed_wnd, unsigned int flags)
{
m_action = actionNone;
m_last_mouse_move = wxPoint();
m_hint_wnd = NULL;
m_flags = flags;
- if (frame)
+ if (managed_wnd)
{
- SetFrame(frame);
+ SetManagedWindow(managed_wnd);
}
}
}
-// SetFrame() is usually called once when the frame
+// don't use these anymore as they are deprecated
+// use Set/GetManagedFrame() instead
+void wxFrameManager::SetFrame(wxFrame* frame)
+{
+ SetManagedWindow((wxWindow*)frame);
+}
+
+wxFrame* wxFrameManager::GetFrame() const
+{
+ return (wxFrame*)m_frame;
+}
+
+
+
+
+// SetManagedWindow() is usually called once when the frame
// manager class is being initialized. "frame" specifies
// the frame which should be managed by the frame mananger
-void wxFrameManager::SetFrame(wxFrame* frame)
+void wxFrameManager::SetManagedWindow(wxWindow* frame)
{
wxASSERT_MSG(frame, wxT("specified frame must be non-NULL"));
m_frame->RemoveEventHandler(this);
}
-// GetFrame() returns the frame pointer being managed by wxFrameManager
-wxFrame* wxFrameManager::GetFrame() const
+// GetManagedWindow() returns the window pointer being managed
+wxWindow* wxFrameManager::GetManagedWindow() const
{
return m_frame;
}
// SetArtProvider() instructs wxFrameManager to use the
// specified art provider for all drawing calls. This allows
-// plugable look-and-feel features
+// plugable look-and-feel features. The pointer that is
+// passed to this method subsequently belongs to wxFrameManager,
+// and is deleted in the frame manager destructor
void wxFrameManager::SetArtProvider(wxDockArt* art_provider)
{
// delete the last art provider, if any
m_art = art_provider;
}
+
bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info)
{
// check if the pane has a valid window
pinfo.name.Printf(wxT("%08lx%08x%08x%08lx"),
((unsigned long)pinfo.window) & 0xffffffff,
(unsigned int)time(NULL),
+#ifdef __WXWINCE__
+ (unsigned int)GetTickCount(),
+#else
(unsigned int)clock(),
+#endif
(unsigned long)m_panes.GetCount());
}
{
return AddPane(window, pane_info);
}
- else
+ else
{
if (pane_info.IsFloating())
{
}
+// DetachPane() removes a pane from the frame manager. This
+// method will not destroy the window that is removed.
bool wxFrameManager::DetachPane(wxWindow* window)
{
int i, count;
{
sizer_item = vert_pane_sizer->Add(1, 1, 1, wxEXPAND);
}
- else
+ else
{
sizer_item = vert_pane_sizer->Add(pane.window, 1, wxEXPAND);
+ // Don't do this because it breaks the pane size in floating windows
+ // BIW: Right now commenting this out is causing problems with
+ // an mdi client window as the center pane.
vert_pane_sizer->SetItemMinSize(pane.window, 1, 1);
}
part.sizer_item = sizer_item;
uiparts.Add(part);
}
- else
+ else
{
sizer_item = cont->Add(horz_pane_sizer, pane_proportion, wxEXPAND);
}
part.sizer_item = sizer_item;
uiparts.Add(part);
}
- else
+ else
{
for (pane_i = 0; pane_i < pane_count; ++pane_i)
{
// we need to create a frame for this
// pane, which has recently been floated
wxFloatingPane* frame = new wxFloatingPane(m_frame,
- this, -1,
- p.floating_pos,
- p.floating_size);
+ this,
+ p);
- // on MSW, if the owner desires transparent dragging, and
+ // 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
-#ifdef __WXMSW__
if (m_action == actionDragFloatingPane &&
(m_flags & wxAUI_MGR_TRANSPARENT_DRAG))
MakeWindowTransparent(frame, 150);
-#endif
frame->SetPaneWindow(p);
p.frame = frame;
if (p.frame->GetPosition() != p.floating_pos)
{
p.frame->SetSize(p.floating_pos.x, p.floating_pos.y,
- -1, -1, wxSIZE_USE_EXISTING);
+ wxDefaultCoord, wxDefaultCoord,
+ wxSIZE_USE_EXISTING);
//p.frame->Move(p.floating_pos.x, p.floating_pos.y);
}
// if a dock operation is allowed, the new dock position is copied into
// the target info. If the operation was allowed, the function returns true.
-static bool ProcessDockResult(wxPaneInfo& target,
+bool wxFrameManager::ProcessDockResult(wxPaneInfo& target,
const wxPaneInfo& new_pos)
{
bool allowed = false;
Position(pt.y - GetDockPixelOffset(drop) - offset.y);
return ProcessDockResult(target, drop);
}
- else if (pt.y < layer_insert_offset &&
- pt.y > layer_insert_offset-auiLayerInsertPixels)
+ 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)),
Position(pt.x - GetDockPixelOffset(drop) - offset.x);
return ProcessDockResult(target, drop);
}
- else if (pt.x >= cli_size.x - layer_insert_offset &&
- pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels)
+ 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)),
Position(pt.y - GetDockPixelOffset(drop) - offset.y);
return ProcessDockResult(target, drop);
}
- else if (pt.y >= cli_size.y - layer_insert_offset &&
- pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels)
+ 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)),
void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
{
-#ifdef __WXMSW__
if (!m_hint_wnd || m_hint_fadeamt >= 50)
{
m_hint_fadetimer.Stop();
m_hint_fadeamt += 5;
MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt);
-#endif
}
void wxFrameManager::ShowHint(const wxRect& rect)
{
-#ifdef __WXMSW__
-
+#if defined(__WXMSW__) || defined(__WXMAC__)
// First, determine if the operating system can handle transparency.
// Transparency is available on Win2000 and above
// If the transparent flag is set, and the OS supports it,
// go ahead and use a transparent hint
- if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 &&
- os_type == wxWINDOWS_NT && ver_major >= 5)
+ if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0
+#ifdef __WXMSW__
+ && os_type == wxWINDOWS_NT && ver_major >= 5
+#endif
+ )
{
if (m_last_hint == rect)
return;
{
wxPoint pt = rect.GetPosition();
wxSize size = rect.GetSize();
+#if defined(__WXMSW__)
m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, pt, size,
wxFRAME_TOOL_WINDOW |
wxFRAME_FLOAT_ON_PARENT |
MakeWindowTransparent(m_hint_wnd, initial_fade);
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, pt, size,
+ 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);
+
+ // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver
+ // color that is really hard to see, especially transparent.
+ // Until a better system color is decided upon we'll just use
+ // blue.
+ p->SetBackgroundColour(*wxBLUE);
+#endif
m_hint_wnd->Show();
// if we are dragging a floating pane, set the focus
m_action_window->SetFocus();
}
- else
+ else
{
- wxPoint pt = rect.GetPosition();
- wxSize size = rect.GetSize();
MakeWindowTransparent(m_hint_wnd, initial_fade);
- m_hint_wnd->SetSize(pt.x, pt.y, rect.width, rect.height);
+ m_hint_wnd->SetSize(rect);
+ m_hint_wnd->Raise();
}
if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
return;
}
#endif
-
+
if (m_last_hint != rect)
{
// remove the last hint rectangle
void wxFrameManager::HideHint()
{
- // hides a transparent window hint (currently wxMSW only)
-#ifdef __WXMSW__
+ // hides a transparent window hint, if there is one
if (m_hint_wnd)
{
MakeWindowTransparent(m_hint_wnd, 0);
m_last_hint = wxRect();
return;
}
-#endif
// hides a painted hint by redrawing the frame window
if (!m_last_hint.IsEmpty())
wxDockUIPartArray uiparts;
wxPaneInfo hint = GetPane(pane_window);
hint.name = wxT("__HINT__");
+ hint.Show();
if (!hint.IsOk())
return;
wxPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
-#ifdef __WXMSW__
if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
MakeWindowTransparent(pane.frame, 150);
-#endif
}
void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd)
{
pane.floating_pos = pane.frame->GetPosition();
- #ifdef __WXMSW__
if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
MakeWindowTransparent(pane.frame, 255);
- #endif
}
Update();
pane.floating_size = size;
}
-void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd)
+
+void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt)
{
// try to find the pane
wxPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
- // 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();
+
+ // fire pane close event
+ wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE);
+ e.SetPane(&pane);
+ e.SetCanVeto(evt.CanVeto());
+ ProcessMgrEvent(e);
+
+ if (e.GetVeto())
+ {
+ evt.Veto();
+ return;
+ }
+ 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();
+ }
}
+
+
void wxFrameManager::OnFloatingPaneActivated(wxWindow* wnd)
{
if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE)
{
// try to find the pane
- wxPaneInfo& pane = GetPane(wnd);
- wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ wxASSERT_MSG(GetPane(wnd).IsOk(), wxT("Pane window not found"));
SetActivePane(m_panes, wnd);
Repaint();
}
}
-// Render() draws all of the pane captions, sashes,
+// OnRender() draws all of the pane captions, sashes,
// backgrounds, captions, grippers, pane borders and buttons.
// It renders the entire user interface.
-void wxFrameManager::Render(wxDC* dc)
+void wxFrameManager::OnRender(wxFrameManagerEvent& evt)
{
+ wxDC* dc = evt.GetDC();
+
#ifdef __WXMAC__
dc->Clear() ;
#endif
}
}
+
+// Render() fire a render event, which is normally handled by
+// wxFrameManager::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
+// invoked in the overridden function by calling OnRender()
+
+void wxFrameManager::Render(wxDC* dc)
+{
+ wxFrameManagerEvent e(wxEVT_AUI_RENDER);
+ e.SetDC(dc);
+ ProcessMgrEvent(e);
+}
+
void wxFrameManager::Repaint(wxDC* dc)
{
#ifdef __WXMAC__
else
state = wxAUI_BUTTON_STATE_HOVER;
}
- else
+ else
{
if (event.LeftDown())
state = wxAUI_BUTTON_STATE_HOVER;
Repaint(NULL);
}
}
- else if (m_action == actionClickButton)
+ else if (m_action == actionClickButton)
{
m_hover_button = NULL;
m_frame->ReleaseMouse();
ProcessMgrEvent(e);
}
}
- else if (m_action == actionClickCaption)
+ else if (m_action == actionClickCaption)
{
m_frame->ReleaseMouse();
}
- else if (m_action == actionDragFloatingPane)
+ else if (m_action == actionDragFloatingPane)
{
m_frame->ReleaseMouse();
}
- else if (m_action == actionDragToolbarPane)
+ else if (m_action == actionDragToolbarPane)
{
m_frame->ReleaseMouse();
pane.state &= ~wxPaneInfo::actionPane;
Update();
}
- else
+ else
{
event.Skip();
}
DrawResizeHint(dc, rect);
m_action_hintrect = rect;
}
- else if (m_action == actionClickCaption)
+ else if (m_action == actionClickCaption)
{
int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
}
}
}
- else if (m_action == actionDragFloatingPane)
+ else if (m_action == actionDragFloatingPane)
{
wxPoint pt = m_frame->ClientToScreen(event.GetPosition());
m_action_window->Move(pt.x - m_action_offset.x,
pt.y - m_action_offset.y);
}
- else if (m_action == actionDragToolbarPane)
+ else if (m_action == actionDragToolbarPane)
{
wxPaneInfo& pane = GetPane(m_action_window);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
// OnPaneButton() is an event handler that is called
// when a pane button has been pressed.
-void wxFrameManager::OnPaneButton(wxFrameManagerEvent& event)
+void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt)
{
- wxPaneInfo& pane = *(event.pane);
+ wxASSERT_MSG(evt.pane, wxT("Pane Info passed to wxFrameManager::OnPaneButton must be non-null"));
- if (event.button == wxPaneInfo::buttonClose)
+ wxPaneInfo& pane = *(evt.pane);
+
+ if (evt.button == wxPaneInfo::buttonClose)
{
- pane.Hide();
- Update();
+ // fire pane close event
+ wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE);
+ e.SetPane(evt.pane);
+ ProcessMgrEvent(e);
+
+ if (!e.GetVeto())
+ {
+ pane.Hide();
+ Update();
+ }
}
- else if (event.button == wxPaneInfo::buttonPin)
+ else if (evt.button == wxPaneInfo::buttonPin)
{
if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) &&
pane.IsFloatable())