gambas-source-code/gb.qt4/src/CButton.cpp
Benoît Minisini 0b478e2d81 [GB.QT4]
* BUG: Newly created ToolButton does not resize its parent unexpectedly 
  anymore.
  
[GB.QT5]
* BUG: Newly created ToolButton does not resize its parent unexpectedly 
  anymore.


git-svn-id: svn://localhost/gambas/trunk@7215 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2015-08-01 16:44:06 +00:00

685 lines
14 KiB
C++

/***************************************************************************
CButton.cpp
(c) 2000-2013 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#define __CBUTTON_CPP
#include <qapplication.h>
#include <qevent.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qsizepolicy.h>
#include <qicon.h>
#include <qlayout.h>
#include <qobject.h>
//Added by qt3to4:
#include <QResizeEvent>
#include <QPixmap>
#include <QStylePainter>
#include <QStyleOptionToolButton>
#include "gambas.h"
#include "CWidget.h"
#include "CPicture.h"
#include "CWindow.h"
#include "CButton.h"
/*#define DEBUG_CBUTTON*/
DECLARE_EVENT(EVENT_Click);
DECLARE_EVENT(EVENT_ClickToggle);
DECLARE_EVENT(EVENT_ClickTool);
//---------------------------------------------------------------------------
static void set_button_text(CBUTTON *_object, const QString &text)
{
WIDGET->setText(text);
WIDGET->calcMinimumSize();
}
static void set_button_picture(CBUTTON *_object)
{
QPixmap p;
QIcon icon;
if (THIS->picture)
{
p = *(THIS->picture->pixmap);
CWIDGET_iconset(icon, p);
WIDGET->setIcon(icon);
WIDGET->setIconSize(p.size());
}
else
{
WIDGET->setIcon(icon);
}
WIDGET->calcMinimumSize();
}
static void set_tool_button(CBUTTON *_object, bool set_text, QString text)
{
QPixmap p;
QIcon icon;
if (!set_text)
text = WIDGET_TOOL->text();
if (THIS->picture)
{
p = *(THIS->picture->pixmap);
WIDGET_TOOL->setText(text);
CWIDGET_iconset(icon, p);
WIDGET_TOOL->setIcon(icon);
WIDGET->setIconSize(p.size());
//WIDGET_TOOL->setUsesTextLabel(qtext.length() > 0);
if (text.length())
WIDGET_TOOL->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
else
WIDGET_TOOL->setToolButtonStyle(Qt::ToolButtonIconOnly);
}
else
{
WIDGET_TOOL->setIcon(icon);
WIDGET_TOOL->setText(text);
WIDGET_TOOL->setToolButtonStyle(Qt::ToolButtonTextOnly);
//WIDGET_TOOL->setUsesTextLabel(qtext.length() > 0);
}
WIDGET->calcMinimumSize();
}
//---------------------------------------------------------------------------
BEGIN_METHOD(CBUTTON_new, GB_OBJECT parent)
MyPushButton *wid = new MyPushButton(QCONTAINER(VARG(parent)));
QObject::connect(wid, SIGNAL(clicked()), &CButton::manager, SLOT(clicked()));
wid->setAutoDefault(false);
CWIDGET_new(wid, (void *)_object);
// We assume that the button widget destructor will always be called before
// its gambas window is released.
WIDGET->top = CWidget::getWindow((CWIDGET *)THIS);
END_METHOD
BEGIN_METHOD(CTOGGLEBUTTON_new, GB_OBJECT parent)
QPushButton *wid = new MyPushButton(QCONTAINER(VARG(parent)));
QObject::connect(wid, SIGNAL(toggled(bool)), &CButton::manager, SLOT(clickedToggle()));
//wid->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
wid->setAutoDefault(false);
wid->setCheckable(TRUE);
CWIDGET_new(wid, (void *)_object);
END_METHOD
BEGIN_METHOD(CTOOLBUTTON_new, GB_OBJECT parent)
MyToolButton *wid = new MyToolButton(QCONTAINER(VARG(parent)));
QObject::connect(wid, SIGNAL(clicked()), &CButton::manager, SLOT(clickedTool()));
//wid->setToggleButton(TRUE);
wid->setAutoRaise(true);
CWIDGET_new(wid, (void *)_object);
wid->calcMinimumSize();
END_METHOD
BEGIN_METHOD_VOID(CBUTTON_free)
CLEAR_PICTURE(&(OBJECT(CBUTTON)->picture));
END_METHOD
BEGIN_PROPERTY(CBUTTON_text)
if (READ_PROPERTY)
RETURN_NEW_STRING(WIDGET->text());
else
set_button_text(THIS, QSTRING_PROP());
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_picture)
if (READ_PROPERTY)
GB.ReturnObject(THIS->picture);
else
{
GB.StoreObject(PROP(GB_OBJECT), POINTER(&(THIS->picture)));
set_button_picture(THIS);
}
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_text)
if (READ_PROPERTY)
RETURN_NEW_STRING(WIDGET->text());
else
set_tool_button(THIS, true, QSTRING_PROP());
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_picture)
if (READ_PROPERTY)
GB.ReturnObject(THIS->picture);
else
{
GB.StoreObject(PROP(GB_OBJECT), POINTER(&(THIS->picture)));
set_tool_button(THIS, false, QString());
}
END_PROPERTY
/*
BEGIN_PROPERTY(CTOOLBUTTON_picture)
QToolButton *wid = QTOOLBUTTON(_object);
char **pict = (char **)&(OBJECT(CBUTTON)->picture);
if (READ_PROPERTY)
GB.ReturnString(*pict, 0);
else
wid->setIconSet(QIconSet(*PIXMAP_set_widget(PROPERTY(GB_STRING), pict), QIconSet::Small));
END_PROPERTY
*/
BEGIN_PROPERTY(CBUTTON_value)
if (READ_PROPERTY)
GB.ReturnBoolean(0);
else if (VPROP(GB_BOOLEAN))
WIDGET->animateClick();
END_PROPERTY
BEGIN_PROPERTY(CTOGGLEBUTTON_value)
if (READ_PROPERTY)
GB.ReturnBoolean(WIDGET->isChecked());
else
WIDGET->setChecked(VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_value)
if (READ_PROPERTY)
GB.ReturnBoolean(WIDGET_TOOL->isChecked());
else
{
if (WIDGET->isCheckable())
WIDGET_TOOL->setChecked(VPROP(GB_BOOLEAN));
else
WIDGET->animateClick();
//qApp->postEvent(WIDGET_TOOL, new QEvent(QEvent::Leave));
}
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_flat)
if (READ_PROPERTY)
GB.ReturnBoolean(WIDGET->isFlat());
else
WIDGET->setFlat(VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_border)
if (READ_PROPERTY)
GB.ReturnBoolean(!WIDGET->isFlat());
else
WIDGET->setFlat(!VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_border)
if (READ_PROPERTY)
GB.ReturnBoolean(!WIDGET_TOOL->autoRaise());
else
WIDGET_TOOL->setAutoRaise(!VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_toggle)
if (READ_PROPERTY)
GB.ReturnBoolean(WIDGET_TOOL->isCheckable());
else
{
WIDGET_TOOL->setCheckable(VPROP(GB_BOOLEAN));
QObject::disconnect(WIDGET_TOOL, 0, &CButton::manager, 0);
if (VPROP(GB_BOOLEAN))
QObject::connect(WIDGET_TOOL, SIGNAL(toggled(bool)), &CButton::manager, SLOT(clickedTool()));
else
QObject::connect(WIDGET_TOOL, SIGNAL(clicked()), &CButton::manager, SLOT(clickedTool()));
}
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_default)
CWINDOW *top = CWidget::getWindow((CWIDGET *)THIS);
if (READ_PROPERTY)
GB.ReturnBoolean(top->defaultButton == WIDGET);
else
CWINDOW_set_default_button(top, WIDGET, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_cancel)
CWINDOW *top = CWidget::getWindow((CWIDGET *)THIS);
if (READ_PROPERTY)
GB.ReturnBoolean(top->cancelButton == WIDGET);
else
CWINDOW_set_cancel_button(top, WIDGET, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_radio)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->radio);
else
THIS->radio = VPROP(GB_BOOLEAN);
END_PROPERTY
BEGIN_PROPERTY(CBUTTON_autoresize)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->autoresize);
else if (THIS->autoresize != VPROP(GB_BOOLEAN))
{
THIS->autoresize = VPROP(GB_BOOLEAN);
WIDGET->calcMinimumSize();
}
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_autoresize)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->autoresize);
else if (THIS->autoresize != VPROP(GB_BOOLEAN))
{
THIS->autoresize = VPROP(GB_BOOLEAN);
WIDGET_TOOL->calcMinimumSize();
}
END_PROPERTY
#if 0
BEGIN_PROPERTY(CBUTTON_stretch)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->stretch);
else if (THIS->stretch != VPROP(GB_BOOLEAN))
{
THIS->stretch = VPROP(GB_BOOLEAN);
set_button(THIS, NULL, true);
}
END_PROPERTY
BEGIN_PROPERTY(CTOOLBUTTON_stretch)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->stretch);
else if (THIS->stretch != VPROP(GB_BOOLEAN))
{
THIS->stretch = VPROP(GB_BOOLEAN);
set_tool_button(THIS, NULL, true);
}
END_PROPERTY
#endif
#define CTOGGLEBUTTON_free CBUTTON_free
#define CTOGGLEBUTTON_text CBUTTON_text
#define CTOGGLEBUTTON_picture CBUTTON_picture
#define CTOGGLEBUTTON_border CBUTTON_border
#define CTOGGLEBUTTON_radio CBUTTON_radio
#define CTOGGLEBUTTON_stretch CBUTTON_stretch
#define CTOOLBUTTON_free CBUTTON_free
#define CTOOLBUTTON_radio CBUTTON_radio
GB_DESC CButtonDesc[] =
{
GB_DECLARE("Button", sizeof(CBUTTON)), GB_INHERITS("Control"),
GB_METHOD("_new", NULL, CBUTTON_new, "(Parent)Container;"),
GB_METHOD("_free", NULL, CBUTTON_free, NULL),
GB_PROPERTY("Text", "s", CBUTTON_text),
GB_PROPERTY("Caption", "s", CBUTTON_text),
GB_PROPERTY("Picture", "Picture", CBUTTON_picture),
GB_PROPERTY("Border", "b", CBUTTON_border),
GB_PROPERTY("Default", "b", CBUTTON_default),
GB_PROPERTY("Cancel", "b", CBUTTON_cancel),
GB_PROPERTY("Value", "b", CBUTTON_value),
GB_PROPERTY("AutoResize", "b", CBUTTON_autoresize),
BUTTON_DESCRIPTION,
GB_EVENT("Click", NULL, NULL, &EVENT_Click),
GB_END_DECLARE
};
GB_DESC CToggleButtonDesc[] =
{
GB_DECLARE("ToggleButton", sizeof(CBUTTON)), GB_INHERITS("Control"),
GB_METHOD("_new", NULL, CTOGGLEBUTTON_new, "(Parent)Container;"),
GB_METHOD("_free", NULL, CTOGGLEBUTTON_free, NULL),
GB_PROPERTY("Text", "s", CTOGGLEBUTTON_text),
GB_PROPERTY("Caption", "s", CTOGGLEBUTTON_text),
GB_PROPERTY("Picture", "Picture", CTOGGLEBUTTON_picture),
GB_PROPERTY("Value", "b", CTOGGLEBUTTON_value),
//GB_PROPERTY("Flat", "b", CBUTTON_flat),
GB_PROPERTY("Border", "b", CTOGGLEBUTTON_border),
GB_PROPERTY("Radio", "b", CTOGGLEBUTTON_radio),
GB_PROPERTY("AutoResize", "b", CBUTTON_autoresize),
TOGGLEBUTTON_DESCRIPTION,
GB_EVENT("Click", NULL, NULL, &EVENT_ClickToggle),
GB_END_DECLARE
};
GB_DESC CToolButtonDesc[] =
{
GB_DECLARE("ToolButton", sizeof(CBUTTON)), GB_INHERITS("Control"),
GB_METHOD("_new", NULL, CTOOLBUTTON_new, "(Parent)Container;"),
GB_METHOD("_free", NULL, CTOOLBUTTON_free, NULL),
GB_PROPERTY("Text", "s", CTOOLBUTTON_text),
GB_PROPERTY("Caption", "s", CTOOLBUTTON_text),
GB_PROPERTY("Picture", "Picture", CTOOLBUTTON_picture),
GB_PROPERTY("Value", "b", CTOOLBUTTON_value),
GB_PROPERTY("Toggle", "b", CTOOLBUTTON_toggle),
GB_PROPERTY("Border", "b", CTOOLBUTTON_border),
GB_PROPERTY("Radio", "b", CTOOLBUTTON_radio),
GB_PROPERTY("AutoResize", "b", CTOOLBUTTON_autoresize),
TOOLBUTTON_DESCRIPTION,
GB_EVENT("Click", NULL, NULL, &EVENT_ClickTool),
GB_END_DECLARE
};
/** class MyPushButton *****************************************************/
MyPushButton::MyPushButton(QWidget *parent) :
QPushButton(parent)
{
calcMinimumSize();
top = 0;
}
MyPushButton::~MyPushButton()
{
if (top)
{
CWINDOW_set_default_button(top, this, false);
CWINDOW_set_cancel_button(top, this, false);
}
}
/*QSize MyPushButton::sizeHint(void) const
{
return QSize(width(), height());
}*/
void MyPushButton::changeEvent(QEvent *e)
{
QPushButton::changeEvent(e);
if (e->type() == QEvent::FontChange || e->type() == QEvent::StyleChange)
calcMinimumSize();
}
void MyPushButton::calcMinimumSize()
{
CBUTTON *_object = (CBUTTON *)CWidget::getReal(this);
QSize size;
if (!THIS || CWIDGET_test_flag(THIS, WF_DESIGN))
return;
if (text().length() > 0)
{
QFontMetrics fm = fontMetrics();
setMinimumHeight(fm.lineSpacing() + 4);
}
else
setMinimumHeight(0);
setMinimumWidth(0);
if (THIS->autoresize)
{
size = sizeHint();
CWIDGET_resize(THIS, size.width(), height());
setMinimumWidth(size.width());
}
//qDebug("%p: %s: %d", this, text().latin1(), minimumHeight());
}
/*void MyPushButton::resizeEvent(QResizeEvent *e)
{
set_button((CBUTTON *)CWidget::get(this), NULL, true);
}*/
/*void MyPushButton::paintEvent(QPaintEvent *)
{
CBUTTON *_object = (CBUTTON *)CWidget::get(this);
QStylePainter p(this);
QStyleOptionToolButton opt;
initStyleOption(&opt);
if (THIS->picture)
opt.iconSize = THIS->picture->pixmap->size();
p.drawComplexControl(QStyle::CC_PushButton, opt);
}*/
/** class MyToolButton *****************************************************/
MyToolButton::MyToolButton(QWidget *parent) :
QToolButton(parent)
{
}
MyToolButton::~MyToolButton()
{
}
void MyToolButton::changeEvent(QEvent *e)
{
QToolButton::changeEvent(e);
if (e->type() == QEvent::FontChange || e->type() == QEvent::StyleChange)
calcMinimumSize();
}
void MyToolButton::calcMinimumSize()
{
CBUTTON *_object = (CBUTTON *)CWidget::get(this);
QSize size;
if (!THIS || CWIDGET_test_flag(THIS, WF_DESIGN))
return;
if (text().length() > 0)
{
QFontMetrics fm = fontMetrics();
setMinimumHeight(fm.lineSpacing() + 4);
}
else
setMinimumHeight(0);
setMinimumWidth(0);
if (THIS->autoresize)
{
size = sizeHint();
CWIDGET_resize(THIS, size.width(), height());
setMinimumWidth(size.width());
}
}
/*void MyToolButton::resizeEvent(QResizeEvent *e)
{
//set_tool_button((CBUTTON *)CWidget::get(this), NULL, true);
}*/
/*void MyToolButton::paintEvent(QPaintEvent *)
{
CBUTTON *_object = (CBUTTON *)CWidget::get(this);
QStylePainter p(this);
QStyleOptionToolButton opt;
initStyleOption(&opt);
if (THIS->picture)
opt.iconSize = THIS->picture->pixmap->size();
p.drawComplexControl(QStyle::CC_ToolButton, opt);
}*/
/* Class CButton */
CButton CButton::manager;
void CButton::onlyMe(CBUTTON *_object)
{
QWidget *parent = WIDGET->parentWidget();
QObjectList list = parent->children();
int i;
QObject *o;
CBUTTON *other;
for (i = 0; i < list.count(); i++)
{
o = list.at(i);
if (!o->isWidgetType())
continue;
other = (CBUTTON *)CWidget::get(o);
if (other == THIS)
continue;
if (other->widget.ob.klass != THIS->widget.ob.klass)
continue;
if (!other->radio)
continue;
o->blockSignals(true);
/*if (qobject_cast<MyPushButton *>(o))
((MyPushButton *)o)->setChecked(false);
else
((MyToolButton *)o)->setChecked(false);*/
(qobject_cast<QAbstractButton *>(o))->setChecked(false);
o->blockSignals(false);
}
}
void CButton::clicked(void)
{
RAISE_EVENT_ACTION(EVENT_Click);
}
void CButton::clickedToggle(void)
{
GET_SENDER();
if (THIS->radio)
{
if (WIDGET->isChecked())
onlyMe(THIS);
else
{
WIDGET->setChecked(true);
return;
}
}
RAISE_EVENT_ACTION(EVENT_ClickToggle);
}
void CButton::clickedTool(void)
{
GET_SENDER();
if (THIS->radio)
{
if (WIDGET_TOOL->isChecked())
onlyMe(THIS);
else
{
WIDGET_TOOL->setChecked(true);
return;
}
}
RAISE_EVENT_ACTION(EVENT_ClickTool);
}