Bug 67058 - Alignment of elements in a group
Summary: Alignment of elements in a group
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: 1.1.1
Platform: Unlisted Binaries Linux
: NOR wishlist
Target Milestone: ---
Assignee: Umbrello Development Group
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-02 16:32 UTC by Eugine V. Kosenko
Modified: 2006-05-05 23:30 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
New alignment: distribute; fixes to align icons (9.14 KB, application/x-tgz)
2006-04-04 04:57 UTC, Daniel Calviño Sánchez
Details
Fix for "distribute" alignment (1.67 KB, patch)
2006-04-29 18:47 UTC, Daniel Calviño Sánchez
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eugine V. Kosenko 2003-11-02 16:32:02 UTC
Version:           1.1.1 (using KDE KDE 3.1.2)
Installed from:    Unspecified Linux
OS:          Linux

It's a useful feature, when I may group a set of elements and give the command "align", after what the elements will take accurate position due to the type of alignment.
Comment 1 Jonathan Riddell 2003-11-03 15:26:18 UTC
We already have a snap to grid feature.  Can you explain it more, are you thinking about something like the broom tool in ArgoUML?

Thanks for your feedback

P.S. you can e-mail comments to bugs.kde.org with the address 67058@bugs.kde.org, changing the number for the appropriate entry.
Comment 2 Eugine V. Kosenko 2003-11-03 22:50:28 UTC
Subject: Re:  Alignment of elements in a group

> We already have a snap to grid feature.  Can you explain it more, are you
> thinking about something like the broom tool in ArgoUML?

Oops! I do not know such tool as ArgoUML. Does it mean Poseidon?

Let us have several widgets, which are arranged like

--_ --_ --

If we would select all the widgets and make the command 'horizontal alignment, 
then we will have the aligned set of widgets like

-- -- -- -- --

This is a semi-solution (or workaround), when the tool does not have an 
autolayout feature.

Comment 3 Sebastian Stein 2003-11-04 12:37:07 UTC
Subject: Re: [Uml-devel]  Alignment of elements in a group

Eugine V. Kosenko <eugine_kosenko@ukr.net> [031103 23:55]:
> ...

<offtopic>
> Oops! I do not know such tool as ArgoUML. Does it mean Poseidon?

ArgoUML is the open source part of Poseidon I think.
 
</offtopic>

> Let us have several widgets, which are arranged like
> 
> --_ --_ --
> 
> If we would select all the widgets and make the command 'horizontal alignment, 
> then we will have the aligned set of widgets like
> 
> -- -- -- -- --

The only thing we have to make clear is which position we use to align the
elements. In your example above you need a y-value to align all widgets with
their top y-value. Which one do you choose? The most toppest y-value, the
median of all y-values of all selected widgets or the lowest y-value?

Steinchen
Comment 4 Eugine V. Kosenko 2003-11-04 20:58:37 UTC
Subject: Re:  Alignment of elements in a group

> The only thing we have to make clear is which position we use to align the
> elements. In your example above you need a y-value to align all widgets
> with their top y-value. Which one do you choose? The most toppest y-value,
> the median of all y-values of all selected widgets or the lowest y-value?

The proper way is to make six menu items united in two groups:

Vertical alignment
	Align top
	Align middle
	Align bottom

Horizontal alignment
	Align left
	Align middle
	Align right

As for me the most important items are vertical top and horisontal middle. I 
used to use the latter to align the main thread (as well as alternative 
threads) on activity diagrams.

I also recommend to explore Tgif (http://bourbon.usc.edu:8001/tgif). This is 
the most powerful graphics tool I ever used. The only problem with it is the 
impossibility to make complex resizable groups of widgets, which may be 
considered as new macrowidgets. I tried to adapt tgif for UML widgets, but 
this problem stopped me.

Comment 5 Sebastian Stein 2003-11-04 22:33:45 UTC
Subject: Re: [Uml-devel]  Alignment of elements in a group

Eugine V. Kosenko <eugine_kosenko@ukr.net> [031104 21:38]:
> The proper way is to make six menu items united in two groups:
> 
> Vertical alignment
> 	Align top
> 	Align middle
> 	Align bottom
> 
> Horizontal alignment
> 	Align left
> 	Align middle
> 	Align right

I think we are talking about different things. I like to have the following
(letters are objects, numbers are just line numbers):

1  A
2   B 
3     E C
4         D
5

Now I click align top and get:

(highest based)
1  AB E C D
2 
3
4
5

or

(lowest based)
1 
2
3
4  AB E C D
5

or

(median based)
1
2 
3  AB E C D
4 
5

> I also recommend to explore Tgif (http://bourbon.usc.edu:8001/tgif). This is 
> the most powerful graphics tool I ever used. The only problem with it is the 
> impossibility to make complex resizable groups of widgets, which may be 
> considered as new macrowidgets. I tried to adapt tgif for UML widgets, but 
> this problem stopped me.

Ok, I draw 3 circles and select them. What should I now click to see the
behaviour you want?

Steinchen
Comment 6 Eugine V. Kosenko 2003-11-05 21:06:08 UTC
Subject: Re:  Alignment of elements in a group

> I think we are talking about different things. I like to have the following
> (letters are objects, numbers are just line numbers):

This is the same what I meant! What is misconception?

> > I also recommend to explore Tgif (http://bourbon.usc.edu:8001/tgif). This
> > is the most powerful graphics tool I ever used. The only problem with it
> > is the impossibility to make complex resizable groups of widgets, which
> > may be considered as new macrowidgets. I tried to adapt tgif for UML
> > widgets, but this problem stopped me.
>
> Ok, I draw 3 circles and select them. What should I now click to see the
> behaviour you want?

Do you talk about Tgif? There are two ways to do this. First, more simple way 
(and I think it is enough) is to select all three circles, choose the verical 
and horizontal alignment (either via menu items 'Arrange->Vertical Align', 
'Arrange->Horizontal Align' or toolbar) and then choose menu item 
'Arrange->Align Objects' (or press Ctrl-I). Another way is to select the 
circles, and choose the menu item 'Arrange->Align Objects Direct' and then 
select the necessary alignment from the two-dimensional menu matrix.

These are too complex methods, but they give big flexibility and minimize the 
count of necessary menu items. I do not require the exact behavior (it is 
enough to make six menu items in two groups) but it may be attractive 
sometimes.

By the way! There is the submenu 'Arrange->More Object Alignments', where all 
six simple alignments are encountered and even bound to shortcuts!

Apart from this, I suggest to see the similar features, 'Arrange->Size 
Objects' and 'Arrange->Abut', which also may be useful.

Comment 7 Sebastian Stein 2004-07-10 15:33:00 UTC
The feature was added and will be shipped with KDE 3.3.
Comment 8 Daniel Calviño Sánchez 2006-04-04 04:57:17 UTC
Created attachment 15450 [details]
New alignment: distribute; fixes to align icons

The attached file is a tar.gz containing a patch for the AlignToolBar. It also
includes fixed images for the alignment icons: pngs in "pics" directory and
svgs in "pics/sources" directory. As far as I know, "svn diff" doesn't manage
binary files, so I made it this way because of it.


About the icons, I have retouched a bit the existent alignment icons because
arrows weren't symmetrical and added two new icons for the new alignments.


About the patch, it adds two new alignments: horizontal distribute and vertical
distribute. After using a distribute alignment on various widgets, the distance
between each widget and the next to it is the same for all.

I thought in creating a new toolbar for "distribute" commands, as they're not
exactly alignments. However, I left them in the AlignToolBar class, but if you
prefer them in a new class, just tell me and I'll upload a new patch.

As I was editing the AlignToolBar class, I made some minor changes to adapt it
to the general code style in Umbrello (well, at least, the general code style
I've seen in various classes). I also applied an extract method refactoring
pattern in the cases of the main switch. If you prefer a patch without those
changes, tell me ;) By the way, it'd be very useful if the main code style
guidelines were put somewhere, because it'll help to keep a more homogeneous
code.

To implement the distribute commands, I needed to sort the UMLWidgetList using
different orders depending on the distribution selected. I didn't found a way
to make that sorting with QPtrList (the class of UMLWidgetList), so I copied
the pointers to a STL vector, order the vector, and then filled again the
UMLWidgetList. I think that it should exist a simpler way to do it, but I
haven't found it :$
Comment 9 Oliver Kellogg 2006-04-06 22:50:56 UTC
SVN commit 527099 by okellogg:

Attachment 15450 [details] from Daniel Calviño Sánchez adds a new alignment
type "distribute" and improves the align icons.
CCBUG:67058


 M  +2 -1      ChangeLog  
 M  +262 -136  umbrello/aligntoolbar.cpp  
 M  +132 -27   umbrello/aligntoolbar.h  
 M             umbrello/pics/align_bottom.png  
 AM            umbrello/pics/align_hori_distribute.png  
 M             umbrello/pics/align_hori_middle.png  
 M             umbrello/pics/align_left.png  
 M             umbrello/pics/align_right.png  
 M             umbrello/pics/align_top.png  
 AM            umbrello/pics/align_vert_distribute.png  
 M             umbrello/pics/align_vert_middle.png  
 M             umbrello/pics/sources/align_bottom.svg  
 A             umbrello/pics/sources/align_hori_distribute.svg  
 M             umbrello/pics/sources/align_hori_middle.svg  
 M             umbrello/pics/sources/align_left.svg  
 M             umbrello/pics/sources/align_right.svg  
 M             umbrello/pics/sources/align_top.svg  
 A             umbrello/pics/sources/align_vert_distribute.svg  
 M             umbrello/pics/sources/align_vert_middle.svg  
Comment 10 Daniel Calviño Sánchez 2006-04-29 18:47:33 UTC
Created attachment 15847 [details]
Fix for "distribute" alignment

When I send the previous patch I thought that widgets X and Y position refered
to the center of widget instead of upper left corner. This patch corrects the
error, and also rounds to the next integer the distance between widgets.

I apologize for the mistake. The widgets I tested the distribute alignment with
worked fine even with the wrong behaviour... so I haven't found the problem
until today.
Comment 11 Oliver Kellogg 2006-05-05 23:30:40 UTC
SVN commit 537809 by okellogg:

Hi Daniel, thanks for contacting me. You're right, I had overlooked your
attachment 15847 [details] which I am applying here. I've learned that the KDE 3.5
branch is still open for small fixes such as this :-)
CCBUG:67058


 M  +4 -6      aligntoolbar.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/aligntoolbar.cpp #537808:537809
@@ -262,7 +262,7 @@
     int smallestY = getSmallestY(widgetList);
     int biggestY = getBiggestY(widgetList);
     int heightsSum = getHeightsSum(widgetList);
-    int distance = ((biggestY - smallestY) - heightsSum) / (int)(widgetList.count()-1);
+    int distance = int(((biggestY - smallestY) - heightsSum) / (widgetList.count()-1.0) + 0.5);
 
     sortWidgetList(widgetList, hasWidgetSmallerY);
 
@@ -275,8 +275,7 @@
     ++it;
     while ((widget = it.current()) != 0) {
         ++it;
-        widget->setY((widgetPrev->getY() + int(widgetPrev->getHeight() / 2)) +
-                        distance + int(widget->getHeight() / 2));
+        widget->setY(widgetPrev->getY() + widgetPrev->getHeight() + distance);
         widgetPrev = widget;
     }
 }
@@ -285,7 +284,7 @@
     int smallestX = getSmallestX(widgetList);
     int biggestX = getBiggestX(widgetList);
     int widthsSum = getWidthsSum(widgetList);
-    int distance = ((biggestX - smallestX) - widthsSum) / (int)(widgetList.count()-1);
+    int distance = int(((biggestX - smallestX) - widthsSum) / (widgetList.count()-1.0) + 0.5);
 
     sortWidgetList(widgetList, hasWidgetSmallerX);
 
@@ -298,8 +297,7 @@
     ++it;
     while ((widget = it.current()) != 0) {
         ++it;
-        widget->setX((widgetPrev->getX() + int(widgetPrev->getWidth() / 2)) +
-                        distance + int(widget->getWidth() / 2));
+        widget->setX(widgetPrev->getX() + widgetPrev->getWidth() + distance);
         widgetPrev = widget;
     }
 }