///////////////////////////////////////////////////////////////////////////////
-// Name: src/univ/window.cpp
+// Name: src/univ/winuniv.cpp
// Purpose: implementation of extra wxWindow methods for wxUniv port
// Author: Vadim Zeitlin
// Modified by:
#include "wx/menu.h"
#include "wx/frame.h"
#include "wx/log.h"
+ #include "wx/button.h"
#endif // WX_PRECOMP
#include "wx/univ/colschem.h"
#include "wx/univ/renderer.h"
#include "wx/univ/theme.h"
+
#if wxUSE_CARET
#include "wx/caret.h"
#endif // wxUSE_CARET
-// turn Refresh() debugging on/off
-#define WXDEBUG_REFRESH
-
-#ifndef __WXDEBUG__
- #undef WXDEBUG_REFRESH
+#if wxDEBUG_LEVEL >= 2
+ // turn Refresh() debugging on/off
+ #define WXDEBUG_REFRESH
#endif
#if defined(WXDEBUG_REFRESH) && defined(__WXMSW__) && !defined(__WXMICROWIN__)
// implementation
// ============================================================================
+// ----------------------------------------------------------------------------
+// scrollbars class
+// ----------------------------------------------------------------------------
+
+// This is scrollbar class used to implement wxWindow's "built-in" scrollbars;
+// unlike the standard wxScrollBar class, this one is positioned outside of its
+// parent's client area
+class wxWindowScrollBar : public wxScrollBar
+{
+public:
+ wxWindowScrollBar(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxSB_HORIZONTAL)
+ : wxScrollBar(parent, id, pos, size, style)
+ {
+ }
+
+ virtual bool CanBeOutsideClientArea() const { return true; }
+};
+
+
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMSW)
#elif defined(__WXGTK__)
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowGTK)
+#elif defined(__WXOSX_OR_COCOA__)
+ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMac)
#elif defined(__WXMGL__)
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMGL)
#elif defined(__WXDFB__)
{
#if wxUSE_SCROLLBAR
m_scrollbarVert =
- m_scrollbarHorz = (wxScrollBar *)NULL;
+ m_scrollbarHorz = NULL;
#endif // wxUSE_SCROLLBAR
m_isCurrent = false;
long style,
const wxString& name)
{
+ // Get default border
+ wxBorder border = GetBorder(style);
+ style &= ~wxBORDER_MASK;
+ style |= border;
+
long actualStyle = style;
// we add wxCLIP_CHILDREN to get the same ("natural") behaviour under MSW
// as under the other platforms
actualStyle |= wxCLIP_CHILDREN;
-#ifdef __WXMSW__
- // FIXME: may need this on other platforms
actualStyle &= ~wxVSCROLL;
actualStyle &= ~wxHSCROLL;
+#ifdef __WXMSW__
// without this, borders (non-client areas in general) are not repainted
// correctly when resizing; apparently, native NC areas are fully repainted
// even without this style by MSW, but wxUniv implements client area
SetInsertIntoMain( true );
#endif
#if wxUSE_SCROLLBAR
- m_scrollbarVert = new wxScrollBar(this, wxID_ANY,
- wxDefaultPosition, wxDefaultSize,
- wxSB_VERTICAL);
+ m_scrollbarVert = new wxWindowScrollBar(this, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ wxSB_VERTICAL);
#endif // wxUSE_SCROLLBAR
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( false );
SetInsertIntoMain( true );
#endif
#if wxUSE_SCROLLBAR
- m_scrollbarHorz = new wxScrollBar(this, wxID_ANY,
- wxDefaultPosition, wxDefaultSize,
- wxSB_HORIZONTAL);
+ m_scrollbarHorz = new wxWindowScrollBar(this, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ wxSB_HORIZONTAL);
#endif // wxUSE_SCROLLBAR
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( false );
wxWindow::~wxWindow()
{
- m_isBeingDeleted = true;
+ SendDestroyEvent();
+
+#if wxUSE_SCROLLBAR
+ // clear pointers to scrollbar before deleting the children: they are
+ // children and so will be deleted by DestroyChildren() call below and if
+ // any code using the scrollbars would be called in the process or from
+ // ~wxWindowBase, the app would crash:
+ m_scrollbarVert = m_scrollbarHorz = NULL;
+#endif
// we have to destroy our children before we're destroyed because our
// children suppose that we're of type wxWindow, not just wxWindowNative,
const wxBitmap& wxWindow::GetBackgroundBitmap(int *alignment,
wxStretch *stretch) const
{
- if ( m_bitmapBg.Ok() )
+ if ( m_bitmapBg.IsOk() )
{
if ( alignment )
*alignment = m_alignBgBitmap;
rect.height = size.y;
wxWindow * const parent = GetParent();
- if ( HasTransparentBackground() && parent )
+ if ( HasTransparentBackground() && !UseBgCol() && parent )
{
+ // DirectFB paints the parent first, then its child windows, so by
+ // the time this code is called, parent's background was already
+ // drawn and there's no point in (imperfectly!) duplicating the work
+ // here:
+#ifndef __WXDFB__
wxASSERT( !IsTopLevel() );
wxPoint pos = GetPosition();
// Restore DC logical origin
dc.SetLogicalOrigin( org_x, org_y );
+#endif // !__WXDFB__
}
else
{
void wxWindow::EraseBackground(wxDC& dc, const wxRect& rect)
{
- if ( GetBackgroundBitmap().Ok() )
+ if ( GetBackgroundBitmap().IsOk() )
{
// Get the bitmap and the flags
int alignment;
}
}
else
- if (HasFlag( wxSUNKEN_BORDER ) || HasFlag( wxRAISED_BORDER ))
+ if (HasFlag( wxSUNKEN_BORDER ) || HasFlag( wxRAISED_BORDER ) || HasFlag( wxBORDER_THEME ))
{
if (newSize.y > m_oldSize.y)
{
return wxWindowNative::DoGetBestSize();
}
+wxSize wxWindow::DoGetBorderSize() const
+{
+ return AdjustSize(wxSize(0, 0));
+}
+
wxSize wxWindow::AdjustSize(const wxSize& size) const
{
wxSize sz = size;
{
#if wxUSE_SCROLLBAR
wxASSERT_MSG( pageSize <= range,
- _T("page size can't be greater than range") );
+ wxT("page size can't be greater than range") );
bool hasClientSizeChanged = false;
wxScrollBar *scrollbar = GetScrollbar(orient);
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( true );
#endif
- scrollbar = new wxScrollBar(this, wxID_ANY,
- wxDefaultPosition, wxDefaultSize,
- orient & wxVERTICAL ? wxSB_VERTICAL
- : wxSB_HORIZONTAL);
+ scrollbar = new wxWindowScrollBar(this, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ orient & wxVERTICAL ? wxSB_VERTICAL
+ : wxSB_HORIZONTAL);
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( false );
#endif
// and scrolling direction
// 2. if scrolling in both axes, scroll all children
+ bool shouldMove = false;
+
if ( rect && (dx * dy == 0 /* moving in only one of x, y axis */) )
{
wxRect childRect = child->GetRect();
if ( dx == 0 && (childRect.GetLeft() <= rect->GetRight() ||
childRect.GetRight() >= rect->GetLeft()) )
{
- child->Move(child->GetPosition() + offset);
+ shouldMove = true;
}
else if ( dy == 0 && (childRect.GetTop() <= rect->GetBottom() ||
childRect.GetBottom() >= rect->GetTop()) )
{
- child->Move(child->GetPosition() + offset);
+ shouldMove = true;
}
+ // else: child outside of scrolling shaft, don't move
}
- else
+ else // scrolling in both axes or rect=NULL
{
- child->Move(child->GetPosition() + offset);
+ shouldMove = true;
}
+
+ if ( shouldMove )
+ child->Move(child->GetPosition() + offset, wxSIZE_ALLOW_MINUS_ONE);
}
#endif // wxX11/!wxX11
}
wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
{
- wxASSERT_MSG( !dx || !dy, _T("can't be used for diag scrolling") );
+ wxASSERT_MSG( !dx || !dy, wxT("can't be used for diag scrolling") );
// the rect to refresh (which we will calculate)
wxRect rect;
// location
wxSize sizeTotal = rectTotal ? rectTotal->GetSize() : GetClientSize();
- wxLogTrace(_T("scroll"), _T("rect is %dx%d, scroll by %d, %d"),
+ wxLogTrace(wxT("scroll"), wxT("rect is %dx%d, scroll by %d, %d"),
sizeTotal.x, sizeTotal.y, dx, dy);
// the initial and end point of the region we move in client coords
if ( size.x <= 0 || size.y <= 0 )
{
// just redraw everything as nothing of the displayed image will stay
- wxLogTrace(_T("scroll"), _T("refreshing everything"));
+ wxLogTrace(wxT("scroll"), wxT("refreshing everything"));
rect = rectTotal ? *rectTotal : wxRect(0, 0, sizeTotal.x, sizeTotal.y);
}
);
dc.Blit(ptDest, size, &dcMem, wxPoint(0,0));
- wxLogTrace(_T("scroll"),
- _T("Blit: (%d, %d) of size %dx%d -> (%d, %d)"),
+ wxLogTrace(wxT("scroll"),
+ wxT("Blit: (%d, %d) of size %dx%d -> (%d, %d)"),
ptSource.x, ptSource.y,
size.x, size.y,
ptDest.x, ptDest.y);
rect.height = sizeTotal.y;
- wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
+ wxLogTrace(wxT("scroll"), wxT("refreshing (%d, %d)-(%d, %d)"),
rect.x, rect.y,
rect.GetRight() + 1, rect.GetBottom() + 1);
}
rect.width = sizeTotal.x;
- wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
+ wxLogTrace(wxT("scroll"), wxT("refreshing (%d, %d)-(%d, %d)"),
rect.x, rect.y,
rect.GetRight() + 1, rect.GetBottom() + 1);
}
}
#endif // wxUSE_MENUS
+#if wxUSE_BUTTON
// if it wasn't in a menu, try to find a button
if ( command != -1 )
{
}
}
}
+#endif // wxUSE_BUTTON
// don't propagate accels from the child frame to the parent one
break;
}
}
+ // if Return was pressed, see if there's a default button to activate
+ if ( !event.HasModifiers() && event.GetKeyCode() == WXK_RETURN )
+ {
+ wxTopLevelWindow *
+ tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
+ if ( tlw )
+ {
+ wxButton *btn = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
+ if ( btn )
+ {
+ wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, btn->GetId());
+ evt.SetEventObject(btn);
+ btn->Command(evt);
+ return;
+ }
+ }
+ }
+
+
event.Skip();
}