#include #include eComboBox::eComboBox( eWidget* parent, int OpenEntries, eLabel* desc, int takefocus, const char *deco ) :eButton(parent, desc, takefocus, deco), listbox(0, 0, takefocus), button( this, 0, 0, eSkin::getActive()->queryValue("eComboBox.smallButton.decoWidth",0)?"eButton":""), pm(0), entries(OpenEntries), current(0) { align=eTextPara::dirLeft; if ( eSkin::getActive()->queryValue("eComboBox.smallButton.decoWidth",0) ) button.loadDeco(); button.setBlitFlags(BF_ALPHATEST); eSkin::getActive()->queryImage(pm, "eComboBox.arrow"); button.setPixmap(pm); listbox.hide(); listbox.setDeco("eComboBox.listbox"); listbox.loadDeco(); CONNECT( selected, eComboBox::onOkPressed ); CONNECT( listbox.selected, eComboBox::onEntrySelected ); CONNECT( listbox.selchanged, eComboBox::onSelChanged ); listbox.zOrderRaise(); addActionMap(&i_cursorActions->map); } eComboBox::~eComboBox() { if ( listbox.isVisible() ) { eDebug("KILL COMBOBOX WITH OPEN LISTBOX"); listbox.hide(); setFocus(this); eWindow::globalCancel( eWindow::ON ); } } void eComboBox::redrawWidget(gPainter *target, const eRect &rc) { // target->clip( eRect( rc.left(), rc.top(), rc.width()-button.width(), rc.bottom() ) ); eLabel::redrawWidget(target, rc); // target->clippop(); } void eComboBox::onOkPressed() { if ( flags & flagShowEntryHelp) { oldHelpText=helptext; setHelpText( listbox.getCurrent()->getHelpText() ); } if ( flags & flagSorted ) listbox.sort(); parent->setFocus( &listbox ); ePoint pt = getAbsolutePosition(); if ( pt.y() + getSize().height() + listbox.getSize().height() > 520) listbox.move( ePoint( pt.x(), pt.y()-listbox.getSize().height() ) ); else listbox.move( ePoint( pt.x(), pt.y()+getSize().height() ) ); eWindow::globalCancel( eWindow::OFF ); listbox.show(); } int eComboBox::setProperty( const eString& prop, const eString& val ) { if ( prop == "sorted" ) flags |= flagSorted; else if (prop == "openEntries" ) entries = atoi( val.c_str() ); else if (prop == "showEntryHelp" ) flags |= flagShowEntryHelp; else if (prop == "openWidth" ) { int width=listbox.getSize().width(); width = atoi(val.c_str()); setOpenWidth( width ); } else return eButton::setProperty( prop, val); return 0; } int eComboBox::eventHandler( const eWidgetEvent& event ) { switch (event.type) { case eWidgetEvent::evtShortcut: onOkPressed(); break; case eWidgetEvent::changedPosition: case eWidgetEvent::changedSize: { eListBoxEntryText* cur = listbox.getCount()?listbox.getCurrent():0; listbox.resize( eSize( getSize().width(), eListBoxEntryText::getEntryHeight()*entries+listbox.getDeco().borderBottom+listbox.getDeco().borderTop ) ); int smButtonDeco = eSkin::getActive()->queryValue("eComboBox.smallButton.decoWidth", pm?pm->x:0 ); if (deco) { button.resize( eSize(smButtonDeco, crect.height()) ); button.move( ePoint( crect.right()-smButtonDeco, crect.top() ) ); } else { button.resize( eSize(smButtonDeco, height()) ); button.move( ePoint( position.x()+size.width()-smButtonDeco, 0 ) ); } if (pm) button.pixmap_position = ePoint( (button.getSize().width() - pm->x) / 2, (button.getSize().height() - pm->y) / 2 ); if (cur) listbox.setCurrent(cur); } default: return eButton::eventHandler( event ); } return 1; } int eComboBox::moveSelection ( int dir, bool sendSelChanged ) { int ret = listbox.moveSelection( dir, sendSelChanged ); eListBoxEntryText *cur = listbox.getCurrent(); if ( cur ) { setText( cur->getText() ); current = cur; } return ret; } void eComboBox::onEntrySelected( eListBoxEntryText* e) { listbox.hide(); if (flags & flagShowEntryHelp) setHelpText( oldHelpText ); if (e && button.getText() != e->getText() ) { setText(e->getText()); setFocus( this ); #ifndef DISABLE_LCD if ( parent->LCDElement ) parent->LCDElement->setText(""); #endif current = e; /* emit */ selchanged_id(this, current); /* emit */ selchanged(current); } else setFocus( this ); eWindow::globalCancel( eWindow::ON ); } void eComboBox::onSelChanged(eListBoxEntryText* le) { if (flags & flagShowEntryHelp ) setHelpText( le->getHelpText() ); #ifndef DISABLE_LCD if ( parent->getFocus() == &listbox ) { if ( LCDTmp ) LCDTmp->setText( le->getText() ); else if ( parent->LCDElement ) parent->LCDElement->setText( le->getText() ); } #endif } void eComboBox::removeEntry( eListBoxEntryText* le ) { if (le) { listbox.remove(le); if ( flags & flagSorted ) listbox.sort(); } } void eComboBox::removeEntry( int num ) { if ( listbox.getCount() >= num) { setCurrent( num ); listbox.remove( listbox.getCurrent() ); if ( flags & flagSorted ) listbox.sort(); } } void eComboBox::removeEntry( void* key ) { setCurrent(key); if (listbox.getCurrent() && key == listbox.getCurrent()->getKey() ) { listbox.remove( listbox.getCurrent() ); if ( flags & flagSorted ) listbox.sort(); } } int eComboBox::setCurrent( eListBoxEntryText* le, bool sendSelChanged ) { if (!le) return E_INVALID_ENTRY; int err = listbox.setCurrent( le, sendSelChanged ); if( err && err != E_ALLREADY_SELECTED ) return err; setText( listbox.getCurrent()->getText() ); current = listbox.getCurrent(); return OK; } struct selectEntryByNum: public std::unary_function { int num; eListBox* lb; bool sendSelChanged; selectEntryByNum(int num, eListBox *lb, bool sendSelChanged=false): num(num), lb(lb), sendSelChanged(sendSelChanged) { } bool operator()(const eListBoxEntryText& le) { if (!num--) { lb->setCurrent(&le, sendSelChanged); return 1; } return 0; } }; int eComboBox::setCurrent( int num, bool sendSelChanged ) { if ( num > listbox.getCount() ) return E_INVALID_ENTRY; int err = listbox.forEachEntry( selectEntryByNum(num, &listbox, sendSelChanged ) ); if ( err ) return E_COULDNT_FIND; setText( listbox.getCurrent()->getText() ); current = listbox.getCurrent(); return OK; } struct selectEntryByKey: public std::unary_function { void* key; eListBox* lb; bool sendSelChanged; selectEntryByKey(void *key, eListBox *lb, bool sendSelChanged=false):key(key), lb(lb), sendSelChanged(sendSelChanged) { } bool operator()(const eListBoxEntryText& le) { if ( le.getKey() == key ) { lb->setCurrent(&le, sendSelChanged ); return 1; } return 0; } }; int eComboBox::setCurrent( void* key, bool sendSelChanged ) { if (!listbox.getCount()) return E_INVALID_ENTRY; eListBoxEntryText* cur = listbox.getCurrent(); if ( cur && cur->getKey() == key ) goto ok; int err; if ( (err=listbox.forEachEntry( selectEntryByKey(key, &listbox, sendSelChanged ) ) ) ) return E_COULDNT_FIND; ok: setText( listbox.getCurrent()->getText() ); current = listbox.getCurrent(); return OK; } eListBoxEntryText* eComboBox::getCurrent() { return current; }