view layout_view.cpp @ 10:877a005c2b42

Layout designer: WidgetView class, with two types: WidgetViewItem and WidgetViewBox which contains items.
author Goffi <goffi@goffi.org>
date Fri, 26 Aug 2011 15:58:46 +0200
parents 0d7875c26974
children 98485ebbdb86
line wrap: on
line source

/*
Bellaciao: a Salut à Toi frontend
Copyright (C) 2011  Jérôme Poisson (goffi@goffi.org)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "layout_view.h"
#include <QDebug>

WidgetView::WidgetView(const QString& name)
{
    qDebug() << "Contructeur WidgetView";
}

WidgetView::~WidgetView()
{
    qDebug() << "Destructeur WidgetView";
}

WidgetViewItem::WidgetViewItem(const QString& name)
    : QLabel(name), WidgetView(name)
{
}

WidgetViewBox::WidgetViewBox(const QString& name)
    : WidgetView(name)
{
    setWidget(new LayoutView(0, HORIZONTAL));
}

LayoutView::LayoutView(QWidget* parent, LayoutDirection direction)
    : m_direction(direction)
{
    setAcceptDrops(true);
    if (m_direction == VERTICAL)
        m_layout = new QVBoxLayout;
    else
        m_layout = new QHBoxLayout;
    setLayout(m_layout);
    m_layout->addStretch();
    setStyleSheet("WidgetViewItem {border: 1px solid black; \
                           border-radius: 5px; \
                           text-align: center; \
                           background-color: white; \
                           min-height: 20px; \
                           max-height: 20px; \
                           margin: 2px; \
                           }");
}

LayoutView::~LayoutView()
{
}
        
void LayoutView::setLayoutWidgets(const QHash<QString, LayoutWidget*>& layout_widgets)
{
    m_layout_widgets = layout_widgets;
}
        
void LayoutView::dragEnterEvent (QDragEnterEvent* event )
{
    if (event->mimeData()->hasFormat(LAYOUT_WIDGET_MIME))
        event->acceptProposedAction();
}
        
void LayoutView::dragLeaveEvent (QDragLeaveEvent* event )
{
    m_loc_hint.setCoords(1,1,0,0); //We make the QRect invalid to hide it
    update();
}


void LayoutView::dragMoveEvent (QDragMoveEvent* event )
{
    int ref_pos = m_direction == VERTICAL ? event->pos().y() : event->pos().x();
    int hint_start = 0;
    int pos_start, pos_end;
    QList<QWidget*>  _children = findChildren<QWidget*>("");
   
    QWidget* wid = 0;

    for (m_insert_pos=0; m_insert_pos<layout()->count()-1; m_insert_pos++) {
        wid = layout()->itemAt(m_insert_pos)->widget();
        
        if (m_direction == VERTICAL) {
            pos_start = wid->geometry().top();
            pos_end = wid->geometry().bottom();
        }
        else {
            pos_start = wid->geometry().left();
            pos_end = wid->geometry().right();
        }

        if (pos_end > ref_pos && pos_start < ref_pos) {
            //We are inside a widget, we break here
            hint_start = pos_end;
            m_insert_pos++;
            break;
        }
        else if (pos_start > ref_pos)
            //we are too far, we stop
            break;
        
        hint_start = pos_end;
    }
    
    if (m_direction == VERTICAL)
        m_loc_hint.setRect(5, hint_start+1, qMax(5,width()-10), 5);
    else
        m_loc_hint.setRect(hint_start+1, 5, 5, qMax(5,height()-10));
    update();
}

void LayoutView::dropEvent (QDropEvent* event)
{
    m_loc_hint.setCoords(1,1,0,0); //We make the QRect invalid to hide it
    update();
    const QMimeData *data = event->mimeData();
    QByteArray encodedData = data->data(LAYOUT_WIDGET_MIME);
    QDataStream stream(&encodedData, QIODevice::ReadOnly);
    while (!stream.atEnd()) {
        QString widget_name;
        stream >> widget_name;
        addWidget(widget_name);
    } 
}

void LayoutView::addWidget(const QString& name)
{
    LayoutWidget* _widget = m_layout_widgets[name];
    WidgetView* _widget_view;
    if (name == "Box") {
        _widget_view = new WidgetViewBox(name);
    }
    else {
        _widget_view = new WidgetViewItem(name);
        reinterpret_cast<WidgetViewItem*>(_widget_view)->setAlignment(Qt::AlignCenter);
    }
    m_layout->insertWidget(m_insert_pos, reinterpret_cast<QWidget*>(_widget_view), 0, Qt::AlignTop);

}

void LayoutView::paintEvent(QPaintEvent* event)
{
   if (m_loc_hint.isValid()) {
       QPainter newPainter(this);
       newPainter.fillRect(m_loc_hint, Qt::blue);
   }
}