/////////////////////////////////////////////////////////////////////////////
-// Name: topluniv.cpp
+// Name: src/univ/topluniv.cpp
// Author: Vaclav Slavik
// Id: $Id$
-// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
+// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "univtoplevel.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
-#include "wx/defs.h"
+#include "wx/toplevel.h"
#ifndef WX_PRECOMP
#include "wx/dcclient.h"
#include "wx/settings.h"
+ #include "wx/bitmap.h"
+ #include "wx/image.h"
+ #include "wx/frame.h"
#endif
-#include "wx/toplevel.h"
#include "wx/univ/renderer.h"
-#include "wx/bitmap.h"
-#include "wx/image.h"
#include "wx/cshelp.h"
#include "wx/evtloop.h"
BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative)
WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow)
EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint)
+ EVT_MENU_RANGE(wxID_CLOSE_FRAME, wxID_RESTORE_FRAME, wxTopLevelWindow::OnSystemMenu)
END_EVENT_TABLE()
WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow)
void wxTopLevelWindow::Init()
{
- m_isActive = FALSE;
+ m_isActive = false;
m_windowStyle = 0;
m_pressedButton = 0;
}
if ( ms_drawDecorations == -1 )
{
- ms_drawDecorations =
- !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS)
+ ms_drawDecorations =
+ !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS)
|| wxGetEnv(wxT("WXDECOR"), NULL);
// FIXME -- wxUniv should provide a way to force non-native decorations!
// $WXDECOR is just a hack in absence of better wxUniv solution
exstyleOrig = GetExtraStyle();
style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW |
- wxTHICK_FRAME);
- style = wxSIMPLE_BORDER;
- SetExtraStyle(exstyleOrig &
- ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP));
+ wxRESIZE_BORDER);
+ style |= wxSIMPLE_BORDER;
+ SetExtraStyle(exstyleOrig & ~wxWS_EX_CONTEXTHELP);
}
if ( !wxTopLevelWindowNative::Create(parent, id, title, pos,
size, style, name) )
- return FALSE;
+ return false;
if ( ms_drawDecorations )
{
m_exStyle = exstyleOrig;
}
- return TRUE;
+ return true;
}
bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
{
- if ( show == IsFullScreen() ) return FALSE;
+ if ( show == IsFullScreen() ) return false;
if ( ms_drawDecorations )
{
style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
}
#if wxUSE_HELP
- if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
+ if ( m_exStyle & wxWS_EX_CONTEXTHELP)
style |= wxTOPLEVEL_BUTTON_HELP;
#endif
}
if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 )
style |= wxTOPLEVEL_BORDER;
- if ( m_windowStyle & (wxRESIZE_BORDER | wxTHICK_FRAME) )
+ if ( m_windowStyle & (wxRESIZE_BORDER | wxRESIZE_BORDER) )
style |= wxTOPLEVEL_RESIZEABLE;
if ( IsMaximized() )
wxTopLevelWindowNative::DoSetClientSize(width, height);
}
-void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
+void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent& event)
{
if ( !ms_drawDecorations || !m_renderer )
event.Skip();
else
{
// get the window rect
- wxRect rect;
- wxSize size = GetSize();
- rect.x =
- rect.y = 0;
- rect.width = size.x;
- rect.height = size.y;
+ wxRect rect(GetSize());
wxWindowDC dc(this);
m_renderer->DrawFrameTitleBar(dc, rect,
return m_renderer->HitTestFrame(rect, pt+GetClientAreaOrigin(), GetDecorationsStyle());
}
+int wxTopLevelWindow::GetMinWidth() const
+{
+ if ( ms_drawDecorations )
+ {
+ return wxMax(wxTopLevelWindowNative::GetMinWidth(),
+ m_renderer->GetFrameMinSize(GetDecorationsStyle()).x);
+ }
+ else
+ return wxTopLevelWindowNative::GetMinWidth();
+}
+
+int wxTopLevelWindow::GetMinHeight() const
+{
+ if ( ms_drawDecorations )
+ {
+ return wxMax(wxTopLevelWindowNative::GetMinHeight(),
+ m_renderer->GetFrameMinSize(GetDecorationsStyle()).y);
+ }
+ else
+ return wxTopLevelWindowNative::GetMinHeight();
+}
+
// ----------------------------------------------------------------------------
// icons
// ----------------------------------------------------------------------------
-void wxTopLevelWindow::SetIcon(const wxIcon& icon)
+void wxTopLevelWindow::SetIcons(const wxIconBundle& icons)
{
- wxTopLevelWindowNative::SetIcon(icon);
+ wxTopLevelWindowNative::SetIcons(icons);
if ( ms_drawDecorations && m_renderer )
{
wxSize size = m_renderer->GetFrameIconSize();
+ const wxIcon& icon = icons.GetIcon( size );
- if ( !icon.Ok() || size.x == -1 )
+ if ( !icon.Ok() || size.x == wxDefaultCoord )
m_titlebarIcon = icon;
else
{
m_titlebarIcon = wxNullIcon;
else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
m_titlebarIcon = icon;
+#if wxUSE_IMAGE
else
{
wxImage img = bmp1.ConvertToImage();
img.Rescale(size.x, size.y);
m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
}
+#endif // wxUSE_IMAGE
}
}
}
// interactive manipulation
// ----------------------------------------------------------------------------
+
+static bool wxGetResizingCursor(long hitTestResult, wxCursor& cursor)
+{
+ if ( hitTestResult & wxHT_TOPLEVEL_ANY_BORDER )
+ {
+ switch (hitTestResult)
+ {
+ case wxHT_TOPLEVEL_BORDER_N:
+ case wxHT_TOPLEVEL_BORDER_S:
+ cursor = wxCursor(wxCURSOR_SIZENS);
+ break;
+ case wxHT_TOPLEVEL_BORDER_W:
+ case wxHT_TOPLEVEL_BORDER_E:
+ cursor = wxCursor(wxCURSOR_SIZEWE);
+ break;
+ case wxHT_TOPLEVEL_BORDER_NE:
+ case wxHT_TOPLEVEL_BORDER_SW:
+ cursor = wxCursor(wxCURSOR_SIZENESW);
+ break;
+ case wxHT_TOPLEVEL_BORDER_NW:
+ case wxHT_TOPLEVEL_BORDER_SE:
+ cursor = wxCursor(wxCURSOR_SIZENWSE);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+}
+
#define wxINTERACTIVE_RESIZE_DIR \
(wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
struct wxInteractiveMoveData
{
- wxTopLevelWindowBase *m_window;
+ wxTopLevelWindow *m_window;
wxEventLoop *m_evtLoop;
int m_flags;
wxRect m_rect;
wxRect m_rectOrig;
wxPoint m_pos;
wxSize m_minSize, m_maxSize;
+ bool m_sizingCursor;
};
class wxInteractiveMoveHandler : public wxEvtHandler
{
public:
wxInteractiveMoveHandler(wxInteractiveMoveData& data) : m_data(data) {}
-
+
private:
DECLARE_EVENT_TABLE()
void OnMouseMove(wxMouseEvent& event);
END_EVENT_TABLE()
-static inline LINKAGEMODE
+static inline LINKAGEMODE
void wxApplyResize(wxInteractiveMoveData& data, const wxPoint& diff)
{
if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
{
data.m_rect.height += diff.y;
}
-
- if ( data.m_minSize.x != -1 && data.m_rect.width < data.m_minSize.x )
+
+ if ( data.m_minSize.x != wxDefaultCoord && data.m_rect.width < data.m_minSize.x )
{
if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
data.m_rect.width = data.m_minSize.x;
}
- if ( data.m_maxSize.x != -1 && data.m_rect.width > data.m_maxSize.x )
+ if ( data.m_maxSize.x != wxDefaultCoord && data.m_rect.width > data.m_maxSize.x )
{
if ( data.m_flags & wxINTERACTIVE_RESIZE_W )
data.m_rect.x -= data.m_minSize.x - data.m_rect.width;
data.m_rect.width = data.m_maxSize.x;
}
- if ( data.m_minSize.y != -1 && data.m_rect.height < data.m_minSize.y )
+ if ( data.m_minSize.y != wxDefaultCoord && data.m_rect.height < data.m_minSize.y )
{
if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
data.m_rect.height = data.m_minSize.y;
}
- if ( data.m_maxSize.y != -1 && data.m_rect.height > data.m_maxSize.y )
+ if ( data.m_maxSize.y != wxDefaultCoord && data.m_rect.height > data.m_maxSize.y )
{
if ( data.m_flags & wxINTERACTIVE_RESIZE_N )
data.m_rect.y -= data.m_minSize.y - data.m_rect.height;
}
}
-void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent& event)
+void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent& WXUNUSED(event))
{
if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
{
- m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
- m_data.m_pos = wxGetMousePosition();
+ m_data.m_evtLoop->Exit();
}
}
void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent& event)
{
- if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
- {
- m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
- m_data.m_pos = wxGetMousePosition();
- }
-
- wxPoint diff(-1,-1);
-
+ wxPoint diff(wxDefaultCoord,wxDefaultCoord);
+
switch ( event.GetKeyCode() )
{
case WXK_UP: diff = wxPoint(0, -16); break;
m_data.m_evtLoop->Exit();
return;
}
-
- if ( diff.x != -1 )
+
+ if ( diff.x != wxDefaultCoord )
{
+ if ( m_data.m_flags & wxINTERACTIVE_WAIT_FOR_INPUT )
+ {
+ m_data.m_flags &= ~wxINTERACTIVE_WAIT_FOR_INPUT;
+ if ( m_data.m_sizingCursor )
+ {
+ wxEndBusyCursor();
+ m_data.m_sizingCursor = false;
+ }
+
+ if ( m_data.m_flags & wxINTERACTIVE_MOVE )
+ {
+ m_data.m_pos = m_data.m_window->GetPosition() +
+ wxPoint(m_data.m_window->GetSize().x/2, 8);
+ }
+ }
+
+ wxPoint warp;
+ bool changeCur = false;
+
if ( m_data.m_flags & wxINTERACTIVE_MOVE )
{
m_data.m_rect.Offset(diff);
m_data.m_window->Move(m_data.m_rect.GetPosition());
+ warp = wxPoint(m_data.m_window->GetSize().x/2, 8);
}
else /* wxINTERACTIVE_RESIZE */
{
- if ( !(m_data.m_flags & wxINTERACTIVE_RESIZE_DIR) )
+ if ( !(m_data.m_flags &
+ (wxINTERACTIVE_RESIZE_N | wxINTERACTIVE_RESIZE_S)) )
{
if ( diff.y < 0 )
+ {
m_data.m_flags |= wxINTERACTIVE_RESIZE_N;
+ m_data.m_pos.y = m_data.m_window->GetPosition().y;
+ changeCur = true;
+ }
else if ( diff.y > 0 )
+ {
m_data.m_flags |= wxINTERACTIVE_RESIZE_S;
+ m_data.m_pos.y = m_data.m_window->GetPosition().y +
+ m_data.m_window->GetSize().y;
+ changeCur = true;
+ }
+ }
+ if ( !(m_data.m_flags &
+ (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E)) )
+ {
if ( diff.x < 0 )
+ {
m_data.m_flags |= wxINTERACTIVE_RESIZE_W;
+ m_data.m_pos.x = m_data.m_window->GetPosition().x;
+ changeCur = true;
+ }
else if ( diff.x > 0 )
+ {
m_data.m_flags |= wxINTERACTIVE_RESIZE_E;
+ m_data.m_pos.x = m_data.m_window->GetPosition().x +
+ m_data.m_window->GetSize().x;
+ changeCur = true;
+ }
}
wxApplyResize(m_data, diff);
m_data.m_window->SetSize(m_data.m_rect);
+
+ if ( m_data.m_flags & wxINTERACTIVE_RESIZE_W )
+ warp.x = 0;
+ else if ( m_data.m_flags & wxINTERACTIVE_RESIZE_E )
+ warp.x = m_data.m_window->GetSize().x-1;
+ else
+ warp.x = wxGetMousePosition().x - m_data.m_window->GetPosition().x;
+
+ if ( m_data.m_flags & wxINTERACTIVE_RESIZE_N )
+ warp.y = 0;
+ else if ( m_data.m_flags & wxINTERACTIVE_RESIZE_S )
+ warp.y = m_data.m_window->GetSize().y-1;
+ else
+ warp.y = wxGetMousePosition().y - m_data.m_window->GetPosition().y;
+ }
+
+ warp -= m_data.m_window->GetClientAreaOrigin();
+ m_data.m_window->WarpPointer(warp.x, warp.y);
+
+ if ( changeCur )
+ {
+ long hit = m_data.m_window->HitTest(warp);
+ wxCursor cur;
+ if ( wxGetResizingCursor(hit, cur) )
+ {
+ if ( m_data.m_sizingCursor )
+ wxEndBusyCursor();
+ wxBeginBusyCursor(&cur);
+ m_data.m_sizingCursor = true;
+ }
}
}
}
-void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent& event)
+void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent& WXUNUSED(event))
{
m_data.m_evtLoop->Exit();
}
wxASSERT_MSG( !((flags & wxINTERACTIVE_MOVE) && (flags & wxINTERACTIVE_RESIZE)),
wxT("can't move and resize window at the same time") );
- wxASSERT_MSG( !(flags & wxINTERACTIVE_RESIZE) ||
- (flags & wxINTERACTIVE_WAIT_FOR_INPUT) ||
+ wxASSERT_MSG( !(flags & wxINTERACTIVE_RESIZE) ||
+ (flags & wxINTERACTIVE_WAIT_FOR_INPUT) ||
(flags & wxINTERACTIVE_RESIZE_DIR),
wxT("direction of resizing not specified") );
wxInteractiveMoveData data;
wxEventLoop loop;
- wxWindow *focus = FindFocus();
-
- // FIXME - display resize cursor if waiting for initial input
+
+ SetFocus();
+
+#ifndef __WXGTK__
+ if ( flags & wxINTERACTIVE_WAIT_FOR_INPUT )
+ {
+ wxCursor sizingCursor(wxCURSOR_SIZING);
+ wxBeginBusyCursor(&sizingCursor);
+ data.m_sizingCursor = true;
+ }
+ else
+#endif
+ data.m_sizingCursor = false;
data.m_window = this;
data.m_evtLoop = &loop;
data.m_minSize = wxSize(GetMinWidth(), GetMinHeight());
data.m_maxSize = wxSize(GetMaxWidth(), GetMaxHeight());
- this->PushEventHandler(new wxInteractiveMoveHandler(data));
- if ( focus )
- focus->PushEventHandler(new wxInteractiveMoveHandler(data));
+ wxEvtHandler *handler = new wxInteractiveMoveHandler(data);
+ this->PushEventHandler(handler);
CaptureMouse();
loop.Run();
ReleaseMouse();
- this->PopEventHandler(TRUE/*delete*/);
- if ( focus )
- focus->PopEventHandler(TRUE/*delete*/);
+ this->RemoveEventHandler(handler);
+ delete handler;
+
+ if ( data.m_sizingCursor )
+ wxEndBusyCursor();
}
// ----------------------------------------------------------------------------
bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
long numArg,
- const wxString& strArg)
+ const wxString& WXUNUSED(strArg))
{
bool isActive = numArg != 0;
m_isActive = isActive;
RefreshTitleBar();
}
- return TRUE;
+ return true;
}
else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS )
{
m_pressedButton = numArg;
RefreshTitleBar();
- return TRUE;
+ return true;
}
else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE )
{
m_pressedButton = 0;
RefreshTitleBar();
- return TRUE;
+ return true;
}
else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK )
m_pressedButton = 0;
RefreshTitleBar();
ClickTitleBarButton(numArg);
- return TRUE;
+ return true;
}
else if ( action == wxACTION_TOPLEVEL_MOVE )
{
InteractiveMove(wxINTERACTIVE_MOVE);
- return TRUE;
+ return true;
}
else if ( action == wxACTION_TOPLEVEL_RESIZE )
if ( numArg & wxHT_TOPLEVEL_BORDER_E )
flags |= wxINTERACTIVE_RESIZE_E;
InteractiveMove(flags);
- return TRUE;
+ return true;
}
else
- return FALSE;
+ return false;
+}
+
+void wxTopLevelWindow::OnSystemMenu(wxCommandEvent& event)
+{
+ bool ret = true;
+
+ switch (event.GetId())
+ {
+ case wxID_CLOSE_FRAME:
+ ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ wxTOPLEVEL_BUTTON_CLOSE);
+ break;
+ case wxID_MOVE_FRAME:
+ InteractiveMove(wxINTERACTIVE_MOVE | wxINTERACTIVE_WAIT_FOR_INPUT);
+ break;
+ case wxID_RESIZE_FRAME:
+ InteractiveMove(wxINTERACTIVE_RESIZE | wxINTERACTIVE_WAIT_FOR_INPUT);
+ break;
+ case wxID_MAXIMIZE_FRAME:
+ ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ wxTOPLEVEL_BUTTON_MAXIMIZE);
+ break;
+ case wxID_ICONIZE_FRAME:
+ ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ wxTOPLEVEL_BUTTON_ICONIZE);
+ break;
+ case wxID_RESTORE_FRAME:
+ ret = PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ wxTOPLEVEL_BUTTON_RESTORE);
+ break;
+
+ default:
+ ret = false;
+ }
+
+ if ( !ret )
+ event.Skip();
}
m_winCapture = NULL;
m_winHitTest = 0;
m_winPressed = 0;
- m_borderCursorOn = FALSE;
+ m_borderCursorOn = false;
}
bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
m_winHitTest = hit;
m_winPressed = hit;
consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
- return TRUE;
+ return true;
}
- else if ( hit & wxHT_TOPLEVEL_TITLEBAR )
+ else if ( (hit & wxHT_TOPLEVEL_TITLEBAR) && !w->IsMaximized() )
{
consumer->PerformAction(wxACTION_TOPLEVEL_MOVE);
- return TRUE;
+ return true;
}
else if ( (consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER)
&& (hit & wxHT_TOPLEVEL_ANY_BORDER) )
{
consumer->PerformAction(wxACTION_TOPLEVEL_RESIZE, hit);
- return TRUE;
+ return true;
}
}
if ( m_winHitTest == m_winPressed )
{
consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed);
- return TRUE;
+ return true;
}
}
//else: the mouse was released outside the window, this doesn't
consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
m_winHitTest = hit;
- return TRUE;
+ return true;
}
}
else if ( consumer->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER )
if ( m_borderCursorOn )
{
- m_borderCursorOn = FALSE;
+ m_borderCursorOn = false;
win->SetCursor(m_origCursor);
}
if ( hit & wxHT_TOPLEVEL_ANY_BORDER )
{
- m_borderCursorOn = TRUE;
wxCursor cur;
- switch (hit)
- {
- case wxHT_TOPLEVEL_BORDER_N:
- case wxHT_TOPLEVEL_BORDER_S:
- cur = wxCursor(wxCURSOR_SIZENS);
- break;
- case wxHT_TOPLEVEL_BORDER_W:
- case wxHT_TOPLEVEL_BORDER_E:
- cur = wxCursor(wxCURSOR_SIZEWE);
- break;
- case wxHT_TOPLEVEL_BORDER_NE:
- case wxHT_TOPLEVEL_BORDER_SW:
- cur = wxCursor(wxCURSOR_SIZENESW);
- break;
- case wxHT_TOPLEVEL_BORDER_NW:
- case wxHT_TOPLEVEL_BORDER_SE:
- cur = wxCursor(wxCURSOR_SIZENWSE);
- break;
- default:
- m_borderCursorOn = FALSE;
- break;
- }
+ m_borderCursorOn = wxGetResizingCursor(hit, cur);
if ( m_borderCursorOn )
{
m_origCursor = win->GetCursor();
if ( m_borderCursorOn )
{
consumer->GetInputWindow()->SetCursor(m_origCursor);
- m_borderCursorOn = FALSE;
+ m_borderCursorOn = false;
}
consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
- return FALSE;
+ return false;
}