Merge branch 'qt-fixes'
A multitude of miscellaneous Qt fixes and improvements. See https://github.com/wxWidgets/wxWidgets/pull/1552
This commit is contained in:
commit
04949050b2
@ -56,6 +56,9 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void DoGetClientSize(int *width, int *height) const wxOVERRIDE;
|
||||
virtual void DoSetClientSize(int width, int height) wxOVERRIDE;
|
||||
|
||||
virtual QWidget* QtGetParentWidget() const wxOVERRIDE;
|
||||
|
||||
private:
|
||||
// Common part of all ctors.
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
|
||||
virtual QWidget *GetHandle() const wxOVERRIDE;
|
||||
|
||||
void QtSendEvent(wxEventType evtType, const QModelIndex &index, bool selected);
|
||||
void QtSendEvent(wxEventType evtType, int rowIndex, bool selected);
|
||||
|
||||
protected:
|
||||
virtual void DoSetFirstItem(int n) wxOVERRIDE;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "wx/bitmap.h"
|
||||
|
||||
class QAction;
|
||||
class wxQtAction;
|
||||
|
||||
class WXDLLIMPEXP_FWD_CORE wxMenu;
|
||||
|
||||
@ -41,7 +42,7 @@ public:
|
||||
|
||||
private:
|
||||
// Qt is using an action instead of a menu item.
|
||||
QAction *m_qtAction;
|
||||
wxQtAction *m_qtAction;
|
||||
wxBitmap m_bitmap;
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS( wxMenuItem );
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define _WX_QT_PRIVATE_TREEITEM_DELEGATE_H
|
||||
|
||||
#include <QtWidgets/QStyledItemDelegate>
|
||||
#include <QtWidgets/QToolTip>
|
||||
|
||||
#include "wx/app.h"
|
||||
#include "wx/textctrl.h"
|
||||
@ -67,6 +68,28 @@ public:
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||
{
|
||||
if ( event->type() == QEvent::ToolTip )
|
||||
{
|
||||
const QRect &itemRect = view->visualRect(index);
|
||||
const QSize &bestSize = sizeHint(option, index);
|
||||
if ( itemRect.width() < bestSize.width() )
|
||||
{
|
||||
const QString &value = index.data(Qt::DisplayRole).toString();
|
||||
QToolTip::showText(event->globalPos(), value, view);
|
||||
}
|
||||
else
|
||||
{
|
||||
QToolTip::hideText();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::helpEvent(event, view, option, index);
|
||||
}
|
||||
|
||||
private:
|
||||
wxWindow* m_parent;
|
||||
mutable wxTextCtrl* m_textCtrl;
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
QObject::connect( this, &QObject::destroyed, this,
|
||||
&wxQtEventSignalHandler::HandleDestroyedSignal );
|
||||
|
||||
Widget::setMouseTracking(true);
|
||||
}
|
||||
|
||||
void HandleDestroyedSignal()
|
||||
@ -104,7 +105,7 @@ protected:
|
||||
if ( !this->GetHandler()->QtHandleCloseEvent(this, event) )
|
||||
Widget::closeEvent(event);
|
||||
else
|
||||
event->accept();
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
//wxContextMenuEvent
|
||||
|
@ -168,6 +168,7 @@ public:
|
||||
|
||||
static void QtStoreWindowPointer( QWidget *widget, const wxWindowQt *window );
|
||||
static wxWindowQt *QtRetrieveWindowPointer( const QWidget *widget );
|
||||
static void QtSendSetCursorEvent(wxWindowQt* win, wxPoint posClient);
|
||||
|
||||
#if wxUSE_ACCEL
|
||||
virtual void QtHandleShortcut ( int command );
|
||||
@ -215,6 +216,12 @@ protected:
|
||||
virtual bool DoPopupMenu(wxMenu *menu, int x, int y) wxOVERRIDE;
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
// Return the parent to use for children being reparented to us: this is
|
||||
// overridden in wxFrame to use its central widget rather than the frame
|
||||
// itself.
|
||||
virtual QWidget* QtGetParentWidget() const { return GetHandle(); }
|
||||
|
||||
|
||||
QWidget *m_qtWindow;
|
||||
|
||||
private:
|
||||
@ -224,6 +231,11 @@ private:
|
||||
QScrollBar *m_horzScrollBar; // owned by m_qtWindow when allocated
|
||||
QScrollBar *m_vertScrollBar; // owned by m_qtWindow when allocated
|
||||
|
||||
// Return the viewport of m_qtContainer, if it's used, or just m_qtWindow.
|
||||
//
|
||||
// Always returns non-null pointer if the window has been already created.
|
||||
QWidget *QtGetClientWidget() const;
|
||||
|
||||
QScrollBar *QtGetScrollBar( int orientation ) const;
|
||||
QScrollBar *QtSetScrollBar( int orientation, QScrollBar *scrollBar=NULL );
|
||||
|
||||
|
@ -848,7 +848,7 @@ void wxAuiManager::UpdateHintWindowConfig()
|
||||
if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) && can_do_transparent)
|
||||
{
|
||||
// Make a window to use for a transparent hint
|
||||
#if defined(__WXMSW__) || defined(__WXGTK__)
|
||||
#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXQT__)
|
||||
m_hintWnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString,
|
||||
wxDefaultPosition, wxSize(1,1),
|
||||
wxFRAME_TOOL_WINDOW |
|
||||
|
@ -85,8 +85,9 @@ wxAnyButton::wxAnyButton() :
|
||||
|
||||
void wxAnyButton::QtCreate(wxWindow *parent)
|
||||
{
|
||||
// create the default push button (used in button and bmp button)
|
||||
m_qtPushButton = new wxQtPushButton( parent, this );
|
||||
// create the basic push button (used in button and bmp button)
|
||||
m_qtPushButton = new wxQtPushButton(parent, this);
|
||||
m_qtPushButton->setAutoDefault(false);
|
||||
}
|
||||
|
||||
void wxAnyButton::QtSetBitmap( const wxBitmap &bitmap )
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
#include "wx/qt/private/converter.h"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QWidget>
|
||||
#include <QMimeData>
|
||||
#include <QCloseEvent>
|
||||
#include <QtGui/QDrag>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtGui/QCloseEvent>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -563,7 +563,7 @@ void wxNativeFontInfo::SetFamily(wxFontFamily family)
|
||||
{
|
||||
m_qtFont.setStyleHint(ConvertFontFamily(family));
|
||||
// reset the face name to force qt to choose a new font
|
||||
m_qtFont.setFamily("");
|
||||
m_qtFont.setFamily(m_qtFont.defaultFamily());
|
||||
}
|
||||
|
||||
void wxNativeFontInfo::SetEncoding(wxFontEncoding WXUNUSED(encoding))
|
||||
|
@ -134,15 +134,16 @@ void wxFrame::SetWindowStyleFlag( long style )
|
||||
{
|
||||
wxWindow::SetWindowStyleFlag( style );
|
||||
|
||||
QMainWindow *qtFrame = GetQMainWindow();
|
||||
Qt::WindowFlags qtFlags = qtFrame->windowFlags();
|
||||
qtFlags |= Qt::CustomizeWindowHint;
|
||||
Qt::WindowFlags qtFlags = Qt::CustomizeWindowHint;
|
||||
|
||||
if ( HasFlag( wxFRAME_TOOL_WINDOW ) )
|
||||
{
|
||||
qtFlags &= ~Qt::WindowType_Mask;
|
||||
qtFlags |= Qt::Tool;
|
||||
}
|
||||
else
|
||||
{
|
||||
qtFlags |= Qt::Window;
|
||||
}
|
||||
|
||||
if ( HasFlag(wxCAPTION) )
|
||||
{
|
||||
@ -183,15 +184,19 @@ void wxFrame::SetWindowStyleFlag( long style )
|
||||
qtFlags |= Qt::FramelessWindowHint;
|
||||
}
|
||||
|
||||
qtFrame->setWindowFlags(qtFlags);
|
||||
GetQMainWindow()->setWindowFlags(qtFlags);
|
||||
}
|
||||
|
||||
QWidget* wxFrame::QtGetParentWidget() const
|
||||
{
|
||||
return GetQMainWindow()->centralWidget();
|
||||
}
|
||||
|
||||
void wxFrame::AddChild( wxWindowBase *child )
|
||||
{
|
||||
// Make sure all children are children of the central widget:
|
||||
|
||||
QtReparent( child->GetHandle(), GetQMainWindow()->centralWidget() );
|
||||
QtReparent( child->GetHandle(), QtGetParentWidget() );
|
||||
|
||||
wxFrameBase::AddChild( child );
|
||||
}
|
||||
@ -226,6 +231,19 @@ void wxFrame::DoGetClientSize(int *width, int *height) const
|
||||
}
|
||||
}
|
||||
|
||||
void wxFrame::DoSetClientSize(int width, int height)
|
||||
{
|
||||
wxWindow::DoSetClientSize(width, height);
|
||||
|
||||
int adjustedWidth, adjustedHeight;
|
||||
DoGetClientSize(&adjustedWidth, &adjustedHeight);
|
||||
|
||||
QWidget *centralWidget = GetQMainWindow()->centralWidget();
|
||||
QRect geometry = centralWidget->geometry();
|
||||
geometry.setSize(QSize(adjustedWidth, adjustedHeight));
|
||||
centralWidget->setGeometry(geometry);
|
||||
}
|
||||
|
||||
QMainWindow *wxFrame::GetQMainWindow() const
|
||||
{
|
||||
return static_cast<QMainWindow*>(m_qtWindow);
|
||||
|
@ -19,31 +19,51 @@ public:
|
||||
wxQtListWidget( wxWindow *parent, wxListBox *handler );
|
||||
|
||||
private:
|
||||
void clicked( const QModelIndex &index );
|
||||
void OnCurrentItemChange(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void doubleClicked( const QModelIndex &index );
|
||||
void itemChanged(QListWidgetItem *item);
|
||||
};
|
||||
|
||||
wxQtListWidget::wxQtListWidget( wxWindow *parent, wxListBox *handler )
|
||||
: wxQtEventSignalHandler< QListWidget, wxListBox >( parent, handler )
|
||||
{
|
||||
connect(this, &QListWidget::clicked, this, &wxQtListWidget::clicked);
|
||||
connect(this, &QListWidget::currentItemChanged, this, &wxQtListWidget::OnCurrentItemChange);
|
||||
connect(this, &QListWidget::doubleClicked, this, &wxQtListWidget::doubleClicked);
|
||||
connect(this, &QListWidget::itemChanged, this, &wxQtListWidget::itemChanged);
|
||||
}
|
||||
|
||||
void wxQtListWidget::clicked(const QModelIndex &index )
|
||||
void wxQtListWidget::OnCurrentItemChange(QListWidgetItem *current, QListWidgetItem *)
|
||||
{
|
||||
if ( !current )
|
||||
return;
|
||||
|
||||
wxListBox *handler = GetHandler();
|
||||
if ( handler )
|
||||
handler->QtSendEvent(wxEVT_LISTBOX, index, true);
|
||||
{
|
||||
const QModelIndex &index = indexFromItem(current);
|
||||
handler->QtSendEvent(wxEVT_LISTBOX, index.row(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void wxQtListWidget::doubleClicked( const QModelIndex &index )
|
||||
{
|
||||
wxListBox *handler = GetHandler();
|
||||
if ( handler )
|
||||
handler->QtSendEvent(wxEVT_LISTBOX_DCLICK, index, true);
|
||||
handler->QtSendEvent(wxEVT_LISTBOX_DCLICK, index.row(), true);
|
||||
}
|
||||
|
||||
void wxQtListWidget::itemChanged(QListWidgetItem *item)
|
||||
{
|
||||
if ( item->flags() & Qt::ItemIsUserCheckable )
|
||||
{
|
||||
wxListBox *handler = GetHandler();
|
||||
if ( handler )
|
||||
{
|
||||
int rowIndex = this->row(item);
|
||||
handler->QtSendEvent(wxEVT_CHECKLISTBOX, rowIndex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxListBox::wxListBox() :
|
||||
m_qtListWidget(NULL)
|
||||
@ -282,9 +302,9 @@ QWidget *wxListBox::GetHandle() const
|
||||
return m_qtListWidget;
|
||||
}
|
||||
|
||||
void wxListBox::QtSendEvent(wxEventType evtType, const QModelIndex &index, bool selected)
|
||||
void wxListBox::QtSendEvent(wxEventType evtType, int rowIndex, bool selected)
|
||||
{
|
||||
SendEvent(evtType, index.row(), selected);
|
||||
SendEvent(evtType, rowIndex, selected);
|
||||
}
|
||||
|
||||
QScrollArea *wxListBox::QtGetScrollBarsContainer() const
|
||||
|
@ -25,6 +25,10 @@ public:
|
||||
wxQtAction( wxMenu *parent, int id, const wxString &text, const wxString &help,
|
||||
wxItemKind kind, wxMenu *subMenu, wxMenuItem *handler );
|
||||
|
||||
// Set the action shortcut to correspond to the accelerator specified by
|
||||
// the given label.
|
||||
void UpdateShortcutsFromLabel(const wxString& text);
|
||||
|
||||
private:
|
||||
void onActionTriggered( bool checked );
|
||||
};
|
||||
@ -51,6 +55,8 @@ void wxMenuItem::SetItemLabel( const wxString &label )
|
||||
{
|
||||
wxMenuItemBase::SetItemLabel( label );
|
||||
|
||||
m_qtAction->UpdateShortcutsFromLabel( label );
|
||||
|
||||
m_qtAction->setText( wxQtConvertString( label ));
|
||||
}
|
||||
|
||||
@ -161,8 +167,20 @@ wxQtAction::wxQtAction( wxMenu *parent, int id, const wxString &text, const wxSt
|
||||
}
|
||||
|
||||
connect( this, &QAction::triggered, this, &wxQtAction::onActionTriggered );
|
||||
|
||||
UpdateShortcutsFromLabel( text );
|
||||
}
|
||||
|
||||
void wxQtAction::UpdateShortcutsFromLabel(const wxString& text)
|
||||
{
|
||||
#if wxUSE_ACCEL
|
||||
const wxString accelStr = text.AfterFirst('\t');
|
||||
if ( !accelStr.empty() )
|
||||
{
|
||||
setShortcut( QKeySequence( wxQtConvertString(accelStr) ) );
|
||||
}
|
||||
#endif // wxUSE_ACCEL
|
||||
}
|
||||
|
||||
void wxQtAction::onActionTriggered( bool checked )
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "wx/qt/private/winevent.h"
|
||||
|
||||
#include <QtWidgets/QTabWidget>
|
||||
#include <QtWidgets/QTabBar>
|
||||
|
||||
class wxQtTabWidget : public wxQtEventSignalHandler< QTabWidget, wxNotebook >
|
||||
{
|
||||
@ -162,7 +163,10 @@ bool wxNotebook::InsertPage(size_t n, wxWindow *page, const wxString& text,
|
||||
|
||||
wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
|
||||
{
|
||||
return sizePage;
|
||||
QTabBar *tabBar = m_qtTabWidget->tabBar();
|
||||
const QSize &tabBarSize = tabBar->size();
|
||||
return wxSize(sizePage.GetWidth(),
|
||||
sizePage.GetHeight() + tabBarSize.height());
|
||||
}
|
||||
|
||||
bool wxNotebook::DeleteAllPages()
|
||||
@ -192,8 +196,8 @@ int wxNotebook::SetSelection(size_t page)
|
||||
int selOld = GetSelection();
|
||||
|
||||
// change the QTabWidget selected page:
|
||||
m_selection = page;
|
||||
m_qtTabWidget->setCurrentIndex( page );
|
||||
m_selection = page;
|
||||
|
||||
return selOld;
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ bool wxSlider::Create(wxWindow *parent,
|
||||
m_qtSlider->blockSignals(true);
|
||||
SetRange( minValue, maxValue );
|
||||
m_qtSlider->blockSignals(false);
|
||||
SetPageSize(wxMax(1, (maxValue - minValue) / 10));
|
||||
|
||||
#if 0 // there are not normally ticks for a wxSlider
|
||||
// draw ticks marks (default bellow if horizontal, right if vertical):
|
||||
|
@ -47,7 +47,6 @@ bool wxStaticText::Create(wxWindow *parent,
|
||||
const wxString &name)
|
||||
{
|
||||
m_qtLabel = new wxQtStaticText( parent, this );
|
||||
m_qtLabel->setText( wxQtConvertString( label ) );
|
||||
|
||||
// Set the buddy to itself to get the mnemonic key but ensure that we don't have
|
||||
// any unwanted side effects, so disable the interaction:
|
||||
@ -64,7 +63,12 @@ bool wxStaticText::Create(wxWindow *parent,
|
||||
else
|
||||
m_qtLabel->setAlignment(Qt::AlignLeft);
|
||||
|
||||
return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name );
|
||||
if ( !QtCreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
|
||||
return false;
|
||||
|
||||
SetLabel(label);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxStaticText::SetLabel(const wxString& label)
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <QtWidgets/QTreeWidget>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
namespace
|
||||
@ -142,6 +143,8 @@ public:
|
||||
this, &wxQTreeWidget::OnItemCollapsed);
|
||||
connect(this, &QTreeWidget::itemExpanded,
|
||||
this, &wxQTreeWidget::OnItemExpanded);
|
||||
connect(verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
this, &wxQTreeWidget::OnTreeScrolled);
|
||||
|
||||
setItemDelegate(&m_item_delegate);
|
||||
setDragEnabled(true);
|
||||
@ -244,6 +247,12 @@ public:
|
||||
return m_placeHolderImage;
|
||||
}
|
||||
|
||||
void select(QTreeWidgetItem* item, QItemSelectionModel::SelectionFlag selectionFlag)
|
||||
{
|
||||
const QModelIndex &index = indexFromItem(item);
|
||||
selectionModel()->select(index, selectionFlag);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void drawRow(
|
||||
QPainter *painter,
|
||||
@ -432,6 +441,12 @@ private:
|
||||
EmitEvent(expandedEvent);
|
||||
}
|
||||
|
||||
void OnTreeScrolled(int)
|
||||
{
|
||||
if ( GetEditControl() != NULL )
|
||||
closeEditor(GetEditControl()->GetHandle(), QAbstractItemDelegate::RevertModelCache);
|
||||
}
|
||||
|
||||
void tryStartDrag(const QMouseEvent *event)
|
||||
{
|
||||
wxEventType command = event->buttons() & Qt::RightButton
|
||||
@ -448,14 +463,14 @@ private:
|
||||
|
||||
tree_event.SetPoint(wxQtConvertPoint(event->pos()));
|
||||
|
||||
// Vetoed unless explicitly accepted.
|
||||
// Client must explicitly accept drag and drop. Vetoed by default.
|
||||
tree_event.Veto();
|
||||
|
||||
EmitEvent(tree_event);
|
||||
|
||||
if ( !tree_event.IsAllowed() )
|
||||
{
|
||||
setState(DragSelectingState);
|
||||
setState(NoState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1158,25 +1173,19 @@ void wxTreeCtrl::Toggle(const wxTreeItemId& item)
|
||||
wxCHECK_RET(item.IsOk(), "invalid tree item");
|
||||
|
||||
QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
|
||||
qTreeItem->setSelected(!qTreeItem->isSelected());
|
||||
qTreeItem->setExpanded(!qTreeItem->isExpanded());
|
||||
}
|
||||
|
||||
void wxTreeCtrl::Unselect()
|
||||
{
|
||||
QTreeWidgetItem *current = m_qtTreeWidget->currentItem();
|
||||
|
||||
if ( current != NULL )
|
||||
current->setSelected(false);
|
||||
m_qtTreeWidget->select(current, QItemSelectionModel::Deselect);
|
||||
}
|
||||
|
||||
void wxTreeCtrl::UnselectAll()
|
||||
{
|
||||
QList<QTreeWidgetItem *> selections = m_qtTreeWidget->selectedItems();
|
||||
const size_t selectedCount = selections.size();
|
||||
for ( size_t i = 0; i < selectedCount; ++i)
|
||||
{
|
||||
selections[i]->setSelected(false);
|
||||
}
|
||||
m_qtTreeWidget->selectionModel()->clearSelection();
|
||||
}
|
||||
|
||||
void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select)
|
||||
@ -1189,7 +1198,15 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select)
|
||||
}
|
||||
|
||||
QTreeWidgetItem *qTreeItem = wxQtConvertTreeItem(item);
|
||||
qTreeItem->setSelected(select);
|
||||
|
||||
if ( qTreeItem )
|
||||
{
|
||||
m_qtTreeWidget->select(qTreeItem, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
|
||||
if ( select && m_qtTreeWidget->selectionMode() == QTreeWidget::SingleSelection )
|
||||
{
|
||||
m_qtTreeWidget->setCurrentItem(qTreeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent)
|
||||
@ -1201,7 +1218,7 @@ void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent)
|
||||
|
||||
for ( int i = 0; i < childCount; ++i )
|
||||
{
|
||||
qTreeItem->child(i)->setSelected(true);
|
||||
m_qtTreeWidget->select(qTreeItem->child(i), QItemSelectionModel::Select);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,9 +59,10 @@ wxQtWidget::wxQtWidget( wxWindowQt *parent, wxWindowQt *handler )
|
||||
|
||||
class wxQtScrollArea : public wxQtEventSignalHandler< QScrollArea, wxWindowQt >
|
||||
{
|
||||
public:
|
||||
wxQtScrollArea(wxWindowQt *parent, wxWindowQt *handler);
|
||||
|
||||
public:
|
||||
wxQtScrollArea( wxWindowQt *parent, wxWindowQt *handler );
|
||||
bool event(QEvent *e) wxOVERRIDE;
|
||||
};
|
||||
|
||||
wxQtScrollArea::wxQtScrollArea( wxWindowQt *parent, wxWindowQt *handler )
|
||||
@ -69,6 +70,27 @@ wxQtScrollArea::wxQtScrollArea( wxWindowQt *parent, wxWindowQt *handler )
|
||||
{
|
||||
}
|
||||
|
||||
bool wxQtScrollArea::event(QEvent *e)
|
||||
{
|
||||
wxWindowQt* handler = GetHandler();
|
||||
if ( handler && handler->HasCapture() )
|
||||
{
|
||||
switch ( e->type() )
|
||||
{
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseButtonDblClick:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::Wheel:
|
||||
case QEvent::TouchUpdate:
|
||||
case QEvent::TouchEnd:
|
||||
return viewportEvent(e);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QScrollArea::event(e);
|
||||
}
|
||||
|
||||
class wxQtInternalScrollBar : public wxQtEventSignalHandler< QScrollBar, wxWindowQt >
|
||||
{
|
||||
public:
|
||||
@ -193,6 +215,30 @@ static const char WINDOW_POINTER_PROPERTY_NAME[] = "wxWindowPointer";
|
||||
return const_cast< wxWindowQt * >( ( variant.value< const wxWindow * >() ));
|
||||
}
|
||||
|
||||
/* static */
|
||||
void wxWindowQt::QtSendSetCursorEvent(wxWindowQt* win, wxPoint posScreen)
|
||||
{
|
||||
wxWindowQt* w = win;
|
||||
for ( ;; )
|
||||
{
|
||||
const wxPoint posClient = w->ScreenToClient(posScreen);
|
||||
wxSetCursorEvent event(posClient.x, posClient.y);
|
||||
event.SetEventObject(w);
|
||||
|
||||
const bool processedEvtSetCursor = w->ProcessWindowEvent(event);
|
||||
if ( processedEvtSetCursor && event.HasCursor() )
|
||||
{
|
||||
win->SetCursor(event.GetCursor());
|
||||
return;
|
||||
}
|
||||
|
||||
w = w->GetParent();
|
||||
if ( w == NULL )
|
||||
break;
|
||||
}
|
||||
win->SetCursor(wxCursor(wxCURSOR_ARROW));
|
||||
}
|
||||
|
||||
static wxWindowQt *s_capturedWindow = NULL;
|
||||
|
||||
/* static */ wxWindowQt *wxWindowBase::DoFindFocus()
|
||||
@ -297,8 +343,6 @@ bool wxWindowQt::Create( wxWindowQt * parent, wxWindowID id, const wxPoint & pos
|
||||
m_qtWindow = new wxQtWidget( parent, this );
|
||||
}
|
||||
|
||||
|
||||
GetHandle()->setMouseTracking(true);
|
||||
if ( !wxWindowBase::CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
|
||||
return false;
|
||||
|
||||
@ -437,7 +481,7 @@ bool wxWindowQt::Reparent( wxWindowBase *parent )
|
||||
if ( !wxWindowBase::Reparent( parent ))
|
||||
return false;
|
||||
|
||||
QtReparent( GetHandle(), parent->GetHandle() );
|
||||
QtReparent( GetHandle(), static_cast<wxWindow*>(parent)->QtGetParentWidget() );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -560,6 +604,23 @@ void wxWindowQt::DoGetTextExtent(const wxString& string, int *x, int *y, int *de
|
||||
*externalLeading = fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
QWidget *wxWindowQt::QtGetClientWidget() const
|
||||
{
|
||||
QWidget *qtWidget = NULL;
|
||||
if ( m_qtContainer != NULL )
|
||||
{
|
||||
qtWidget = m_qtContainer->viewport();
|
||||
}
|
||||
|
||||
if ( qtWidget == NULL )
|
||||
{
|
||||
// We don't have scrollbars or the QScrollArea has no children
|
||||
qtWidget = GetHandle();
|
||||
}
|
||||
|
||||
return qtWidget;
|
||||
}
|
||||
|
||||
/* Returns a scrollbar for the given orientation, or NULL if the scrollbar
|
||||
* has not been previously created and create is false */
|
||||
QScrollBar *wxWindowQt::QtGetScrollBar( int orientation ) const
|
||||
@ -935,7 +996,10 @@ void wxWindowQt::DoSetSize(int x, int y, int width, int height, int sizeFlags )
|
||||
|
||||
void wxWindowQt::DoGetClientSize(int *width, int *height) const
|
||||
{
|
||||
QRect geometry = GetHandle()->geometry();
|
||||
QWidget *qtWidget = QtGetClientWidget();
|
||||
wxCHECK_RET( qtWidget, "window must be created" );
|
||||
|
||||
const QRect geometry = qtWidget->geometry();
|
||||
if (width) *width = geometry.width();
|
||||
if (height) *height = geometry.height();
|
||||
}
|
||||
@ -943,7 +1007,9 @@ void wxWindowQt::DoGetClientSize(int *width, int *height) const
|
||||
|
||||
void wxWindowQt::DoSetClientSize(int width, int height)
|
||||
{
|
||||
QWidget *qtWidget = GetHandle();
|
||||
QWidget *qtWidget = QtGetClientWidget();
|
||||
wxCHECK_RET( qtWidget, "window must be created" );
|
||||
|
||||
QRect geometry = qtWidget->geometry();
|
||||
geometry.setWidth( width );
|
||||
geometry.setHeight( height );
|
||||
@ -955,9 +1021,19 @@ void wxWindowQt::DoMoveWindow(int x, int y, int width, int height)
|
||||
QWidget *qtWidget = GetHandle();
|
||||
|
||||
qtWidget->move( x, y );
|
||||
qtWidget->resize( width, height );
|
||||
}
|
||||
|
||||
// There doesn't seem to be any way to change Qt frame size directly, so
|
||||
// change the widget size, but take into account the extra margins
|
||||
// corresponding to the frame decorations.
|
||||
const QSize frameSize = qtWidget->frameSize();
|
||||
const QSize innerSize = qtWidget->geometry().size();
|
||||
const QSize frameSizeDiff = frameSize - innerSize;
|
||||
|
||||
const int clientWidth = std::max(width - frameSizeDiff.width(), 0);
|
||||
const int clientHeight = std::max(height - frameSizeDiff.height(), 0);
|
||||
|
||||
qtWidget->resize(clientWidth, clientHeight);
|
||||
}
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
void wxWindowQt::QtApplyToolTip(const wxString& text)
|
||||
@ -983,9 +1059,10 @@ void wxWindowQt::DoSetToolTip( wxToolTip *tip )
|
||||
#if wxUSE_MENUS
|
||||
bool wxWindowQt::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||
{
|
||||
menu->UpdateUI();
|
||||
menu->GetHandle()->exec( GetHandle()->mapToGlobal( QPoint( x, y ) ) );
|
||||
|
||||
return ( true );
|
||||
return true;
|
||||
}
|
||||
#endif // wxUSE_MENUS
|
||||
|
||||
@ -1424,11 +1501,15 @@ bool wxWindowQt::QtHandleMouseEvent ( QWidget *handler, QMouseEvent *event )
|
||||
}
|
||||
|
||||
// Fill the event
|
||||
QPoint mousePos = event->pos();
|
||||
|
||||
// Use screen position as the event might originate from a different
|
||||
// Qt window than this one.
|
||||
wxPoint mousePos = ScreenToClient(wxQtConvertPoint(event->globalPos()));
|
||||
|
||||
wxMouseEvent e( wxType );
|
||||
e.SetEventObject(this);
|
||||
e.m_clickCount = -1;
|
||||
e.SetPosition( wxQtConvertPoint( mousePos ) );
|
||||
e.SetPosition(mousePos);
|
||||
|
||||
// Mouse buttons
|
||||
wxQtFillMouseButtons( event->buttons(), &e );
|
||||
@ -1440,8 +1521,8 @@ bool wxWindowQt::QtHandleMouseEvent ( QWidget *handler, QMouseEvent *event )
|
||||
|
||||
// Determine if mouse is inside the widget
|
||||
bool mouseInside = true;
|
||||
if ( mousePos.x() < 0 || mousePos.x() > handler->width() ||
|
||||
mousePos.y() < 0 || mousePos.y() > handler->height() )
|
||||
if ( mousePos.x < 0 || mousePos.x > handler->width() ||
|
||||
mousePos.y < 0 || mousePos.y > handler->height() )
|
||||
mouseInside = false;
|
||||
|
||||
if ( e.GetEventType() == wxEVT_MOTION )
|
||||
@ -1460,6 +1541,8 @@ bool wxWindowQt::QtHandleMouseEvent ( QWidget *handler, QMouseEvent *event )
|
||||
|
||||
ProcessWindowEvent( e );
|
||||
}
|
||||
|
||||
QtSendSetCursorEvent(this, wxQtConvertPoint( event->globalPos()));
|
||||
}
|
||||
|
||||
m_mouseInside = mouseInside;
|
||||
@ -1521,18 +1604,27 @@ bool wxWindowQt::QtHandleChangeEvent ( QWidget *handler, QEvent *event )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the closing should be vetoed and false if the window should be closed.
|
||||
bool wxWindowQt::QtHandleCloseEvent ( QWidget *handler, QCloseEvent *WXUNUSED( event ) )
|
||||
{
|
||||
if ( GetHandle() != handler )
|
||||
return false;
|
||||
|
||||
return Close();
|
||||
// This is required as Qt will still send out close events when the window is disabled.
|
||||
if ( !IsEnabled() )
|
||||
return true;
|
||||
|
||||
return !Close();
|
||||
}
|
||||
|
||||
bool wxWindowQt::QtHandleContextMenuEvent ( QWidget *WXUNUSED( handler ), QContextMenuEvent *event )
|
||||
{
|
||||
wxContextMenuEvent e( wxEVT_CONTEXT_MENU, GetId() );
|
||||
e.SetPosition( wxQtConvertPoint( event->globalPos() ) );
|
||||
e.SetPosition(
|
||||
event->reason() == QContextMenuEvent::Keyboard
|
||||
? wxDefaultPosition
|
||||
: wxQtConvertPoint( event->globalPos() )
|
||||
);
|
||||
e.SetEventObject(this);
|
||||
|
||||
return ProcessWindowEvent( e );
|
||||
|
@ -21,78 +21,36 @@
|
||||
#include "wx/window.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "wx/scopedptr.h"
|
||||
|
||||
class ClientSizeTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
ClientSizeTestCase() { }
|
||||
|
||||
virtual void setUp() wxOVERRIDE;
|
||||
virtual void tearDown() wxOVERRIDE;
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( ClientSizeTestCase );
|
||||
CPPUNIT_TEST( ClientToWindow );
|
||||
CPPUNIT_TEST( ClientSizeNotNegative );
|
||||
CPPUNIT_TEST( WindowToClient );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void ClientToWindow();
|
||||
void ClientSizeNotNegative();
|
||||
void WindowToClient();
|
||||
|
||||
wxWindow *m_win;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(ClientSizeTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( ClientSizeTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClientSizeTestCase, "ClientSizeTestCase" );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test initialization
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ClientSizeTestCase::setUp()
|
||||
{
|
||||
m_win = wxTheApp->GetTopWindow();
|
||||
}
|
||||
|
||||
void ClientSizeTestCase::tearDown()
|
||||
{
|
||||
m_win = NULL;
|
||||
}
|
||||
#include "asserthelper.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ClientSizeTestCase::ClientToWindow()
|
||||
TEST_CASE("wxWindow::ClientWindowSizeRoundTrip", "[window][client-size]")
|
||||
{
|
||||
CPPUNIT_ASSERT(m_win->GetSize() ==
|
||||
m_win->ClientToWindowSize(m_win->GetClientSize()));
|
||||
wxWindow* const w = wxTheApp->GetTopWindow();
|
||||
REQUIRE( w );
|
||||
|
||||
const wxSize sizeWindow = w->GetSize();
|
||||
const wxSize sizeClient = w->GetClientSize();
|
||||
|
||||
INFO("client size: " << sizeClient);
|
||||
CHECK( sizeWindow == w->ClientToWindowSize(sizeClient) );
|
||||
|
||||
INFO("window size: " << sizeWindow);
|
||||
CHECK( sizeClient == w->WindowToClientSize(sizeWindow) );
|
||||
}
|
||||
|
||||
void ClientSizeTestCase::ClientSizeNotNegative()
|
||||
TEST_CASE("wxWindow::MinClientSize", "[window][client-size]")
|
||||
{
|
||||
wxWindow* w = new wxWindow(wxTheApp->GetTopWindow(), -1,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxBORDER_THEME);
|
||||
wxScopedPtr<wxWindow> w(new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxBORDER_THEME));
|
||||
w->SetSize(wxSize(1,1));
|
||||
const wxSize szw = w->GetClientSize();
|
||||
CPPUNIT_ASSERT(szw.GetWidth() >= 0);
|
||||
CPPUNIT_ASSERT(szw.GetHeight() >= 0);
|
||||
w->Destroy();
|
||||
}
|
||||
|
||||
void ClientSizeTestCase::WindowToClient()
|
||||
{
|
||||
CPPUNIT_ASSERT(m_win->GetClientSize() ==
|
||||
m_win->WindowToClientSize(m_win->GetSize()));
|
||||
CHECK(szw.GetWidth() >= 0);
|
||||
CHECK(szw.GetHeight() >= 0);
|
||||
}
|
||||
|
@ -18,100 +18,136 @@
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/frame.h"
|
||||
#include "wx/window.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/scopedptr.h"
|
||||
#include "wx/stopwatch.h"
|
||||
|
||||
#include "asserthelper.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// tests helpers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class SetSizeTestCase : public CppUnit::TestCase
|
||||
namespace
|
||||
{
|
||||
|
||||
// Helper class overriding DoGetBestSize() for testing purposes.
|
||||
class MyWindow : public wxWindow
|
||||
{
|
||||
public:
|
||||
SetSizeTestCase() { }
|
||||
|
||||
virtual void setUp() wxOVERRIDE;
|
||||
virtual void tearDown() wxOVERRIDE;
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( SetSizeTestCase );
|
||||
CPPUNIT_TEST( SetSize );
|
||||
CPPUNIT_TEST( SetSizeLessThanMinSize );
|
||||
CPPUNIT_TEST( BestSize );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void SetSize();
|
||||
void SetSizeLessThanMinSize();
|
||||
void BestSize();
|
||||
|
||||
// Helper class overriding DoGetBestSize() for testing purposes.
|
||||
class MyWindow : public wxWindow
|
||||
MyWindow(wxWindow* parent)
|
||||
: wxWindow(parent, wxID_ANY)
|
||||
{
|
||||
public:
|
||||
MyWindow(wxWindow* parent)
|
||||
: wxWindow(parent, wxID_ANY)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual wxSize DoGetBestSize() const wxOVERRIDE { return wxSize(50, 250); }
|
||||
};
|
||||
|
||||
wxWindow *m_win;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(SetSizeTestCase);
|
||||
protected:
|
||||
virtual wxSize DoGetBestSize() const wxOVERRIDE { return wxSize(50, 250); }
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( SetSizeTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SetSizeTestCase, "SetSizeTestCase" );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test initialization
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void SetSizeTestCase::setUp()
|
||||
// Class used to check if we received the (first) paint event.
|
||||
class WaitForPaint
|
||||
{
|
||||
m_win = new MyWindow(wxTheApp->GetTopWindow());
|
||||
public:
|
||||
// Note that we have to use a pointer here, i.e. we can't just store the
|
||||
// flag inside the class itself because it's going to be cloned inside wx
|
||||
// and querying the flag of the original copy is not going to work.
|
||||
explicit WaitForPaint(bool* painted)
|
||||
: m_painted(*painted)
|
||||
{
|
||||
m_painted = false;
|
||||
}
|
||||
|
||||
void operator()(wxPaintEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
m_painted = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool& m_painted;
|
||||
};
|
||||
|
||||
// This function should be used to show the window and wait until we can get
|
||||
// its real geometry.
|
||||
void ShowAndWaitForPaint(wxWindow* w)
|
||||
{
|
||||
// Unfortunately showing the window is asynchronous, at least when using
|
||||
// X11, so we have to wait for some time before retrieving its true
|
||||
// geometry. And it's not clear how long should we wait, so we do it until
|
||||
// we get the first paint event -- by then the window really should have
|
||||
// its final size.
|
||||
bool painted;
|
||||
WaitForPaint waitForPaint(&painted);
|
||||
w->Bind(wxEVT_PAINT, waitForPaint);
|
||||
|
||||
w->Show();
|
||||
|
||||
wxStopWatch sw;
|
||||
while ( !painted )
|
||||
{
|
||||
wxYield();
|
||||
|
||||
if ( sw.Time() > 250 )
|
||||
{
|
||||
WARN("Didn't get a paint event until timeout expiration");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetSizeTestCase::tearDown()
|
||||
{
|
||||
delete m_win;
|
||||
m_win = NULL;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void SetSizeTestCase::SetSize()
|
||||
TEST_CASE("wxWindow::SetSize", "[window][size]")
|
||||
{
|
||||
const wxSize size(127, 35);
|
||||
m_win->SetSize(size);
|
||||
CPPUNIT_ASSERT_EQUAL( size, m_win->GetSize() );
|
||||
wxScopedPtr<wxWindow> w(new MyWindow(wxTheApp->GetTopWindow()));
|
||||
|
||||
SECTION("Simple")
|
||||
{
|
||||
const wxSize size(127, 35);
|
||||
w->SetSize(size);
|
||||
CHECK( size == w->GetSize() );
|
||||
}
|
||||
|
||||
SECTION("With min size")
|
||||
{
|
||||
w->SetMinSize(wxSize(100, 100));
|
||||
|
||||
const wxSize size(200, 50);
|
||||
w->SetSize(size);
|
||||
CHECK( size == w->GetSize() );
|
||||
}
|
||||
}
|
||||
|
||||
void SetSizeTestCase::SetSizeLessThanMinSize()
|
||||
TEST_CASE("wxWindow::GetBestSize", "[window][size][best-size]")
|
||||
{
|
||||
m_win->SetMinSize(wxSize(100, 100));
|
||||
wxScopedPtr<wxWindow> w(new MyWindow(wxTheApp->GetTopWindow()));
|
||||
|
||||
const wxSize size(200, 50);
|
||||
m_win->SetSize(size);
|
||||
CPPUNIT_ASSERT_EQUAL( size, m_win->GetSize() );
|
||||
CHECK( wxSize(50, 250) == w->GetBestSize() );
|
||||
|
||||
w->SetMinSize(wxSize(100, 100));
|
||||
CHECK( wxSize(100, 250) == w->GetBestSize() );
|
||||
|
||||
w->SetMaxSize(wxSize(200, 200));
|
||||
CHECK( wxSize(100, 200) == w->GetBestSize() );
|
||||
}
|
||||
|
||||
void SetSizeTestCase::BestSize()
|
||||
TEST_CASE("wxWindow::MovePreservesSize", "[window][size][move]")
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL( wxSize(50, 250), m_win->GetBestSize() );
|
||||
wxScopedPtr<wxWindow>
|
||||
w(new wxFrame(wxTheApp->GetTopWindow(), wxID_ANY, "Test child frame"));
|
||||
|
||||
m_win->SetMinSize(wxSize(100, 100));
|
||||
CPPUNIT_ASSERT_EQUAL( wxSize(100, 250), m_win->GetBestSize() );
|
||||
ShowAndWaitForPaint(w.get());
|
||||
|
||||
m_win->SetMaxSize(wxSize(200, 200));
|
||||
CPPUNIT_ASSERT_EQUAL( wxSize(100, 200), m_win->GetBestSize() );
|
||||
const wxRect rectOrig = w->GetRect();
|
||||
|
||||
// Check that moving the window doesn't change its size.
|
||||
w->Move(rectOrig.GetPosition() + wxPoint(100, 100));
|
||||
CHECK( w->GetSize() == rectOrig.GetSize() );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user