[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Autolayout plug-in
- From: "Fred Morcos" <fred morcos gmail com>
- To: "discussions about usage and development of dia" <dia-list gnome org>
- Subject: Re: Autolayout plug-in
- Date: Fri, 2 Jan 2009 15:36:51 +0200
That's as far as I've gotten until 2 months ago (no work has been done
since, have been busy with post-graduate courses). As far as I can
remember, I didn't go on because of the fact that too many
recalculations will have to happen without a data structure for
caching the graph.
On Mon, Oct 13, 2008 at 12:12 AM, Fred Morcos <fred morcos gmail com> wrote:
> I am wondering again how to run your plugin.
>
> dia.register_action ("LayoutForcePy", "Layout (force)",
> "/DisplayMenu/Test/TestExtensionStart", layout_force_cb)
>
> What's the DisplayMenu?
>
> On Sun, Oct 12, 2008 at 10:35 PM, Hans Breuer <hans breuer org> wrote:
>> At 12.10.2008 19:07, Fred Morcos wrote:
>>>
>>> On Sun, Oct 12, 2008 at 6:55 PM, Hans Breuer <hans breuer org> wrote:
>>>>
>>>> At 08.10.2008 16:50, Fred Morcos wrote:
>>>>>
>>>>> Sorry for the very late reply, I have been finalizing my thesis and
>>>>> moving back to my country. I would like to restart the discussion
>>>>> about automatic layout, gearing things towards inclusion into Dia as
>>>>> an offered feature.
>>>>>
>>>>> You would prefer it as a plugin (I presume)?
>>>>
>>>> Yes.
>>>>>
>>>>> If it is a plugin, where should the GUI code go (if any)?
>>>>
>>>> In the plug-in. I did the necessary changes to your code some time ago,
>>>> but
>>>> that may be lost in some email. I have now added the plug-in to bugzilla.
>>>> See: http://bugzilla.gnome.org/show_bug.cgi?id=556026
>>>>
>>>
>>> I forgot to mention that I am going to implement it in Python.
>>
>> Why would you want to do this? As mentioned before it definitely is no
>> requirement to get your code to be included with Dia.
>>
>>> That was why I asked about GUI code. So should I use pygtk?
>>>
>> If you would go with Python, yes.
>>
>>>>> Any requirements for the GUI (following a certain HIG)?
>>>>
>>>> You may want to read http://library.gnome.org/devel/hig-book/stable/. But
>>>> please keep in mind that Dia should rely only on GUI available with
>>>> vanilla
>>>> Gtk+ for portability easons.
>>>>>
>>>>> How can I generate the API docs for plugins? --with-hardbooks didn't
>>>>> work.
>>>>
>>>> There is no dedicated plug-in API documentation. Basically you can use
>>>> everything available from lib/* and nothing from app/*
>>>>
>>>
>>> Help > PyDia Docs is all what's there?
>>>
>> Almost, but see also: http://www.gnome.org/projects/dia/python.html
>>
>> -------- Hans "at" Breuer "dot" Org -----------
>> Tell me what you need, and I'll tell you how to
>> get along without it. -- Dilbert
>> _______________________________________________
>> dia-list mailing list
>> dia-list gnome org
>> http://mail.gnome.org/mailman/listinfo/dia-list
>> FAQ at http://live.gnome.org/Dia/Faq
>> Main page at http://live.gnome.org/Dia
>>
>>
>
>
>
> --
> Fred Morcos
> http://fredmorcos.blogspot.com/
> http://fredmorcos.googlecode.com/
>
--
Fred Morcos
http://fredmorcos.blogspot.com/
http://katoob.googlecode.com/
https://savannah.nongnu.org/projects/objective-gtk/
http://grafer.googlecode.com/
# autolayoutforcefast.py - Fast Diagram Layout Plugin for Dia
#
# Diagram Automatic Layout Plugin for Dia.
#
# Copyright (c) 2008 Frederic-Gerald Morcos <fred morcos gmail com>
# Copyright (c) 2008 Hans Breuer <hans breuer org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import dia, gtk, math
class LayoutUI(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_border_width(5)
self.set_skip_pager_hint(True)
self.set_skip_taskbar_hint(True)
# FIXME - self.set_transient_for() on Dia's main window
box = gtk.VBox(False, 5)
connBox = gtk.HBox(False, 5)
connLabel = gtk.Label('Connection Length:')
self.connSpin = gtk.SpinButton(gtk.Adjustment(1, 1, 500, 1, 10))
connBox.pack_start(connLabel, False, False, 2)
connBox.pack_start(self.connSpin, True, True, 2)
buttBox = gtk.HButtonBox()
buttBox.set_spacing(5)
buttBox.set_layout(gtk.BUTTONBOX_END)
self.buttApply = gtk.Button(None, gtk.STOCK_APPLY)
buttClose = gtk.Button(None, gtk.STOCK_CLOSE)
buttClose.connect('clicked', self.buttClose_clicked, None)
buttBox.pack_start(self.buttApply, False, False, 2)
buttBox.pack_start(buttClose, False, False, 2)
box.pack_start(connBox, False, False, 2)
box.pack_start(gtk.HSeparator(), False, False, 2)
box.pack_start(buttBox, False, False, 2)
self.add(box)
self.show_all()
def buttClose_clicked(self, widget, data):
self.destroy()
def fast_layout_force_cb (data, flags):
nodes = []
connections = []
for i in data.selected:
if isConnection(i):
connections.append(i)
else:
nodes.append(i)
win = LayoutUI()
win.buttApply.connect(
'clicked', buttApply_clicked,
nodes, connections, win.connSpin, data)
def fast_layout_force(nodes, connections, connLen,
rconst, aconst, timestep, damping):
energy = [0.0, 0.0]
i = 0
netforces = []
while i < len(nodes):
netforces.append([0.0, 0.0])
i += 1
for i, n in enumerate(nodes):
for j, nn in enumerate(nodes[i + 1 : len(nodes)]):
res = repulsion (n, nn, rconst)
netforces[i][0] += res[0]
netforces[i][1] += res[1]
netforces[j][0] -= res[0]
netforces[j][1] -= res[1]
# for c in connections:
# attraction (c, connLen, aconst, energy)
for i, n in enumerate(nodes):
update(timestep, damping, n, netforces[i], energy)
return energy
def repulsion(node1, node2, const):
pos1 = node1.properties['obj_pos'].value
pos2 = node2.properties['obj_pos'].value
dx = pos1.x - pos2.x
dy = pos1.y - pos2.y
numer = area(node1) * area(node2) * const
denom = math.pow(dx * dx + dy * dy, 1.5)
try:
resx = numer * dx / denom
resy = numer * dy / denom
except ZeroDivisionError:
print 'Repulsion: Zero division error.'
return 0, 0
return resx, resy
def update(timestep, damping, object, netforce, energy):
velocity = [0.0, 0.0]
velocity[0] = timestep * netforce[0] * damping
velocity[1] = timestep * netforce[1] * damping
p = object.properties['obj_pos'].value
px = p.x + timestep * velocity[0]
py = p.y + timestep * velocity[1]
object.move(px, py)
mass = area(object)
energy[0] += mass * math.pow(velocity[0], 2) / 2
energy[1] += mass * math.pow(velocity[1], 2) / 2
def area(object):
rect = object.bounding_box
return (rect.bottom - rect.top) * (rect.right - rect.left)
def buttApply_clicked(widget, nodes, connections, connSpin, data):
connLen = connSpin.get_value_as_int()
diagram = dia.active_display().diagram
loops = 0
energy = fast_layout_force(
nodes, connections, connLen, 2.0, 3.0, 2e-1, 5e-1)
while (energy[0] > 1 or energy[1] > 1) and loops < 100:
energy = fast_layout_force(
nodes, connections, connLen, 2.0, 3.0, 2e-1, 5e-1)
loops += 1
for n in nodes:
diagram.update_connections(n)
data.active_layer.update_extents()
diagram.update_extents()
diagram.flush()
print loops, 'iterations.'
def isConnection (o):
for connPoint in o.connections:
if len (connPoint.connected) > 0:
return False
return True
dia.register_action (
'FastLayoutForcePy',
'Fast Layout (force)',
'/DisplayMenu/Test/TestExtensionStart',
fast_layout_force_cb)
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]