[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-panel-devel
Subject:    [Fwd: Re: [Bug 164805] Multiple columns in kick off]
From:       Bernhard Friedreich <friesoft () gmail ! com>
Date:       2009-04-28 13:43:04
Message-ID: 49F707E8.9030002 () googlemail ! com
[Download RAW message or body]

Hey!

I'm forwarding this mail because I'd really like to see multiple columns 
in kickoff (in 4.3). Afaik hard feature freaze is next week so it must 
go in "now"...

The original author of the patch has no time to complete it and I don't 
know if I'll have the skills/time to do so.. so I just bring up this 
topic again in hope that someone can volunteer and bring that patch to 
shape (if even neccessary).

I applied it some time ago and it worked without any major problems. (I 
would have tried with newer trunk but unfurtunately I'm atm bound to 
Windows cause of school :-( )

Attached you can find the patch from Luiz Felipe Talvik. All the credit 
goes to him.. I was just the one reminding him of this feature from time 
to time :D

I really hope this will end up in trunk.. otherwise I'll try to get it 
ready at least for 4.4..

Thanks!

Best regards,
Bernhard Friedreich

PS: If anyone wants to put this on reviewboard.. no problem.. I just 
couldn't figure out what to do with the base path thingy ^^

["screenshot.png" (image/png)]
["urlitemview.patch" (text/plain)]

--- urlitemview.cpp.orig2	2009-02-22 22:30:12.000000000 -0300
+++ urlitemview.cpp	2009-02-24 19:40:44.000000000 -0300
@@ -41,6 +41,8 @@
 #include "core/kickoffmodel.h"
 #include "ui/itemdelegate.h"
 
+#include<cmath>
+
 using namespace Kickoff;
 
 class UrlItemView::Private
@@ -62,84 +64,181 @@
         }
 
         int verticalOffset = ItemDelegate::TOP_OFFSET;
-        int horizontalOffset = 0;
-        int row = 0;
-        int visualColumn = 0;
-
-        QModelIndex branch = currentRootIndex;
-
-        while (true) {
-            if (itemChildOffsets[branch] + row >= q->model()->rowCount(branch) ||
-                    (branch != currentRootIndex && row > MAX_CHILD_ROWS)) {
-
-                if (branch.isValid()) {
-                    row = branch.row() + 1;
-                    branch = branch.parent();
-                    continue;
-                } else {
-                    break;
+                int horizontalOffset = 0;
+                int row = 0;
+                int headerCount = 0;
+                int childCount = 0;
+                int verticalSize = ItemDelegate::TOP_OFFSET;
+                int itemVerticalSize = 0;
+                QList<int> sectionVerticalSize;
+                QList<int> sectionItemCount;
+                QList<QModelIndex> itemOrder;
+
+
+                QModelIndex branch = currentRootIndex;
+                numberColumns = 1;
+
+                //reads items list and estimates size needed
+                while (true) {
+                    if (itemChildOffsets[branch]+row >= q->model()->rowCount(branch) \
|| +                        (branch != currentRootIndex && row > MAX_CHILD_ROWS)) {
+                        if (branch.isValid()) {
+                            row = branch.row()+1;
+                            branch = branch.parent();
+                            continue;
+                        } else {
+                            break;
+                        }
+                    }
+
+                    QModelIndex child = \
q->model()->index(row+itemChildOffsets[branch],0,branch); +
+                    if (q->model()->hasChildren(child)) {
+                        QSize childSize = calculateHeaderSize(child);
+                        QRect rect(QPoint(ItemDelegate::HEADER_LEFT_MARGIN, 0), \
childSize); +                        if (childSize.isValid()) {
+                            itemRects.insert(child, rect);
+                            itemOrder<<child;
+                            headerCount++;
+                            sectionVerticalSize.append(childSize.height());
+                            sectionItemCount.append(0);
+                            if ((verticalSize + childSize.height()) > \
contentHeight()) { +                                verticalSize = \
headerVerticalOffset+ItemDelegate::TOP_OFFSET; +                                \
numberColumns++; +                            }
+                            verticalSize += childSize.height();
+                            if (isFirstHeader(child)) headerVerticalOffset = \
childSize.height(); +                        }
+                        QRect rect2(QPoint(ItemDelegate::HEADER_LEFT_MARGIN, \
verticalOffset), childSize); +                        //kDebug() << "header rect for" \
<< child.data(Qt::DisplayRole) << "is" << rect; +                        \
itemRects.insert(child, rect2); +
+                        if (childSize.isValid()) {
+                            // don't subtract 1
+                            // verticalOffset += childSize.height();
+                        }
+                        horizontalOffset = 0;
+                        branch = child;
+                        row = 0;
+                    } else {
+                        QSize childSize = calculateItemSize(child);
+                        //kDebug() << "item rect for" << child.data(Qt::DisplayRole) \
<< "is" << QRect(QPoint(horizontalOffset,verticalOffset), childSize); +
+                        itemRects.insert(child,QRect(QPoint(0,0),childSize));
+
+                        if (childSize.isValid()) {
+                            visualOrder << child;
+                            itemOrder<<child;
+                            childCount++;
+                            sectionVerticalSize[headerCount-1] += \
childSize.height(); +                            sectionItemCount[headerCount-1]++;
+                            if ((verticalSize + childSize.height()) > \
contentHeight()) { +                                verticalSize = \
headerVerticalOffset+ItemDelegate::TOP_OFFSET; +                                \
numberColumns++; +                            }
+                            verticalSize += childSize.height();
+
+                            itemVerticalSize = childSize.height();
+                        }
+
+                        row++;
+
+                        bool wasLastRow = row+itemChildOffsets[branch] >= \
q->model()->rowCount(branch); +                        bool nextItemIsBranch = false;
+                        if (!wasLastRow) {
+                            QModelIndex nextIndex \
=q->model()->index(row+itemChildOffsets[branch],0,branch); +                          \
nextItemIsBranch = q->model()->hasChildren(nextIndex); +                        }
+
+
+                        if (childSize.isValid()) {
+                            // don't subtract 1
+//                             verticalOffset += childSize.height();
+                        }
+                    }
                 }
-            }
 
-            QModelIndex child = q->model()->index(row + itemChildOffsets[branch], 0, \
branch); +                QModelIndex currentChild;
+                QRect rect;
+                int itemsSet=0;
+                int headersSet=0;
+                int visualColumn = 0;
+                contentsHeight = 0;
+                int itemsPerColumn = 0;
+                int resetVertOffset =0;
+                int extraItem =0;
+                int lowestItem = 0;
+                bool extraItemSet = false;
+
+                //logic for setting up the layout
+                foreach(currentChild,itemOrder){
+                    rect = itemRects.value(currentChild);
+
+                    if (q->model()->hasChildren(currentChild)){
+                        //number of columns will be max possible except when the the \
number of items is lower +                        if (sectionItemCount[headersSet] > \
getMaxColumns()) { +                            numberColumns = getMaxColumns();
+                        } else {
+                            numberColumns = sectionItemCount[headersSet];
+                        }
+                        horizontalOffset = 0;
+                        headersSet++;
+                        resetVertOffset = verticalOffset+rect.height();
+
+                        if(isFirstHeader(currentChild)) \
rect.setHeight(headerVerticalOffset); +                        itemsSet=0;
+                        visualColumn=0;
+                        itemsPerColumn = \
sectionItemCount[headersSet-1]/numberColumns; +
+                        extraItem = sectionItemCount[headersSet-1]%numberColumns;
+                        extraItemSet = false;
+                        if (verticalOffset<lowestItem) {
+                            verticalOffset = lowestItem;
+                            resetVertOffset = lowestItem+rect.height();
+                        }
+
+                    } else {
+                        itemsSet++;
+                    }
+
+                    //moves to next column
+                    if (itemsSet > itemsPerColumn && \
visualColumn<(getMaxColumns()-1)){ +                        if (extraItem<=0 || \
extraItemSet){ +                            if (verticalOffset>lowestItem) lowestItem \
= verticalOffset; +                            verticalOffset = resetVertOffset;
+                            horizontalOffset += contentWidth()/numberColumns;
+                            visualColumn++;
+                            itemsSet=1;
+                            extraItemSet = false;
+                        } else {
+                            extraItem--;
+                            extraItemSet = true;
+                        }
+
+                    }
+
+                    //positioning the items
+                    int tempHeight = rect.height();
+                    rect.setY(verticalOffset);
+                    rect.setX(horizontalOffset);
+                    rect.setHeight(tempHeight);
+                    rect.setWidth(contentWidth()/numberColumns);
+                    if (q->model()->hasChildren(currentChild)) {  //header occupies \
entire width +                            rect.setWidth(contentWidth());
+                    }
+                    verticalOffset += rect.height();
 
-            if (q->model()->hasChildren(child)) {
-                QSize childSize = calculateHeaderSize(child);
-                QRect rect(QPoint(ItemDelegate::HEADER_LEFT_MARGIN, verticalOffset), \
                childSize);
-                //kDebug() << "header rect for" << child.data(Qt::DisplayRole) << \
                "is" << rect;
-                itemRects.insert(child, rect);
-
-                if (childSize.isValid()) {
-                    // don't subtract 1
-                    verticalOffset += childSize.height();
+                    itemRects[currentChild] = rect;
+                    if (verticalOffset>contentsHeight) contentsHeight = \
verticalOffset;  }
-                horizontalOffset = 0;
-                branch = child;
-                row = 0;
-                visualColumn = 0;
-            } else {
-                QSize childSize = calculateItemSize(child);
-                //kDebug() << "item rect for" << child.data(Qt::DisplayRole) << "is" \
<< QRect(QPoint(horizontalOffset,verticalOffset), childSize);  
-                itemRects.insert(child, QRect(QPoint(horizontalOffset, \
                verticalOffset),
-                                              childSize));
-
-                if (childSize.isValid()) {
-                    visualOrder << child;
-                }
-
-                horizontalOffset += contentWidth() / MAX_COLUMNS;
-
-                visualColumn++;
-                row++;
-
-                bool wasLastRow = row + itemChildOffsets[branch] >= \
                q->model()->rowCount(branch);
-                bool nextItemIsBranch = false;
-                if (!wasLastRow) {
-                    QModelIndex nextIndex = q->model()->index(row + \
                itemChildOffsets[branch], 0, branch);
-                    nextItemIsBranch = q->model()->hasChildren(nextIndex);
-                }
-
-                if (visualColumn >= MAX_COLUMNS || wasLastRow || nextItemIsBranch) {
-                    horizontalOffset = 0;
-                    visualColumn = 0;
-                }
-
-                if (childSize.isValid()) {
-                    // don't subtract 1
-                    verticalOffset += childSize.height();
-                }
-            }
-        }
-        contentsHeight = verticalOffset;
-
-        updateScrollBarRange();
+                updateScrollBarRange();
     }
 
     void drawHeader(QPainter *painter,
                     const QModelIndex& index,
-                    const QStyleOptionViewItem& option) {
-        const bool first = isFirstHeader(index);
+                    const QStyleOptionViewItem& option,
+                    bool first) {
         const int rightMargin = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) \
+ 6;  const int dy = (first ? 4 : ItemDelegate::HEADER_TOP_MARGIN);
 
@@ -167,6 +266,31 @@
         painter->restore();
     }
 
+    void drawColumnSeparator(QPainter *painter,const QStyleOptionViewItem& option)
+    {
+
+        painter->save();
+        painter->setRenderHint(QPainter::Antialiasing, false);
+
+        int bottom = (contentsHeight>contentHeight() ? contentsHeight : \
contentHeight())-q->verticalScrollBar()->value(); +        int top = \
headerVerticalOffset+ItemDelegate::TOP_OFFSET-q->verticalScrollBar()->value(); +
+        QLinearGradient gradient(0,top ,0,bottom);
+        gradient.setColorAt(0.0, Qt::transparent);
+        gradient.setColorAt(0.1, option.palette.midlight().color());
+        gradient.setColorAt(0.5, option.palette.mid().color());
+        gradient.setColorAt(0.9, option.palette.midlight().color());
+        gradient.setColorAt(1.0, Qt::transparent);
+        painter->setPen(QPen(gradient, 1));
+
+        for (int i=1;i<numberColumns;i++){
+            painter->drawLine((columnWidth())*i, top,
+                              (columnWidth())*i, bottom);
+        }
+
+        painter->restore();
+    }
+
     void updateScrollBarRange() {
         int pageSize = q->height();
         q->verticalScrollBar()->setRange(0, contentsHeight - pageSize);
@@ -175,14 +299,25 @@
     }
 
     int contentWidth() const {
-        return q->width() - q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 2;
+        return q->width() - q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) - 4;
+    }
+
+    int contentHeight() const
+    {
+        return q->height();
+    }
+
+    int columnWidth() const
+    {
+        return contentWidth()/numberColumns;
     }
 
     QSize calculateItemSize(const QModelIndex& index) const {
         if (itemStateProvider && !itemStateProvider->isVisible(index)) {
             return QSize();
         } else {
-            return  QSize(contentWidth() / MAX_COLUMNS, \
q->sizeHintForIndex(index).height()); +             return  QSize(0, \
q->sizeHintForIndex(index).height()); +//              return  QSize(contentWidth() / \
MAX_COLUMNS, q->sizeHintForIndex(index).height());  }
     }
 
@@ -237,6 +372,11 @@
         return point - QPoint(0, q->verticalOffset());
     }
 
+    int getMaxColumns()
+    {
+        return ((contentWidth() / COLUMN_THRESHOLD == 0) ? 1 : (contentWidth() / \
COLUMN_THRESHOLD)); +    }
+
     UrlItemView * const q;
     QPersistentModelIndex currentRootIndex;
     QPersistentModelIndex hoveredIndex;
@@ -252,8 +392,11 @@
 
     int contentsHeight;
     ItemStateProvider *itemStateProvider;
+    int headerVerticalOffset;
 
-    static const int MAX_COLUMNS = 1;
+    //static const int MAX_COLUMNS = 1;
+    int numberColumns;
+    static const int COLUMN_THRESHOLD=280;
 
     // TODO Eventually it will be possible to restrict each branch to only showing
     // a given number of children, with Next/Previous arrows to view more children
@@ -445,6 +588,7 @@
 
     QPainter painter(viewport());
     painter.setRenderHint(QPainter::Antialiasing);
+    QStyleOptionViewItem option = viewOptions();
 
     if (d->dragging && dragDropMode() == QAbstractItemView::DragDrop) {
         const int y = (d->dropRect.top() + d->dropRect.bottom()) / 2;
@@ -481,12 +625,17 @@
             }
 
             if (model()->hasChildren(index)) {
-                d->drawHeader(&painter, index, option);
+                bool topHeader = itemRect.y() <= ItemDelegate::TOP_OFFSET;
+                d->drawHeader(&painter, index, option, topHeader);
             } else {
-                if (option.rect.left() == 0) {
+//                 if (option.rect.left() == 0) {
                     option.rect.setLeft(option.rect.left() + \
                ItemDelegate::ITEM_LEFT_MARGIN);
-                    option.rect.setRight(option.rect.right() - \
                ItemDelegate::ITEM_RIGHT_MARGIN);
-                }
+//                 }
+//                 else {
+//                     option.rect.setLeft(option.rect.left() + \
ItemDelegate::ITEM_RIGHT_MARGIN); +//                 }
+
+                option.rect.setRight(option.rect.right() - \
ItemDelegate::ITEM_RIGHT_MARGIN);  itemDelegate(index)->paint(&painter, option, \
index);  }
         }
@@ -654,7 +803,7 @@
             row--;
         }
 
-        model()->dropMimeData(event->mimeData(), event->dropAction(), 
+        model()->dropMimeData(event->mimeData(), event->dropAction(),
 							    row, 0, parent);
 
         d->dragging = false;


["Re: [Bug 164805] Multiple columns in kick off.eml" (message/rfc822)]

X-Account-Key: account5
X-Mozilla-Keys: 
Delivered-To: friesoft@gmail.com
Received: by 10.239.150.16 with SMTP id l16cs3101hbb;
        Tue, 28 Apr 2009 04:53:24 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.231.16.129 with SMTP id o1mr2576658iba.9.1240919603780; Tue, 
	28 Apr 2009 04:53:23 -0700 (PDT)
In-Reply-To: <49F60A18.1050901@googlemail.com>
References: <bug-164805-101565@http.bugs.kde.org/>
	 <20090214123827.D5B00128D0@immanuel.kde.org>
	 <98dc12ca0902141002l49db9f35x3846ab2116da6e39@mail.gmail.com>
	 <49972C41.9090408@googlemail.com>
	 <98dc12ca0902241624r7da43b36i443de29248e04a9b@mail.gmail.com>
	 <49D4C8A1.1030907@googlemail.com>
	 <98dc12ca0904020928x1a32f753p5a0e270db9bc22bf@mail.gmail.com>
	 <49F60A18.1050901@googlemail.com>
Date: Tue, 28 Apr 2009 08:53:23 -0300
Message-ID: <98dc12ca0904280453k1593fe85kc513e39fe1b161e6@mail.gmail.com>
Subject: Re: [Bug 164805] Multiple columns in kick off
From: Luiz Felipe Talvik <talvik@gmail.com>
To: Bernhard Friedreich <friesoft@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Hi,

I'm not having much free time lately. You can do anything you want
with it, I'm don't think the patch is going to make it.
If you need anything just ask.

Talvik

On Mon, Apr 27, 2009 at 4:40 PM, Bernhard Friedreich <friesoft@gmail.com> wrote:
> Hey!
>
> Ok.. so I keep poking :-D
>
> As far as I can remember next week or so is hard feature freeze -- meaning
> the feature must be in trunk (I think ^^) -- so what are we going to do?
> anything new you can show or shall I publish your work (of course under your
> name ^^) -- or do you want to do that yourself
>
> Just wondering what's going on because we are running out of time (not that
> I AM having any time ^^)
>
> Cya
> Bernhard
>
> Luiz Felipe Talvik schrieb:
>
> Hey.
>
> I have seen this email. About adding this feature to that list, can
> you do that? I don't know how it works.
> I'll really try finishin the patch today and get it on the mailing
> list tomorrow.
> I want to dedicate a couple of hours to kde dev but I'm a big
> procrastinator. :P
>
> Thanks for the poking and keep poking
> Talvik
>
> On Thu, Apr 2, 2009 at 11:16 AM, Bernhard Friedreich <friesoft@gmail.com>
> wrote:
>
>
> Hey!
>
> How's it going with the multiple columns kickoff? I'm especially asking
> because of the soft feature freeze for KDE 4.3... I'd propose you're adding
> the feature to the features list because I'm sure many would love to see
> this in 4.3
>
> If you want to I can take care of adding the entry.. really hope the work is
> falling into place as it should :-)
>
> Thanks for your time and effort :-)
>
> Regards,
> Bernhard Friedreich
>
> Luiz Felipe Talvik schrieb:
>
> Hi,
>
> took longer than I expected and it still isn't ready. I changed the
> behavior, it was getting to complex.
> This code is killing me, 1k lines per file, no comments, strange
> coding style. Application tab is totally different from the rest of
> the tabs, I'm still trying to read the code from apps tab.
>
> TODO urlitemview:
> kdelibs/plasma/delegate - isn't workin correctly with multiple columns
> (long names aren't restrained to the given area, look at snapshot)
> COLUMN_THRESHOLD - is hardcoded, it should be based on a certain
> number of chars and get the current style to calculate the lenght
>
> TODO app tab:
> EVERYTHING
>
>
> On Sat, Feb 14, 2009 at 5:40 PM, Bernhard Friedreich <friesoft@gmail.com>
> wrote:
>
>
> Hey!
>
> Glad to hear from you  :-)
>
> Yeah I've got *some* experience (2-3 smaller and bigger projects) in Qt and
> I'm at least partly familiar with most of the technical terms of plasma (but
> I haven't coded or looked at any code yet due to lack of time  :-( ).
> Although I think, it would be a great start for me to get dirty with coding
> plasma :-P
>
> Would like to see your patch as soon as you have something.. hope I can be
> of help
>
> I'll look for the thread and reread it to get a hang on all the details we
> should watch out for.
>
> I really hope this will end up in trunk anytime soon and we'll have the time
> and skills (in my case) to finish it appropriately :-P
>
> Regards,
> Bernhard Friedreich
>
> Luiz Felipe Talvik schrieb:
>
> Hey,
>
> I'm the one who started doing it 8 months ago, but I had some problems
> in real life.
> Coincidently I started refactoring the code, one week ago. I'm having
> some trouble cause the code changed so much. I'll release a diff as
> soon as I have something descent.
> I would like you to give your opinion on the exact behavior of items
> and sections on kickoff .
> And do you  have experience coding Qt and/or plasma? There are a
> couple of things holding me back.
>
> ,Talvik
>
> ps: forget that patch it's useless code, to find the thread discussing
> kickoff multiple columns search the panel-devel mailing list for
> "kickoff talvik".
>
> On Sat, Feb 14, 2009 at 10:38 AM, Bernhard Friedreich
> <friesoft@gmail.com> wrote:
>
>
> http://bugs.kde.org/show_bug.cgi?id=164805
>
>
> Bernhard Friedreich <friesoft@gmail.com> changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                 CC|                            |friesoft@gmail.com
>
>
>
>
> --- Comment #6 from Bernhard Friedreich <friesoft gmail com>  2009-02-14
> 13:38:27 ---
> any news on that one? There's been a patch long time ago but somehow I can't
> find it anymore :-(
>
> Would have like to give it a try and modify the patch to cleanly apply to
> trunk
> (don't have the time to start from scratch)... really hope this will go into
> trunk soon so all can enjoy it in 4.3
>
>
> --
> Configure bugmail: http://bugs.kde.org/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You reported the bug.
>
>
>
>
>
>
>
> ________________________________
>
>
>
>
>
>



_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic