/*************************************************************************** CListBox.cpp The ListBox class (c) 2000-2007 Benoit Minisini 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 1, 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 WIDGET program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************/ #define __CLISTBOX_CPP #include #include #include #include "gambas.h" #include "CWidget.h" #include "CPicture.h" #include "CDraw.h" #include "CListBox.h" #include "CConst.h" DECLARE_EVENT(EVENT_Select); /* selection change */ DECLARE_EVENT(EVENT_Click); /* simple click */ DECLARE_EVENT(EVENT_Activate); /* double click */ //DECLARE_EVENT(EVENT_Draw); static int _selection_mode[] = { SELECT_NONE, QListBox::NoSelection, SELECT_SINGLE, QListBox::Single, SELECT_MULTIPLE, QListBox::Extended, CONST_MAGIC }; BEGIN_METHOD(CLISTBOX_new, GB_OBJECT parent) QListBox *wid = new MyListBox(QCONTAINER(VARG(parent))); QObject::connect(wid, SIGNAL(selectionChanged()), &CListBox::manager, SLOT(selected())); QObject::connect(wid, SIGNAL(selected(int)), &CListBox::manager, SLOT(activated(int))); QObject::connect(wid, SIGNAL(highlighted(int)), &CListBox::manager, SLOT(highlighted(int))); QObject::connect(wid, SIGNAL(clicked(QListBoxItem *)), &CListBox::manager, SLOT(clicked(QListBoxItem *))); CWIDGET_new(wid, (void *)_object); THIS->sorted = false; THIS->last = -1; END_METHOD BEGIN_METHOD_VOID(CLISTBOX_clear) WIDGET->clear(); END_METHOD BEGIN_METHOD(CLISTBOX_get, GB_INTEGER index) int index = VARG(index); if (index < 0 || index >= (int)WIDGET->count()) { //qDebug("index = %ld", index); GB.Error("Bad index"); return; } THIS->index = index; RETURN_SELF(); END_METHOD /* BEGIN_METHOD(CLISTBOX_set, GB_STRING item; int index) int index = PARAM(index); int current; bool selected; if (index < 0 || index >= (int)WIDGET->count()) return; selected = WIDGET->isSelected(PARAM(index)); WIDGET->changeItem(QString(GB.ToZeroString(PARAM(item))), index); WIDGET->setSelected(index, selected); current = WIDGET->currentItem(); WIDGET->setCurrentItem(current); END_METHOD */ BEGIN_METHOD(CLISTBOX_add, GB_STRING item; GB_INTEGER pos) int pos = VARGOPT(pos, -1); //if (GB.IsMissing(2)) //WIDGET->blockSignals(true); WIDGET->insertItem(QSTRING_ARG(item), pos); if (THIS->sorted) WIDGET->sort(); //WIDGET->blockSignals(false); //else //{ //QLISTBOX(_object)->insertItem(PIXMAP_get(GB.ToZeroString(PARAM(picture))), // GB.ToZeroString(PARAM(item)), pos); //} //QLISTBOX(_object)->updateGeometry(); END_METHOD /* BEGIN_METHOD(CLISTBOX_add_custom, GB_INTEGER width; GB_INTEGER height; GB_STRING text; GB_INTEGER pos) int pos = VARGOPT(pos, -1); QString text(GB.ToZeroString(ARG(text))); WIDGET->insertItem(new MyListBoxItem(WIDGET, text, VARG(width), VARG(height)), pos); if (THIS->sorted) WIDGET->sort(); END_METHOD */ BEGIN_METHOD(CLISTBOX_remove, GB_INTEGER pos) //WIDGET->blockSignals(true); WIDGET->removeItem(VARG(pos)); //WIDGET->blockSignals(false); END_METHOD BEGIN_PROPERTY(CLISTBOX_sorted) if (READ_PROPERTY) GB.ReturnBoolean(THIS->sorted); else { THIS->sorted = VPROP(GB_BOOLEAN); if (THIS->sorted) WIDGET->sort(); } END_METHOD BEGIN_PROPERTY(CLISTBOX_count) GB.ReturnInteger(WIDGET->count()); END_PROPERTY BEGIN_PROPERTY(CLISTBOX_index) int index; if (READ_PROPERTY) GB.ReturnInteger(CListBox::currentItem(WIDGET)); else { index = VPROP(GB_INTEGER); if (index < 0 || index >= (int)WIDGET->count()) { WIDGET->clearSelection(); return; } //if (WIDGET->selectionMode() == QListBox::Multi || WIDGET->selectionMode() == QListBox::Extended) //{ //WIDGET->clearSelection(); //WIDGET->setSelected(index, true); //} WIDGET->setCurrentItem(index); if (WIDGET->selectionMode() == QListBox::Single) WIDGET->setSelected(WIDGET->currentItem(), true); WIDGET->ensureCurrentVisible(); } END_PROPERTY BEGIN_PROPERTY(CLISTBOX_current) THIS->index = CListBox::currentItem(WIDGET); if (THIS->index < 0) GB.ReturnNull(); else RETURN_SELF(); END_PROPERTY BEGIN_PROPERTY(CLISTBOX_text) int index = CListBox::currentItem(WIDGET); if (index < 0) GB.ReturnNull(); else GB.ReturnNewZeroString(TO_UTF8(WIDGET->text(index))); END_PROPERTY BEGIN_PROPERTY(CLISTBOX_mode) if (READ_PROPERTY) GB.ReturnInteger(CCONST_convert(_selection_mode, WIDGET->selectionMode(), SELECT_NONE, false)); else WIDGET->setSelectionMode((QListBox::SelectionMode)CCONST_convert(_selection_mode, VPROP(GB_INTEGER), SELECT_NONE, true)); END_PROPERTY BEGIN_PROPERTY(CLISTBOX_item_selected) if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->isSelected(THIS->index)); else WIDGET->setSelected(THIS->index, VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CLISTBOX_item_text) bool selected; int current; if (READ_PROPERTY) GB.ReturnNewZeroString(TO_UTF8(WIDGET->text(THIS->index))); else { current = WIDGET->currentItem(); WIDGET->blockSignals(true); selected = WIDGET->isSelected(THIS->index); WIDGET->changeItem(QSTRING_PROP(), THIS->index); if (selected) WIDGET->setSelected(THIS->index, selected); WIDGET->setCurrentItem(current); WIDGET->blockSignals(false); } END_PROPERTY /* BEGIN_PROPERTY(CLISTBOX_item_custom) GB.ReturnBoolean(WIDGET->item(WIDGET->currentItem())->rtti() == CUSTOM_RTTI); END_PROPERTY */ BEGIN_METHOD(CLISTBOX_find, GB_STRING item) GB.ReturnInteger(CListBox::find(WIDGET, QSTRING_ARG(item))); END_METHOD BEGIN_PROPERTY(CLISTBOX_list) GB_ARRAY array; if (READ_PROPERTY) { GB.Array.New(&array, GB_T_STRING, WIDGET->count()); CListBox::getAll(WIDGET, array); GB.ReturnObject(array); } else { CListBox::setAll(WIDGET, (GB_ARRAY)VPROP(GB_OBJECT)); if (THIS->sorted) WIDGET->sort(); } END_PROPERTY GB_DESC CListBoxItemDesc[] = { GB_DECLARE(".ListBoxItem", 0), GB_VIRTUAL_CLASS(), GB_PROPERTY("Text", "s", CLISTBOX_item_text), GB_PROPERTY("Selected", "b", CLISTBOX_item_selected), //GB_PROPERTY_READ("Custom", "b", CLISTBOX_item_custom), GB_END_DECLARE }; GB_DESC CListBoxDesc[] = { GB_DECLARE("ListBox", sizeof(CLISTBOX)), GB_INHERITS("Control"), //GB_CONSTANT("None", "i", SELECT_NONE), //GB_CONSTANT("Single", "i", SELECT_SINGLE), //GB_CONSTANT("Multi", "i", SELECT_MULTIPLE), // REMOVE //GB_CONSTANT("Multiple", "i", SELECT_MULTIPLE), //GB_CONSTANT("Extended", "i", QListBox::Extended), GB_METHOD("_new", NULL, CLISTBOX_new, "(Parent)Container;"), GB_METHOD("_get", ".ListBoxItem", CLISTBOX_get, "(Index)i"), GB_METHOD("Clear", NULL, CLISTBOX_clear, NULL), GB_METHOD("Add", NULL, CLISTBOX_add, "(Text)s[(Index)i]"), //GB_METHOD("AddCustom", NULL, CLISTBOX_add_custom, "(Width)i(Height)i[(Text)s(After)i]"), GB_METHOD("Remove", NULL, CLISTBOX_remove, "(Index)i"), GB_PROPERTY("Sorted", "b", CLISTBOX_sorted), GB_PROPERTY("List", "String[]", CLISTBOX_list), //GB_PROPERTY("Contents", "s", CLISTBOX_list), GB_PROPERTY_READ("Count", "i", CLISTBOX_count), GB_PROPERTY_READ("Current", ".ListBoxItem", CLISTBOX_current), GB_PROPERTY_READ("Text", "s", CLISTBOX_text), GB_PROPERTY("Index", "i", CLISTBOX_index), GB_PROPERTY("Mode", "i", CLISTBOX_mode), GB_METHOD("Find", "i", CLISTBOX_find, "(Item)s"), /* GB_METHOD("Select", NULL, CLISTBOX_select, 1, 1, "i"), GB_METHOD("Invert", NULL, CLISTBOX_invert, 0, 0, NULL), */ GB_EVENT("Select", NULL, NULL, &EVENT_Select), GB_EVENT("Activate", NULL, NULL, &EVENT_Activate), GB_EVENT("Click", NULL, NULL, &EVENT_Click), //GB_EVENT("Draw", NULL, "(Index)i", &EVENT_Draw), LISTBOX_DESCRIPTION, GB_END_DECLARE }; /** MyListBox ***************************************************************/ MyListBox::MyListBox(QWidget *parent) : QListBox(parent) { } void MyListBox::mousePressEvent( QMouseEvent *e ) { if (e->button() == LeftButton) QListBox::mousePressEvent(e); } void MyListBox::resizeEvent( QResizeEvent *e ) { //qDebug("MyListBox::resizeEvent"); QScrollView::resizeEvent(e); triggerUpdate(true); doLayout(); viewport()->repaint( FALSE ); ensureCurrentVisible(); } void MyListBox::setCurrentItem(QListBoxItem *item) { //void *_object = CWidget::get(this); //int current = currentItem(); //qDebug("setCurrentItem"); QListBox::setCurrentItem(item); //if (current == currentItem()) // GB.Raise(THIS, EVENT_Click, 0); } #if 0 /** MyListBoxItem ***********************************************************/ MyListBoxItem::MyListBoxItem(QListBox *listbox, QString& text, int width, int height) :QListBoxItem(listbox) { setText(text); w = width; h = height; } MyListBoxItem::~MyListBoxItem() { } void MyListBoxItem::paint(QPainter *painter) { int status = DRAW_status(); DRAW_begin(DRAW_ON_ITEM, painter); //qDebug("MyDrawingArea::paintEvent %p", CWidget::get(this)); GB.Raise(CWidget::get(listBox()), EVENT_Draw, 1, GB_T_INTEGER, listBox()->index(this)); DRAW_restore(status); } int MyListBoxItem::height( const QListBox* lb ) const { return QMAX(h, QApplication::globalStrut().height()); } int MyListBoxItem::width( const QListBox* lb ) const { return QMAX(w, QApplication::globalStrut().width()); } int MyListBoxItem::RTTI = CUSTOM_RTTI; int MyListBoxItem::rtti() const { return RTTI; } #endif /** CListBox ****************************************************************/ CListBox CListBox::manager; static void post_select_event(void *_object) { GB.Raise(_object, EVENT_Select, 0); GB.Unref(&_object); } void CListBox::selected(void) { GET_SENDER(_object); if (WIDGET->selectionMode() == QListBox::Single) GB.Raise(_object, EVENT_Select, 0); else { GB.Ref(THIS); GB.Post((GB_POST_FUNC)post_select_event, (intptr_t)THIS); } //RAISE_EVENT(EVENT_Select); } void CListBox::activated(int index) { RAISE_EVENT(EVENT_Activate); } void CListBox::highlighted(int index) { GET_SENDER(_object); if (currentItem(WIDGET) < 0) return; if (!WIDGET->isSelected(index)) return; THIS->last = index; GB.Raise(_object, EVENT_Click, 0); } void CListBox::clicked(QListBoxItem *i) { int current; GET_SENDER(_object); if (!i) return; current = currentItem(WIDGET); if (THIS->last == current) { THIS->last = -1; return; } GB.Raise(_object, EVENT_Click, 0); THIS->last = -1; } #if 0 void CListBox::clicked(QListBoxItem *item) { int current; GET_SENDER(_object); if (!item) return; current = currentItem(WIDGET); if (current < 0 || WIDGET->item(current) != item) return; GB.Raise(_object, EVENT_Click, 0); } #endif int CListBox::find(QListBox *list, const QString& s) { for (int i = 0; i < (int)list->count(); i++) { if (list->text(i) == s) return i; } return (-1); } void CListBox::getAll(QListBox *list, GB_ARRAY array) { uint i; char *str; for (i = 0; i < list->count(); i++) { GB.NewString(&str, TO_UTF8(list->text(i)), 0); *((char **)GB.Array.Get(array, i)) = str; } } void CListBox::setAll(QListBox *list, GB_ARRAY array) { int i; list->clear(); list->blockSignals(true); if (array) { for (i = 0; i < GB.Array.Count(array); i++) { list->insertItem(TO_QSTRING(*((char **)GB.Array.Get(array, i)))); } } list->blockSignals(false); } int CListBox::currentItem(QListBox *list) { int mode = list->selectionMode(); int index; if (mode == QListBox::NoSelection) return -1; index = list->currentItem(); if (mode == QListBox::Single) { if (!list->isSelected(index)) index = -1; } return index; }