Example #1
0
QSize PopupMenuEditor::contentsSize()
{
    QRect textRect = fontMetrics().boundingRect( addSeparator.action()->menuText() );
    textWidth = textRect.width();
    accelWidth = textRect.height(); // default size
    iconWidth = textRect.height();

    int w = 0;
    int h = itemHeight( &addItem ) + itemHeight( &addSeparator );
    PopupMenuEditorItem * i = itemList.first();
    QAction * a = 0;
    while ( i ) {
	if ( i->isVisible() ) {
	    if ( !i->isSeparator() ) {
		a = i->action();
		w = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ).rect().width() +
		    borderSize; // padding
		iconWidth = QMAX( iconWidth, w );
		w = fontMetrics().boundingRect( a->menuText() ).width();
		textWidth = QMAX( textWidth, w );
		w = fontMetrics().boundingRect( a->accel() ).width() + 2; // added padding?
		accelWidth = QMAX( accelWidth, w );
	    }
	    h += itemHeight( i );
	}
	i = itemList.next();
    }

    int width = iconWidth + textWidth + borderSize * 3 + accelWidth + arrowWidth;
    return QSize( width, h );
}
Example #2
0
void PopupMenuEditor::setFocusAt( const QPoint & pos )
{
    hideSubMenu();
    lineEdit->hide();

    currentIndex = 0;
    int iy = 0;
    PopupMenuEditorItem * i = itemList.first();

    while ( i ) {
	iy += itemHeight( i );
	if ( iy > pos.y() )
	    break;
	i = itemList.next();
	currentIndex++;
    }

    iy += itemHeight( &addItem );
    if ( iy <= pos.y() )
	currentIndex++;

    if ( currentIndex < (int)itemList.count() ) {
	if ( pos.x() < iconWidth )
	    currentField = 0;
	else if ( pos.x() < iconWidth + textWidth )
	    currentField = 1;
	else
	    currentField = 2;
    } else {
	currentField = 1;
    }

    showSubMenu();
}
Example #3
0
KNTabManagerItem::KNTabManagerItem(const QString &caption, QWidget *parent) :
    QLabel(parent),
    m_selected(false),
    m_codeEditor(new KNCodeEditor(this)),
    m_closeButton(new KNLabelAnimeButton(this))
{
    setObjectName("TabManagerItem");
    //Set properties.
    setContentsMargins(9,0,9,0);
    setFixedHeight(itemHeight());
    setAutoFillBackground(true);

    //Save and set the palette.
    m_palette=KNGlobal::instance()->getPalette(objectName());
    setPalette(m_palette);

    //Set the caption.
    setCaption(caption);
    //Configure the close button.
    m_closeButton->setPixmap(QPixmap(":/image/resource/images/close.png"));
    m_closeButton->setScaledContents(true);
    m_closeButton->resize(itemHeight(), itemHeight());
    m_closeButton->hide();
    connect(m_closeButton, &KNLabelAnimeButton::clicked,
            this, &KNTabManagerItem::onActionClose);

    //Link the code editor.
    connect(m_codeEditor, &KNCodeEditor::fileNameChange,
            this, &KNTabManagerItem::setCaption);
}
bool AbstractWheelWidget::event(QEvent *e)
{
    switch (e->type()) {
// ![1]
    case QEvent::ScrollPrepare:
    {
        // We set the snap positions as late as possible so that we are sure
        // we get the correct itemHeight
        QScroller *scroller = QScroller::scroller(this);
        scroller->setSnapPositionsY( WHEEL_SCROLL_OFFSET, itemHeight() );

        QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e);
        se->setViewportSize(QSizeF(size()));
        // we claim a huge scrolling area and a huge content position and
        // hope that the user doesn't notice that the scroll area is restricted
        se->setContentPosRange(QRectF(0.0, 0.0, 0.0, WHEEL_SCROLL_OFFSET * 2));
        se->setContentPos(QPointF(0.0, WHEEL_SCROLL_OFFSET + m_currentItem * itemHeight() + m_itemOffset));
        se->accept();
        return true;
    }
// ![1]
// ![2]
    case QEvent::Scroll:
    {
        QScrollEvent *se = static_cast<QScrollEvent *>(e);

        qreal y = se->contentPos().y();
        int iy = y - WHEEL_SCROLL_OFFSET;
        int ih = itemHeight();

// ![2]
// ![3]
        // -- calculate the current item position and offset and redraw the widget
        int ic = itemCount();
        if (ic>0) {
            m_currentItem = iy / ih % ic;
            m_itemOffset = iy % ih;

            // take care when scrolling backwards. Modulo returns negative numbers
            if (m_itemOffset < 0) {
                m_itemOffset += ih;
                m_currentItem--;
            }

            if (m_currentItem < 0)
                m_currentItem += ic;
        }
        // -- repaint
        update();

        se->accept();
        return true;
// ![3]
    }
    default:
        return QWidget::event(e);
    }
    return true;
}
ListBoxItem::TgtLocation
  ListBoxItem :: targetLocation ( IListBox *pLB, const IPoint &pt )
  {
  // Target position is in desktiop coordinates.
  // We must map this to listbox window coordinates.
  IPoint
    lbPt = IWindow::mapPoint( pt,
                              IWindow::desktopWindow()->handle(),
                              pLB->handle() );
  // Get index of target item:
  unsigned
    index = sourceIndex( pLB, lbPt );
  LocType
    type = on;
  if ( index != nil )
    { // Drop at item, see if before or after:
    unsigned
      dy  = pLB->rect().height() - lbPt.y(),
      i   = itemHeight(pLB),
      rem = dy % i;
    if ( rem < i/4 )
      type = before;
    else if ( rem > 3*i/4 )
      type = after;
    }
  else
    { // Drop off end.
    type = after;
    index = pLB->count() - 1;
    }
  return TgtLocation( type, index );
  }
Example #6
0
void KNTabManagerItem::resizeEvent(QResizeEvent *event)
{
    //Resize the item.
    QLabel::resizeEvent(event);
    //Move the button.
    m_closeButton->move(width()-itemHeight(), 0);
}
Example #7
0
PopupMenuEditorItem * PopupMenuEditor::itemAt( int y )
{
    PopupMenuEditorItem * i = itemList.first();
    int iy = 0;

    while ( i ) {
	iy += itemHeight( i );
	if ( iy > y )
	    return i;
	i = itemList.next();
    }
    iy += itemHeight( &addItem );
    if ( iy > y )
	return &addItem;
    return &addSeparator;
}
Example #8
0
void PopupMenuEditor::drawItems( QPainter * p )
{
    int flags = 0;
    int idx = 0;

    QColorGroup enabled = colorGroup();
    QColorGroup disabled = palette().disabled();
    QRect focus;
    QRect rect( borderSize, borderSize, width() - borderSize * 2, 0 );

    PopupMenuEditorItem * i = itemList.first();
    while ( i ) {
	if ( i->isVisible() ) {
	    rect.setHeight( itemHeight( i ) );
	    if ( idx == currentIndex )
		focus = rect;
	    if ( i->action()->isEnabled() ) {
		flags = QStyle::Style_Enabled;
		p->setPen( enabled.buttonText() );
	    } else {
		flags = QStyle::Style_Default;
		p->setPen( disabled.buttonText() );
	    }
	    drawItem( p, i, rect, flags );
	    rect.moveBy( 0, rect.height() );
	}
	i = itemList.next();
	idx++;
    }

    // Draw the "add item" and "add separator" items
    p->setPen( darkBlue );
    rect.setHeight( itemHeight( &addItem ) );
    if ( idx == currentIndex )
	focus = rect;
    drawItem( p, &addItem, rect, QStyle::Style_Default );
    rect.moveBy( 0, rect.height() );
    idx++;
    rect.setHeight( itemHeight( &addSeparator ) );
    if ( idx == currentIndex )
	focus = rect;
    drawItem( p, &addSeparator, rect, QStyle::Style_Default );
    idx++;

    if ( hasFocus() && !draggedItem )
	drawWinFocusRect( p, focus );
}
Example #9
0
int CtrlTree::maxItems()
{
    const Position *pPos = getPosition();
    if( !pPos )
    {
        return -1;
    }
    return pPos->getHeight() / itemHeight();
}
Example #10
0
QSize OCompletionBox::sizeHint() const
{
    int ih = itemHeight();
    int h = QMIN( 15 * ih, (int) count() * ih ) +1;
    h = QMAX( h, OListBox::minimumSizeHint().height() );

    int w = (d->m_parent) ? d->m_parent->width() : OListBox::minimumSizeHint().width();
    w = QMAX( OListBox::minimumSizeHint().width(), w );
    return QSize( w, h );
}
Example #11
0
Transition::Transition(const ItemInfo &info, int transitiontrack, double fps, const QDomElement &params, bool automaticTransition) :
    AbstractClipItem(info, QRectF(), fps),
    m_forceTransitionTrack(false),
    m_automaticTransition(automaticTransition),
    m_transitionTrack(transitiontrack)
{
    setZValue(4);
    m_info.cropDuration = info.endPos - info.startPos;
    if (QApplication::style()->styleHint(QStyle::SH_Widget_Animate, 0, QApplication::activeWindow())) {
        // animation disabled
        setRect(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal) itemHeight());
    }
    else {
        QPropertyAnimation *startAnimation = new QPropertyAnimation(this, "rect");
        startAnimation->setDuration(200);
        const QRectF r(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal) itemHeight() / 2);
        const QRectF r2(0, 0, m_info.cropDuration.frames(fps) - 0.02, (qreal)itemHeight());
        startAnimation->setStartValue(r);
        startAnimation->setEndValue(r2);
        startAnimation->setEasingCurve(QEasingCurve::OutQuad);
        startAnimation->start(QAbstractAnimation::DeleteWhenStopped);
    }

    m_info.cropStart = GenTime();
    m_maxDuration = GenTime(600);

    if (m_automaticTransition) setBrush(QColor(200, 200, 50, 180));
    else setBrush(QColor(200, 100, 50, 180));

    //m_referenceClip = clipa;
    if (params.isNull()) {
        m_parameters = MainWindow::transitions.getEffectByTag(QStringLiteral("luma"), QStringLiteral("dissolve")).cloneNode().toElement();
    } else {
        m_parameters = params;
    }
    if (m_automaticTransition) m_parameters.setAttribute(QStringLiteral("automatic"), 1);
    else if (m_parameters.attribute(QStringLiteral("automatic")) == QLatin1String("1")) m_automaticTransition = true;
    if (m_parameters.attribute(QStringLiteral("force_track")) == QLatin1String("1")) m_forceTransitionTrack = true;
    m_name = i18n(m_parameters.firstChildElement("name").text().toUtf8().data());
}
Example #12
0
void LayoutListBox::computeLogicalHeight(
    LayoutUnit,
    LayoutUnit logicalTop,
    LogicalExtentComputedValues& computedValues) const {
  LayoutUnit height = itemHeight() * size();
  // FIXME: The item height should have been added before updateLogicalHeight
  // was called to avoid this hack.
  setIntrinsicContentLogicalHeight(height);

  height += borderAndPaddingHeight();

  LayoutBox::computeLogicalHeight(height, logicalTop, computedValues);
}
Example #13
0
int PopupMenuEditor::itemPos( const PopupMenuEditorItem * item ) const
{
    PopupMenuEditor * that = ( PopupMenuEditor * ) this;
    int y = 0;
    PopupMenuEditorItem * i = that->itemList.first();
    while ( i ) {
	if ( i == item )
	    return y;
	y += itemHeight( i );
	i = that->itemList.next();
    }
    return y;
}
Example #14
0
void spaceSaverSetRowHeights(struct spaceSaver *ss, struct spaceSaver *holdSs, int (*itemHeight)(void *item))
/* Determine maximum height of items in a row. Return total height.
   Used by tracks with variable height items */
{
assert(ss != NULL);
assert(holdSs != NULL);
if (!holdSs->rowSizes)
    AllocArray(holdSs->rowSizes, ss->rowCount);
struct spaceNode *sn;
for (sn = ss->nodeList; sn != NULL; sn = sn->next)
    {
    holdSs->rowSizes[sn->row] = max(holdSs->rowSizes[sn->row], itemHeight(sn->val));
    }
}
Example #15
0
int PopupMenuEditor::snapToItem( int y )
{
    int iy = 0;
    int dy = 0;

    PopupMenuEditorItem * i = itemList.first();

    while ( i ) {
	    dy = itemHeight( i );
	    if ( iy + dy / 2 > y )
		return iy;
	    iy += dy;
	i = itemList.next();
    }

    return iy;
}
Example #16
0
void PopupMenuEditor::showLineEdit( int index )
{
    int idx = ( index == -1 ? currentIndex : index );

    PopupMenuEditorItem * i = 0;

    if ( idx >= (int)itemList.count() )
	i = &addItem;
    else
	i = itemList.at( idx );

    // open edit currentField for item name
    lineEdit->setText( i->action()->menuText() );
    lineEdit->selectAll();
    lineEdit->setGeometry( borderSize + iconWidth, borderSize + itemPos( i ),
			   textWidth, itemHeight( i ) );
    lineEdit->show();
    lineEdit->setFocus();
}
unsigned ListBoxItem :: sourceIndex ( IListBox *pLB, 
                                      const IPoint &pt ) 
  {
  // If there are no items, indicate no match.
  if ( pLB->isEmpty() )
    return nil;

  // Calculate index of dragged item:
  unsigned
    dy = pLB->rect().height() - pt.y(),
    i  = itemHeight(pLB),
    row = dy / i,
    index = pLB->top() + row;

  // If off end, indicate that.
  if ( index >= pLB->count() )
    index = nil;

  return index;
  }
Example #18
0
void DragListBox::dropEvent( QDropEvent *evt ) {
	QString text;

	int i = int( float(evt->pos().y())/float(itemHeight()) + 0.5 ) + topItem();
	if ( i > count() + 1 ) i = count() + 1;

	if ( QTextDrag::decode( evt, text ) ) {
		//If we dragged an "Ignore item from the FieldList to the FieldPool, then we don't
		//need to insert the item, because FieldPool already has a persistent Ignore item.
		if ( !( text == i18n("Ignore" ) && QString(evt->source()->name()) == "FieldList" && 
				evt->source() != this )) {
			insertItem( text, i );
		}

		//If we dragged the "Ignore" item from FieldPool to FieldList, then we don't
		//want to remove the item from the FieldPool
		if ( !( text == i18n("Ignore" ) && QString(evt->source()->name()) == "FieldPool" && 
				evt->source() != this ) ) {
			DragListBox *fp = (DragListBox*)evt->source();
			fp->removeItem( fp->currentItem() );
		}
	}
}
Example #19
0
void PopupMenuEditor::dropInPlace( PopupMenuEditorItem * i, int y )
{
    int iy = 0;
    int dy = 0;
    int idx = 0;

    PopupMenuEditorItem * n = itemList.first();

    while ( n ) {
	dy = itemHeight( n );
	if ( iy + dy / 2 > y )
	    break;
	iy += dy;
	idx++;
	n = itemList.next();
    }
    int same = itemList.findRef( i );
    AddActionToPopupCommand * cmd = new AddActionToPopupCommand( "Drop Item", formWnd, this, i, idx );
    formWnd->commandHistory()->addCommand( cmd );
    cmd->execute();
    currentIndex = ( same >= 0 && same < idx ) ? idx - 1 : idx;
    currentField = 1;
}
Example #20
0
void CtrlTree::makeImage()
{
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
        return;
    int width = pPos->getWidth();
    int height = pPos->getHeight();

    int i_itemHeight = itemHeight();

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    Iterator it = m_firstPos;

    if( m_pBgBitmap )
    {
        // Draw the background bitmap
        if( !m_pScaledBitmap ||
            m_pScaledBitmap->getWidth() != width ||
            m_pScaledBitmap->getHeight() != height )
        {
            delete m_pScaledBitmap;
            m_pScaledBitmap =
                new ScaledBitmap( getIntf(), *m_pBgBitmap, width, height );
        }
        m_pImage->drawBitmap( *m_pScaledBitmap, 0, 0 );

        for( int yPos = 0;
             yPos < height && it != m_rTree.end();
             yPos += i_itemHeight, ++it )
        {
            if( it->isSelected() )
            {
                int rectHeight = __MIN( i_itemHeight, height - yPos );
                m_pImage->fillRect( 0, yPos, width, rectHeight, m_selColor );
            }
        }
    }
    else
    {
        // Fill background with background color
        uint32_t bgColor = m_bgColor1;
        m_pImage->fillRect( 0, 0, width, height, bgColor );
        // Overwrite with alternate colors (bgColor1, bgColor2)
        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            int rectHeight = __MIN( i_itemHeight, height - yPos );
            if( it == m_rTree.end() )
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            else
            {
                uint32_t color = ( it->isSelected() ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                ++it;
            }
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    int bitmapWidth = itemImageWidth();

    it = m_firstPos;
    for( int yPos = 0; yPos < height && it != m_rTree.end(); ++it )
    {
        const GenericBitmap *m_pCurBitmap;
        UString *pStr = it->getString();
        if( pStr != NULL )
        {
            uint32_t color = it->isPlaying() ? m_playColor : m_fgColor;
            int depth = m_flat ? 1 : it->depth();
            GenericBitmap *pText =
                m_rFont.drawString( *pStr, color, width-bitmapWidth*depth );
            if( !pText )
            {
                return;
            }
            if( it->size() )
                m_pCurBitmap =
                    it->isExpanded() ? m_pOpenBitmap : m_pClosedBitmap;
            else
                m_pCurBitmap = m_pItemBitmap;

            if( m_pCurBitmap )
            {
                // Make sure we are centered on the line
                int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
                if( yPos2 >= height )
                {
                    delete pText;
                    break;
                }
                // Draw the icon in front of the text
                m_pImage->drawBitmap( *m_pCurBitmap, 0, 0,
                                      bitmapWidth * (depth - 1 ), yPos2,
                                      m_pCurBitmap->getWidth(),
                                      __MIN( m_pCurBitmap->getHeight(),
                                             height -  yPos2), true );
            }
            yPos += i_itemHeight - pText->getHeight();
            int ySrc = 0;
            if( yPos < 0 )
            {
                ySrc = - yPos;
                yPos = 0;
            }
            int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
            // Draw the text
            m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
                                  pText->getWidth(),
                                  lineHeight, true );
            yPos += (pText->getHeight() - ySrc );

            if( it == m_itOver )
            {
                // Draw the underline bar below the text for drag&drop
                m_pImage->fillRect(
                    bitmapWidth * (depth - 1 ), yPos - 2,
                    bitmapWidth + pText->getWidth(), __MAX( lineHeight/5, 3 ),
                    m_selColor );
            }
            delete pText;
        }
    }
}
/*!
    Rotates the wheel widget to a given index.
    You can also give an index greater than itemCount or less than zero in which
    case the wheel widget will scroll in the given direction and end up with
    (index % itemCount)
*/
void AbstractWheelWidget::scrollTo(int index)
{
    QScroller *scroller = QScroller::scroller(this);

    scroller->scrollTo(QPointF(0, WHEEL_SCROLL_OFFSET + index * itemHeight()), 5000);
}
void AbstractWheelWidget::paintEvent(QPaintEvent* event)
{
    Q_UNUSED( event );

    // -- first calculate size and position.
    int w = width();
    int h = height();

    QPainter painter(this);
    QPalette palette = QApplication::palette();
    QPalette::ColorGroup colorGroup = isEnabled() ? QPalette::Active : QPalette::Disabled;

    // linear gradient brush
    QLinearGradient grad(0.5, 0, 0.5, 1.0);
    grad.setColorAt(0, palette.color(colorGroup, QPalette::ButtonText));
    grad.setColorAt(0.2, palette.color(colorGroup, QPalette::Button));
    grad.setColorAt(0.8, palette.color(colorGroup, QPalette::Button));
    grad.setColorAt(1.0, palette.color(colorGroup, QPalette::ButtonText));
    grad.setCoordinateMode( QGradient::ObjectBoundingMode );
    QBrush gBrush( grad );

    // paint a border and background
    painter.setPen(palette.color(colorGroup, QPalette::ButtonText));
    painter.setBrush(gBrush);
    // painter.setBrushOrigin( QPointF( 0.0, 0.0 ) );
    painter.drawRect( 0, 0, w-1, h-1 );

    // paint inner border
    painter.setPen(palette.color(colorGroup, QPalette::Button));
    painter.setBrush(Qt::NoBrush);
    painter.drawRect( 1, 1, w-3, h-3 );

    // paint the items
    painter.setClipRect( QRect( 3, 3, w-6, h-6 ) );
    painter.setPen(palette.color(colorGroup, QPalette::ButtonText));

    int iH = itemHeight();
    int iC = itemCount();
    if (iC > 0) {

        m_itemOffset = m_itemOffset % iH;

        for (int i=-h/2/iH; i<=h/2/iH+1; i++) {

            int itemNum = m_currentItem + i;
            while (itemNum < 0)
                itemNum += iC;
            while (itemNum >= iC)
                itemNum -= iC;

            paintItem(&painter, itemNum, QRect(6, h/2 +i*iH - m_itemOffset - iH/2, w-6, iH ));
        }
    }

    // draw a transparent bar over the center
    QColor highlight = palette.color(colorGroup, QPalette::Highlight);
    highlight.setAlpha(150);

    QLinearGradient grad2(0.5, 0, 0.5, 1.0);
    grad2.setColorAt(0, highlight);
    grad2.setColorAt(1.0, highlight.lighter());
    grad2.setCoordinateMode( QGradient::ObjectBoundingMode );
    QBrush gBrush2( grad2 );

    QLinearGradient grad3(0.5, 0, 0.5, 1.0);
    grad3.setColorAt(0, highlight);
    grad3.setColorAt(1.0, highlight.darker());
    grad3.setCoordinateMode( QGradient::ObjectBoundingMode );
    QBrush gBrush3( grad3 );

    painter.fillRect( QRect( 0, h/2 - iH/2, w, iH/2 ), gBrush2 );
    painter.fillRect( QRect( 0, h/2,        w, iH/2 ), gBrush3 );
}
Example #23
0
void CtrlTree::makeImage()
{
    stats_TimerStart( getIntf(), "[Skins] Playlist image",
                      STATS_TIMER_SKINS_PLAYTREE_IMAGE );
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
    {
        stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
        return;
    }
    int width = pPos->getWidth();
    int height = pPos->getHeight();

    int i_itemHeight = itemHeight();

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    VarTree::Iterator it = m_firstPos;

    if( m_pBgBitmap )
    {
        // Draw the background bitmap
        if( !m_pScaledBitmap ||
            m_pScaledBitmap->getWidth() != width ||
            m_pScaledBitmap->getHeight() != height )
        {
            delete m_pScaledBitmap;
            m_pScaledBitmap =
                new ScaledBitmap( getIntf(), *m_pBgBitmap, width, height );
        }
        m_pImage->drawBitmap( *m_pScaledBitmap, 0, 0 );

        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            if( it != m_rTree.end() )
            {
                if( it->isSelected() )
                {
                    int rectHeight = __MIN( i_itemHeight, height - yPos );
                    m_pImage->fillRect( 0, yPos, width, rectHeight,
                                        m_selColor );
                }
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
        }
    }
    else
    {
        // FIXME (TRYME)
        // Fill background with background color
        uint32_t bgColor = m_bgColor1;
        m_pImage->fillRect( 0, 0, width, height, bgColor );
        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            int rectHeight = __MIN( i_itemHeight, height - yPos );
            if( it == m_rTree.end() )
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            else
            {
                uint32_t color = ( it->isSelected() ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    int bitmapWidth = itemImageWidth();

    int yPos = 0;
    it = m_firstPos;
    while( it != m_rTree.end() && yPos < height )
    {
        const GenericBitmap *m_pCurBitmap;
        UString *pStr = it->getString();
        uint32_t color = ( it->isPlaying() ? m_playColor : m_fgColor );

        // Draw the text
        if( pStr != NULL )
        {
            int depth = m_flat ? 1 : it->depth();
            GenericBitmap *pText = m_rFont.drawString( *pStr, color, width - bitmapWidth * depth );
            if( !pText )
            {
                stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
                return;
            }
            if( it->size() )
                m_pCurBitmap = it->isExpanded() ? m_pOpenBitmap : m_pClosedBitmap;
            else
                m_pCurBitmap = m_pItemBitmap;

            if( m_pCurBitmap )
            {
                // Make sure we are centered on the line
                int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
                if( yPos2 >= height )
                {
                    delete pText;
                    break;
                }
                m_pImage->drawBitmap( *m_pCurBitmap, 0, 0,
                                      bitmapWidth * (depth - 1 ), yPos2,
                                      m_pCurBitmap->getWidth(),
                                      __MIN( m_pCurBitmap->getHeight(),
                                             height -  yPos2), true );
            }
            yPos += i_itemHeight - pText->getHeight();
            int ySrc = 0;
            if( yPos < 0 )
            {
                ySrc = - yPos;
                yPos = 0;
            }
            int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
            m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
                                  pText->getWidth(),
                                  lineHeight, true );
            yPos += (pText->getHeight() - ySrc );
            delete pText;
        }
        do
        {
            it = m_flat ? m_rTree.getNextLeaf( it )
                : m_rTree.getNextVisibleItem( it );
        } while( it != m_rTree.end() && it->isDeleted() );
    }
    stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
}
Example #24
0
void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
    bool bChangedPosition = false;
    VarTree::Iterator toShow; bool needShow = false;
    if( rEvent.getAsString().find( "key:down" ) != string::npos )
    {
        int key = ((EvtKey&)rEvent).getKey();
        VarTree::Iterator it;
        bool previousWasSelected = false;

        /* Delete the selection */
        if( key == KEY_DELETE )
        {
            /* Find first non selected item before m_pLastSelected */
            VarTree::Iterator it_sel = m_flat ? m_rTree.firstLeaf()
                                              : m_rTree.begin();
            for( it = (m_flat ? m_rTree.firstLeaf() : m_rTree.begin());
                 it != m_rTree.end();
                 it = (m_flat ? m_rTree.getNextLeaf( it )
                              : m_rTree.getNextVisibleItem( it )) )
            {
                if( &*it == m_pLastSelected ) break;
                if( !it->isSelected() ) it_sel = it;
            }

            /* Delete selected stuff */
            m_rTree.delSelected();

            /* Verify if there is still sthg selected (e.g read-only items) */
            m_pLastSelected = NULL;
            for( it = (m_flat ? m_rTree.firstLeaf() : m_rTree.begin());
                 it != m_rTree.end();
                 it = (m_flat ? m_rTree.getNextLeaf( it )
                              : m_rTree.getNextVisibleItem( it )) )
            {
                if( it->isSelected() )
                    m_pLastSelected = &*it;
            }

            /* if everything was deleted, use it_sel as last selection */
            if( !m_pLastSelected )
            {
                it_sel->setSelected( true );
                m_pLastSelected = &*it_sel;
            }

            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( key == KEY_PAGEDOWN )
        {
            it = m_firstPos;
            int i = (int)(maxItems()*1.5);
            while( i >= 0 )
            {
                VarTree::Iterator it_old = it;
                it = m_flat ? m_rTree.getNextLeaf( it )
                            : m_rTree.getNextVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == m_rTree.end() )
                {
                    it = it_old;
                    break;
                }
                needShow = true;
                i--;
            }
            if( needShow )
            {
                ensureVisible( it );
                makeImage();
                notifyLayout();
            }
        }
        else if (key == KEY_PAGEUP )
        {
            it = m_firstPos;
            int i = maxItems();
            while( i >= maxItems()/2 )
            {
                it = m_flat ? m_rTree.getPrevLeaf( it )
                            : m_rTree.getPrevVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == ( m_flat ? m_rTree.firstLeaf() : m_rTree.begin() ) )
                {
                    break;
                }
                i--;
            }
            ensureVisible( it );
            makeImage();
            notifyLayout();
        }
        else if ( key == KEY_UP ||
                  key == KEY_DOWN ||
                  key == KEY_LEFT ||
                  key == KEY_RIGHT ||
                  key == KEY_ENTER ||
                  key == ' ' )
        {
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                VarTree::Iterator next = m_flat ?
                                         m_rTree.getNextLeaf( it ) :
                                         m_rTree.getNextVisibleItem( it );
                if( key == KEY_UP )
                {
                    // Scroll up one item
                    if( ( it->parent()
                          && it != it->parent()->begin() )
                        || &*it != m_pLastSelected )
                    {
                        bool nextWasSelected = ( &*next == m_pLastSelected );
                        it->setSelected( nextWasSelected );
                        if( nextWasSelected )
                        {
                            m_pLastSelected = &*it;
                            needShow = true; toShow = it;
                        }
                    }
                }
                else if( key == KEY_DOWN )
                {
                    // Scroll down one item
                    if( ( it->parent()
                          && next != it->parent()->end() )
                        || &*it != m_pLastSelected )
                    {
                        it->setSelected( previousWasSelected );
                    }
                    if( previousWasSelected )
                    {
                        m_pLastSelected = &*it;
                        needShow = true; toShow = it;
                        previousWasSelected = false;
                    }
                    else
                    {
                        previousWasSelected = ( &*it == m_pLastSelected );
                    }

                    // Fix last tree item selection
                    if( ( m_flat ? m_rTree.getNextLeaf( it )
                        : m_rTree.getNextVisibleItem( it ) ) == m_rTree.end()
                     && &*it == m_pLastSelected )
                    {
                        it->setSelected( true );
                    }
                }
                else if( key == KEY_RIGHT )
                {
                    // Go down one level (and expand node)
                    if( &*it == m_pLastSelected )
                    {
                        if( it->isExpanded() )
                        {
                            if( it->size() )
                            {
                                it->setSelected( false );
                                it->begin()->setSelected( true );
                                m_pLastSelected = &*(it->begin());
                            }
                            else
                            {
                                m_rTree.action( &*it );
                            }
                        }
                        else
                        {
                            it->setExpanded( true );
                            bChangedPosition = true;
                        }
                    }
                }
                else if( key == KEY_LEFT )
                {
                    // Go up one level (and close node)
                    if( &*it == m_pLastSelected )
                    {
                        if( it->isExpanded() && it->size() )
                        {
                            it->setExpanded( false );
                            bChangedPosition = true;
                        }
                        else
                        {
                            if( it->parent() && it->parent() != &m_rTree)
                            {
                                it->setSelected( false );
                                m_pLastSelected = it->parent();
                                m_pLastSelected->setSelected( true );
                            }
                        }
                    }
                }
                else if( key == KEY_ENTER || key == ' ' )
                {
                    // Go up one level (and close node)
                    if( &*it == m_pLastSelected )
                    {
                        m_rTree.action( &*it );
                    }
                }
            }
            if( needShow )
                ensureVisible( toShow );
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else
        {
            // other keys to be forwarded to vlc core
            EvtKey& rEvtKey = (EvtKey&)rEvent;
            var_SetInteger( getIntf()->p_libvlc, "key-pressed",
                            rEvtKey.getModKey() );
        }

    }

    else if( rEvent.getAsString().find( "mouse:left" ) != string::npos )
    {
        EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
        const Position *pos = getPosition();
        int yPos = ( rEvtMouse.getYPos() - pos->getTop() ) / itemHeight();
        int xPos = rEvtMouse.getXPos() - pos->getLeft();
        VarTree::Iterator it;

        if( rEvent.getAsString().find( "mouse:left:down:ctrl,shift" ) !=
            string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->setSelected( it->isSelected() || select );
                select = nextSelect;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down:ctrl" ) !=
                 string::npos )
        {
            // Invert the selection of the item
            it = findItemAtPos( yPos );
            if( it != m_rTree.end() )
            {
                it->toggleSelected();
                m_pLastSelected = &*it;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down:shift" ) !=
                 string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->setSelected( select );
                select = nextSelect;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
                if( ( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
                      && xPos < it->depth() * itemImageWidth() )
                 && !m_flat )
                {
                    // Fold/unfold the item
                    it->toggleExpanded();
                    bChangedPosition = true;
                }
                else
                {
                    // Unselect any previously selected item
                    VarTree::Iterator it2;
                    for( it2 = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                         it2 != m_rTree.end();
                         it2 = m_flat ? m_rTree.getNextLeaf( it2 )
                                      : m_rTree.getNextVisibleItem( it2 ) )
                    {
                        it2->setSelected( false );
                    }
                    // Select the new item
                    if( it != m_rTree.end() )
                    {
                        it->setSelected( true );
                        m_pLastSelected = &*it;
                    }
                }
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:dblclick" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
               // Execute the action associated to this item
               m_rTree.action( &*it );
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
    }

    else if( rEvent.getAsString().find( "scroll" ) != string::npos )
    {
        // XXX ctrl_slider.cpp has two more (but slightly different)
        // XXX implementations of `scroll'. Figure out where it belongs.

        int direction = static_cast<EvtScroll&>(rEvent).getDirection();

        double percentage = m_rTree.getPositionVar().get();
        double step = 2.0 / (double)( m_flat ? m_rTree.countLeafs()
                                             : m_rTree.visibleItems() );
        if( direction == EvtScroll::kUp )
        {
            percentage += step;
        }
        else
        {
            percentage -= step;
        }
        m_rTree.getPositionVar().set( percentage );
    }

    /* We changed the nodes, let's fix the position var */
    if( bChangedPosition )
    {
        VarTree::Iterator it;
        int iFirst = 0;
        for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
             it != m_rTree.end();
             it = m_flat ? m_rTree.getNextLeaf( it )
                         : m_rTree.getNextVisibleItem( it ) )
        {
            if( it == m_firstPos )
                break;
            iFirst++;
        }

        int indexMax = ( m_flat ? m_rTree.countLeafs()
                                : m_rTree.visibleItems() ) - 1;
        float f_new = (float)iFirst / (float)indexMax;

        m_dontMove = true;
        m_rTree.getPositionVar().set( 1.0 - f_new );
        m_dontMove = false;
    }
}
Example #25
0
AlarmListView::AlarmListView(const QValueList<int> &order, QWidget *parent, const char *name)
    : EventListViewBase(parent, name),
      mMousePressed(false),
      mDrawMessageInColour(false),
      mShowExpired(false)
{
    static QString titles[COLUMN_COUNT] =
    {
        i18n("Time"),
        i18n("Time To"),
        i18n("Repeat"),
        QString::null,
        QString::null,
        i18n("Message, File or Command")
    };

    setSelectionMode(QListView::Extended);

    // Set the column order
    int i;
    bool ok = false;
    if(order.count() >= COLUMN_COUNT)
    {
        // The column order is specified
        bool posns[COLUMN_COUNT];
        for(i = 0;  i < COLUMN_COUNT;  ++i)
            posns[i] = false;
        for(i = 0;  i < COLUMN_COUNT;  ++i)
        {
            int ord = order[i];
            if(ord < COLUMN_COUNT  &&  ord >= 0)
            {
                mColumn[i] = ord;
                posns[ord] = true;
            }
        }
        ok = true;
        for(i = 0;  i < COLUMN_COUNT;  ++i)
            if(!posns[i])
                ok = false;
        if(ok  &&  mColumn[MESSAGE_COLUMN] != MESSAGE_COLUMN)
        {
            // Shift the message column to be last, since otherwise
            // column widths get screwed up.
            int messageCol = mColumn[MESSAGE_COLUMN];
            for(i = 0;  i < COLUMN_COUNT;  ++i)
                if(mColumn[i] > messageCol)
                    --mColumn[i];
            mColumn[MESSAGE_COLUMN] = MESSAGE_COLUMN;
        }
    }
    if(!ok)
    {
        // Either no column order was specified, or it was invalid,
        // so use the default order
        for(i = 0;  i < COLUMN_COUNT;  ++i)
            mColumn[i] = i;
    }

    // Initialise the columns
    for(i = 0;  i < COLUMN_COUNT;  ++i)
    {
        for(int j = 0;  j < COLUMN_COUNT;  ++j)
            if(mColumn[j] == i)
            {
                if(j != MESSAGE_COLUMN)
                    addColumn(titles[j]);
                break;
            }
    }
    addLastColumn(titles[MESSAGE_COLUMN]);

    setSorting(mColumn[TIME_COLUMN]);           // sort initially by date/time
    mTimeColumnHeaderWidth   = columnWidth(mColumn[TIME_COLUMN]);
    mTimeToColumnHeaderWidth = columnWidth(mColumn[TIME_TO_COLUMN]);
    setColumnAlignment(mColumn[REPEAT_COLUMN], Qt::AlignHCenter);
    setColumnWidthMode(mColumn[REPEAT_COLUMN], QListView::Maximum);

    // Set the width of the colour column in proportion to height
    setColumnWidth(mColumn[COLOUR_COLUMN], itemHeight() * 3 / 4);
    setColumnWidthMode(mColumn[COLOUR_COLUMN], QListView::Manual);

    // Set the width of the alarm type column to exactly accommodate the icons.
    // Don't allow the user to resize it (to avoid refresh problems, and bearing
    // in mind that resizing doesn't seem very useful anyway).
    setColumnWidth(mColumn[TYPE_COLUMN], AlarmListViewItem::typeIconWidth(this));
    setColumnWidthMode(mColumn[TYPE_COLUMN], QListView::Manual);
    header()->setResizeEnabled(false, mColumn[TYPE_COLUMN]);

    mInstanceList.append(this);

    mTooltip = new AlarmListTooltip(viewport());
}
Example #26
0
void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
    bool bChangedPosition = false;
    VarTree::Iterator toShow; bool needShow = false;
    if( rEvent.getAsString().find( "key:down" ) != string::npos )
    {
        int key = ((EvtKey&)rEvent).getKey();
        VarTree::Iterator it;
        bool previousWasSelected = false;

        /* Delete the selection */
        if( key == KEY_DELETE )
        {
            /* Find first non selected item before m_pLastSelected */
            VarTree::Iterator it_sel = m_flat ? m_rTree.firstLeaf()
                                              : m_rTree.begin();
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                if( &*it == m_pLastSelected ) break;
                if( !it->m_selected ) it_sel = it;
            }

            /* Delete selected stuff */
            m_rTree.delSelected();

            /* Select it_sel */
            it_sel->m_selected = true;
            m_pLastSelected = &*it_sel;
        }
        else if( key == KEY_PAGEDOWN )
        {
            it = m_firstPos;
            int i = (int)(maxItems()*1.5);
            while( i >= 0 )
            {
                VarTree::Iterator it_old = it;
                it = m_flat ? m_rTree.getNextLeaf( it )
                            : m_rTree.getNextVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == m_rTree.end() )
                {
                    it = it_old;
                    break;
                }
                needShow = true;
                i--;
            }
            if( needShow )
            {
                ensureVisible( it );
                makeImage();
                notifyLayout();
                return;
            }
        }
        else if (key == KEY_PAGEUP )
        {
            it = m_firstPos;
            int i = maxItems();
            while( i >= maxItems()/2 )
            {
                it = m_flat ? m_rTree.getPrevLeaf( it )
                            : m_rTree.getPrevVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == ( m_flat ? m_rTree.firstLeaf() : m_rTree.begin() ) )
                {
                    break;
                }
                i--;
            }
            ensureVisible( it );
            makeImage();
            notifyLayout();
            return;
        }


        for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
             it != m_rTree.end();
             it = m_flat ? m_rTree.getNextLeaf( it )
                         : m_rTree.getNextVisibleItem( it ) )
        {
            VarTree::Iterator next = m_flat ? m_rTree.getNextLeaf( it )
                                            : m_rTree.getNextVisibleItem( it );
            if( key == KEY_UP )
            {
                // Scroll up one item
                if( ( it->parent()
                      && it != it->parent()->begin() )
                    || &*it != m_pLastSelected )
                {
                    bool nextWasSelected = ( &*next == m_pLastSelected );
                    it->m_selected = nextWasSelected;
                    if( nextWasSelected )
                    {
                        m_pLastSelected = &*it;
                        needShow = true; toShow = it;
                    }
                }
            }
            else if( key == KEY_DOWN )
            {
                // Scroll down one item
                if( ( it->parent()
                      && next != it->parent()->end() )
                    || &*it != m_pLastSelected )
                {
                    (*it).m_selected = previousWasSelected;
                }
                if( previousWasSelected )
                {
                    m_pLastSelected = &*it;
                    needShow = true; toShow = it;
                    previousWasSelected = false;
                }
                else
                {
                    previousWasSelected = ( &*it == m_pLastSelected );
                }

                // Fix last tree item selection
                if( ( m_flat ? m_rTree.getNextLeaf( it )
                    : m_rTree.getNextVisibleItem( it ) ) == m_rTree.end()
                 && &*it == m_pLastSelected )
                {
                    (*it).m_selected = true;
                }
            }
            else if( key == KEY_RIGHT )
            {
                // Go down one level (and expand node)
                if( &*it == m_pLastSelected )
                {
                    if( it->m_expanded )
                    {
                        if( it->size() )
                        {
                            it->m_selected = false;
                            it->begin()->m_selected = true;
                            m_pLastSelected = &*(it->begin());
                        }
                        else
                        {
                            m_rTree.action( &*it );
                        }
                    }
                    else
                    {
                        it->m_expanded = true;
                        bChangedPosition = true;
                    }
                }
            }
            else if( key == KEY_LEFT )
            {
                // Go up one level (and close node)
                if( &*it == m_pLastSelected )
                {
                    if( it->m_expanded && it->size() )
                    {
                        it->m_expanded = false;
                        bChangedPosition = true;
                    }
                    else
                    {
                        if( it->parent() && it->parent() != &m_rTree)
                        {
                            it->m_selected = false;
                            m_pLastSelected = it->parent();
                            m_pLastSelected->m_selected = true;
                        }
                    }
                }
            }
            else if( key == KEY_ENTER || key == ' ' )
            {
                // Go up one level (and close node)
                if( &*it == m_pLastSelected )
                {
                    m_rTree.action( &*it );
                }
            }
        }
        if( needShow )
            ensureVisible( toShow );

        // Redraw the control
        makeImage();
        notifyLayout();
    }

    else if( rEvent.getAsString().find( "mouse:left" ) != string::npos )
    {
        EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
        const Position *pos = getPosition();
        int yPos = ( rEvtMouse.getYPos() - pos->getTop() ) / itemHeight();
        int xPos = rEvtMouse.getXPos() - pos->getLeft();
        VarTree::Iterator it;

        if( rEvent.getAsString().find( "mouse:left:down:ctrl,shift" ) !=
            string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->m_selected = (*it).m_selected || select;
                select = nextSelect;
            }
        }
        else if( rEvent.getAsString().find( "mouse:left:down:ctrl" ) !=
                 string::npos )
        {
            // Invert the selection of the item
            it = findItemAtPos( yPos );
            if( it != m_rTree.end() )
            {
                it->m_selected = !it->m_selected;
                m_pLastSelected = &*it;
            }
        }
        else if( rEvent.getAsString().find( "mouse:left:down:shift" ) !=
                 string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->m_selected = select;
                select = nextSelect;
            }
        }
        else if( rEvent.getAsString().find( "mouse:left:down" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
                if( ( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
                      && xPos < it->depth() * itemImageWidth() )
                 && !m_flat )
                {
                    // Fold/unfold the item
                    it->m_expanded = !it->m_expanded;
                    bChangedPosition = true;
                }
                else
                {
                    // Unselect any previously selected item
                    VarTree::Iterator it2;
                    for( it2 = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                         it2 != m_rTree.end();
                         it2 = m_flat ? m_rTree.getNextLeaf( it2 )
                                      : m_rTree.getNextVisibleItem( it2 ) )
                    {
                        it2->m_selected = false;
                    }
                    // Select the new item
                    if( it != m_rTree.end() )
                    {
                        it->m_selected = true;
                        m_pLastSelected = &*it;
                    }
                }
            }
        }

        else if( rEvent.getAsString().find( "mouse:left:dblclick" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
               // Execute the action associated to this item
               m_rTree.action( &*it );
            }
        }
        // Redraw the control
        makeImage();
        notifyLayout();
    }

    else if( rEvent.getAsString().find( "scroll" ) != string::npos )
    {
        int direction = ((EvtScroll&)rEvent).getDirection();

        double percentage = m_rTree.getPositionVar().get();
        double step = 2.0 / (double)( m_flat ? m_rTree.countLeafs()
                                             : m_rTree.visibleItems() );
        if( direction == EvtScroll::kUp )
        {
            percentage += step;
        }
        else
        {
            percentage -= step;
        }
        m_rTree.getPositionVar().set( percentage );
    }

    /* We changed the nodes, let's fix teh position var */
    if( bChangedPosition )
    {
        VarTree::Iterator it;
        int i = 0;
        int iFirst = 0;
        for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
             it != m_rTree.end();
             it = m_flat ? m_rTree.getNextLeaf( it )
                         : m_rTree.getNextVisibleItem( it ) )
        {
            i++;
            if( it == m_firstPos )
            {
                iFirst = i;
                break;
            }
        }
        iFirst += maxItems();
        if( iFirst >= m_flat ? m_rTree.countLeafs() : m_rTree.visibleItems() )
            iFirst = m_flat ? m_rTree.countLeafs() : m_rTree.visibleItems();
        float f_new = (float)iFirst / (float)( m_flat ? m_rTree.countLeafs()
                                                      :m_rTree.visibleItems() );
        m_dontMove = true;
        m_rTree.getPositionVar().set( 1.0 - f_new );
        m_dontMove = false;
    }
}
void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
    bool needShow = false;
    bool needRefresh = false;
    Iterator toShow = m_firstPos;
    if( rEvent.getAsString().find( "key:down" ) != string::npos )
    {
        int key = ((EvtKey&)rEvent).getKey();

        /* Delete the selection */
        if( key == KEY_DELETE )
        {
            /* Delete selected stuff */
            m_rTree.delSelected();
        }
        else if( key == KEY_PAGEDOWN )
        {
            int numSteps = (int)m_capacity / 2;
            VarPercent &rVarPos = m_rTree.getPositionVar();
            rVarPos.increment( -numSteps );
        }
        else if( key == KEY_PAGEUP )
        {
            int numSteps = (int)m_capacity / 2;
            VarPercent &rVarPos = m_rTree.getPositionVar();
            rVarPos.increment( numSteps );
        }
        else if( key == KEY_UP )
        {
            // Scroll up one item
            m_rTree.unselectTree();
            if( m_lastClicked != m_rTree.end() )
            {
                if( --m_lastClicked != m_rTree.end() )
                {
                    m_lastClicked->setSelected( true );
                }
            }
            if( m_lastClicked == m_rTree.end() )
            {
                m_lastClicked = m_firstPos;
                if( m_lastClicked != m_rTree.end() )
                    m_lastClicked->setSelected( true );
            }
            needRefresh = true;
            needShow = true; toShow = m_lastClicked;
        }
        else if( key == KEY_DOWN )
        {
            // Scroll down one item
            m_rTree.unselectTree();
            if( m_lastClicked != m_rTree.end() )
            {
                Iterator it_old = m_lastClicked;
                if( ++m_lastClicked != m_rTree.end() )
                {
                    m_lastClicked->setSelected( true );
                }
                else
                {
                    it_old->setSelected( true );
                    m_lastClicked = it_old;
                }
            }
            else
            {
                m_lastClicked = m_firstPos;
                if( m_lastClicked != m_rTree.end() )
                    m_lastClicked->setSelected( true );
            }
            needRefresh = true;
            needShow = true; toShow = m_lastClicked;
        }
        else if( key == KEY_RIGHT )
        {
            // Go down one level (and expand node)
            Iterator& it = m_lastClicked;
            if( it != m_rTree.end() )
            {
                if( !m_flat && !it->isExpanded() && it->size() )
                {
                    it->setExpanded( true );
                    needRefresh = true;
                }
                else
                {
                    m_rTree.unselectTree();
                    Iterator it_old = m_lastClicked;
                    if( ++m_lastClicked != m_rTree.end() )
                    {
                        m_lastClicked->setSelected( true );
                    }
                    else
                    {
                        it_old->setSelected( true );
                        m_lastClicked = it_old;
                    }
                    needRefresh = true;
                    needShow = true; toShow = m_lastClicked;
                }
            }
        }
        else if( key == KEY_LEFT )
        {
            // Go up one level (and close node)
            Iterator& it = m_lastClicked;
            if( it != m_rTree.end() )
            {
                if( m_flat )
                {
                    m_rTree.unselectTree();
                    if( --m_lastClicked != m_rTree.end() )
                    {
                        m_lastClicked->setSelected( true );
                    }
                    else
                    {
                        m_lastClicked = m_firstPos;
                        if( m_lastClicked != m_rTree.end() )
                            m_lastClicked->setSelected( true );
                    }
                    needRefresh = true;
                    needShow = true; toShow = m_lastClicked;
                }
                else
                {
                    if( it->isExpanded() )
                    {
                        it->setExpanded( false );
                        needRefresh = true;
                    }
                    else
                    {
                        Iterator it_parent = it.getParent();
                        if( it_parent != m_rTree.end() )
                        {
                            it->setSelected( false );
                            m_lastClicked = it_parent;
                            m_lastClicked->setSelected( true );
                            needRefresh = true;
                            needShow = true; toShow = m_lastClicked;
                        }
                    }
                }
            }
        }
        else if( key == KEY_ENTER || key == ' ' )
        {
            // Go up one level (and close node)
            if( m_lastClicked != m_rTree.end() )
            {
                m_rTree.action( &*m_lastClicked );
            }
        }
        else
        {
            // other keys to be forwarded to vlc core
            EvtKey& rEvtKey = (EvtKey&)rEvent;
            var_SetInteger( getIntf()->p_libvlc, "key-pressed",
                            rEvtKey.getModKey() );
        }
    }

    else if( rEvent.getAsString().find( "mouse:left" ) != string::npos )
    {
        EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
        const Position *pos = getPosition();
        int xPos = rEvtMouse.getXPos() - pos->getLeft();
        int yPos = ( rEvtMouse.getYPos() - pos->getTop() ) / itemHeight();

        Iterator itClicked = findItemAtPos( yPos );
        if( itClicked != m_rTree.end() )
        {
            if( rEvent.getAsString().find( "mouse:left:down:ctrl,shift" ) !=
                string::npos )
            {
                // Flag to know if the current item must be selected
                bool select = false;
                for( Iterator it = m_firstPos; it != m_rTree.end(); ++it )
                {
                    bool nextSelect = select;
                    if( it == itClicked || it == m_lastClicked )
                    {
                        if( select )
                        {
                            nextSelect = false;
                        }
                        else
                        {
                            select = true;
                            if( itClicked != m_lastClicked )
                                nextSelect = true;
                        }
                    }
                    it->setSelected( it->isSelected() || select );
                    select = nextSelect;
                    needRefresh = true;
                }
            }
            else if( rEvent.getAsString().find( "mouse:left:down:ctrl" ) !=
                     string::npos )
            {
                // Invert the selection of the item
                itClicked->toggleSelected();
                m_lastClicked = itClicked;
                needRefresh = true;
            }
            else if( rEvent.getAsString().find( "mouse:left:down:shift" ) !=
                     string::npos )
            {
                bool select = false;
                for( Iterator it = m_firstPos; it != m_rTree.end(); ++it )
                {
                    bool nextSelect = select;
                    if( it == itClicked || it == m_lastClicked )
                    {
                        if( select )
                        {
                            nextSelect = false;
                        }
                        else
                        {
                            select = true;
                            if( itClicked != m_lastClicked )
                                nextSelect = true;
                        }
                    }
                    it->setSelected( select );
                    select = nextSelect;
                }
                needRefresh = true;
            }
            else if( rEvent.getAsString().find( "mouse:left:down" ) !=
                     string::npos )
            {
                if( !m_flat &&
                    itClicked->size() &&
                    xPos > (itClicked->depth() - 1) * itemImageWidth() &&
                    xPos < itClicked->depth() * itemImageWidth() )
                {
                    // Fold/unfold the item
                    itClicked->toggleExpanded();
                }
                else
                {
                    // Unselect any previously selected item
                    m_rTree.unselectTree();
                    // Select the new item
                    itClicked->setSelected( true );
                    m_lastClicked = itClicked;
                }
                needRefresh = true;
            }
            else if( rEvent.getAsString().find( "mouse:left:dblclick" ) !=
                     string::npos )
            {
               // Execute the action associated to this item
               m_rTree.action( &*itClicked );
            }
        }
    }

    else if( rEvent.getAsString().find( "scroll" ) != string::npos )
    {
        int direction = static_cast<EvtScroll&>(rEvent).getDirection();
        if( direction == EvtScroll::kUp )
            m_rTree.getPositionVar().increment( +1 );
        else
            m_rTree.getPositionVar().increment( -1 );
    }

    else if( rEvent.getAsString().find( "drag:over" ) != string::npos )
    {
        EvtDragOver& evt = static_cast<EvtDragOver&>(rEvent);
        const Position *pos = getPosition();
        int yPos = ( evt.getYPos() - pos->getTop() ) / itemHeight();

        Iterator it = findItemAtPos( yPos );
        if( it != m_itOver )
        {
            m_itOver = it;
            needRefresh = true;
        }
    }

    else if( rEvent.getAsString().find( "drag:drop" ) != string::npos )
    {
        EvtDragDrop& evt = static_cast<EvtDragDrop&>(rEvent);
        Playtree& rPlaytree = static_cast<Playtree&>(m_rTree);
        VarTree& item = ( m_itOver != m_rTree.end() ) ? *m_itOver : m_rTree;
        rPlaytree.insertItems( item, evt.getFiles(), false );
        m_itOver = m_rTree.end();
        needRefresh = true;
    }

    else if( rEvent.getAsString().find( "drag:leave" ) != string::npos )
    {
        m_itOver = m_rTree.end();
        needRefresh = true;
    }

    if( needShow )
    {
        if( toShow == m_rTree.end() ||
            !ensureVisible( toShow ) )
            needRefresh = true;
    }
    if( needRefresh )
    {
        setSliderFromFirst();

        makeImage();
        notifyLayout();
    }
}