GNOME Bugzilla – Bug 358092
Add drag-and-drop layout
Last modified: 2009-12-29 12:52:58 UTC
See http://www.glom.org/wiki/index.php?title=Development/Plans and http://www.glom.org/wiki/index.php?title=Development/Plans/DragAndDropLayout
*** Bug 425145 has been marked as a duplicate of this bug. ***
Created attachment 85848 [details] [review] A tiny DND experiment.
I will have a look at this though I am quite sure that this will take some time. The 60 hours stated in the proposal look realistic.
Yeah, feel free to take simpler tasks first.
Created attachment 86988 [details] [review] Another test program for dnd This one is based on the tiny DND experiment but has some differences: - Instead of dragging on the items you can drag items into the flowtable - Some preview rectangle is shown as user feedback Still todo: - If a FlowItem has no second item it should be possible to drag a second item - make it look pretty - integrate with glom This is work in progress, the code is also not very nice yet but I want some basic functionality before I start to integrate this in glom.
OK, I have some working dnd code now but I have a question on the generic workflow of interface creation. In the moment you can define new Fields in the Table and later add a LayoutItem by selecting one of the fields. This will always create a Label + Widget (Button, Entry, Combo, etc). In the new workflow I propose the following: - Define the fields in the dialog as before - Have a generic drag button to be able to arrange a new Layoutitem - When the LayoutItem is dropped the dialog to select the field would pop up and after the user selects a field the appropriate widget is created. Is this your intention or did you think of something different.
Yes, you would drap-and-drop a generic field layout item. And when you drop it, you would be forced to choose an actual field. Then it would just show itself appropriately, as now. For now, this will not offer any way to add a field to the underlying table - the fields must exist already.
Created attachment 87264 [details] [review] Some dnd test code integrated in glom Dnd test code - do not commit! To test dnd, open a database, choose Designer mode and use the Designer->Fields menu entry. This will popup a little window where you can drag from. The preview does not yet work like in the test program, I have to figure out why.
> To test dnd, open a database, choose Designer mode and use the Designer->Fields menu entry. Feel free to add an extra menu item for this, even if it's just for testing. It's odd having it together with the table fields definition. > This will popup a little window where you can drag from. Unfortunately, I can't seem to start a drag from that "Drag Widget" button.
> I can't seem to start a drag Ah, I can when I close the fields definitions window.
Created attachment 87888 [details] [review] Yet another dnd test Yet another test! I added a new menu item "Fields interactive" which shows the drag button now. Some preview is also provided for the dragging though it needs to be improved a lot. Somehow, the drawing does no longer work after one widget was added or the "Fields"-Window was used. I have to investigate that.
OK, after some more experimenting I finally asked on gtk-app-devel list why it does not work as expected. The problem is that FlowTableWithFields is a nested container meaning that it can contain yet another FlowTable. As classes derived from GtkContainer do not have a GdkWindow and thus do not receive X events it's impossible to use them for drag and drop more or less. See: http://mail.gnome.org/archives/gtk-app-devel-list/2007-May/msg00069.html (hopefully the answer I already got will appear there soon...) We have to think of a completely different solution. What came into my mind was to use glade internally (glade3 can be embedded) and strip it down so that only the useful features are availible but that's also going to be complicated.
Can we fix this by using a GtkEventBox? I wonder if there are other examples of drag-and-drop happening in containers? There must be. I'd rather avoid messing with glade.
Thanks for the hint! GtkEventBox solves most of the problems. I have experimented a bit with moving other widgets away (up or down a bit) while dragging to have a better preview. It's working for the test program but not in glom, yet. More to come soon...
Created attachment 88685 [details] [review] Prelimitery dnd layout This is a slightly more useful patch. You can now drag items on the layout and they will be added (to the interface, not yet to the database). The position of the items is often wrong especially when you want to drag something in the top-level frame. As before, the missing GdkWindows are a probleme here.
The patch is missing the floweventbox.[h|c] files.
Created attachment 95727 [details] one of the missing files
Created attachment 95728 [details] floweventbox.h
Created attachment 95729 [details] floweventbox.cc
I've just tried this. Dragging either an item or a group to the layout causes the target group to be highlighted. That's maybe useful, but we really need to draw a placeholder to show where the actual item would be dropped, and the other items need to flow out of the way to make room for it. But you probably know that already.
Created attachment 95785 [details] [review] glomdragdrop.patch This is a version of the patch that applies cleanly against svn trunk.
Created attachment 96286 [details] [review] Updated version of the patch This patch now adds a placeholder where the widget will be added later. Unfortunately it does only add items and the end of the FlowTable. I have to investigate the use of more EventBoxes to change this
Created attachment 97121 [details] [review] Merged changes from trunk into the patch This patch does just merge the changes from trunk and applies cleanly. No new/better functionality.
Created attachment 97730 [details] [review] Preview/Placeholder handling With this patch, the preview/placeholder handling is mostly complete. Currently only the preview is drawn and no widget is really added. This is because of changes in Glom::DataWidget that I have not yet merged. Preview works good for most cases but is off by some pixels for FlowTables inside of GtkNotebooks. Some other questions: - How should the GUI look like in the end. Do you want to keep the floating window (with better icons, etc.) or should we add a toolbar. - Do you have an idea how the placeholder could look like? Currently it is really not nice but I am not artist and no UI designer so any idea would be nice.
Tell me when I should take a look, and at what branch. Then I'll make some decisions. Well done so far.
Hi Murray! The patch is against trunk. I can create a branch if you like. As I asked, it mostly about how to design the UI around drag and drop and how to present everything to the user in a convenient way. I will make some screenshots and blog about it soon to get some more feedback.
A blog entry would be good. Thanks. Let's apply this to trunk soon, but not just yet. I think that a simple rectangle for the drop preview is fine, but let's see.
> How should the GUI look like in the end. Do you want to keep the floating > window (with better icons, etc.) or should we add a toolbar. I would like a (maybe undockable) vertical toolbar. I need this for the print layout too, so it would be great if you investigated how best to do this.
This is looking pretty good, though I have not yet tested it with an empty or almost-empty layout. I notice that the placeholder is not visible if I drag over a field entry, though it works when dragging over the field label. Note that Mathias is working on a glade-3-like reusable tool palette widget that we can use for this and my print layout work.
> I notice that the placeholder is not visible if I drag over a field entry, > though it works when dragging over the field label. Yes, that because the field has it's own GdkWindow and catches the drag events itself. I'am working on a way to chain those events up to the FlowTable but it's not entirely easy. > Note that Mathias is working on a glade-3-like reusable tool palette widget > that we can use for this and my print layout work. It shouldn't be difficult to integrate this later. We already discussed that the buttons have to work for dragging and he found out how to do it. Another problem that remains is that it's not yet possible to drag empty containers. Here, some kind of "sticky" placeholders is needed that is inserted until the user drags some real layout element into the container.
> Another problem that remains is that it's not yet possible to drag empty > containers. Here, some kind of "sticky" placeholders is needed that is inserted > until the user drags some real layout element into the container. Yeah, or we could just make sure that FlowTable has a certain default height when it has no children. We could even make it have a "<empty>" label as the child in this case. By the way, there are already dialogs for editing text and button items - see what happens when you edit them in the old layout editing dialog. Also, they should maybe just start with the same default contents that they have when you add them there (or via right-click).
> I notice that the placeholder is not visible if I drag over a field entry, > though it works when dragging over the field label. Fixed now for entries though it's not very pretty and I have to do some work to support texts and images. Also fixed some alignment problem for the placeholders. Adding new fields with default properties could be easier because using the editable cells in the layout editing dialog directly is not very pretty IMHO. That should be finished soon and I will concentrate on making it possible to start with an empty layout. Integrating Mathias toolbar should not be a big deal later when it's API is half-way frozen (and there is a C++ wraper...).
> Adding new fields with default properties could be easier because using the > editable cells in the layout editing dialog directly is not very pretty IMHO. I don't understand this. Could you try again to explain?
Sorry, this was meant as reply to comment #31: > By the way, there are already dialogs for editing text and button items - see > what happens when you edit them in the old layout editing dialog. Also, they > should maybe just start with the same default contents that they have when you > add them there (or via right-click). And I would agree that starting with the default contents would be the simplest solution. Sorry for the confusion.
I am currently investigating why adding of groups does not work correctly to make it possible to start with am empty layout (had to fix some bugs that causes crashes when the layout is empty...). Anyway, there is signal_layout_item_added() which is emitted by FlowTableWithFields but does not seem to be caught anywhere. Was there some plan to do something with it? create_layout() somehow seems to miss out the new group and thus it disappears some milliseconds after it was added.
Not that I know of. If the signal is really not used, feel free to comment it out.
Some general ideas that I want to have approved before starting coding: - Adding Fields: The user can simply add fields at any position he wants (at least if there is some group). No dialog will be shown because the field is self-contained. - Adding Buttons/Text After adding the item, the LayoutDetails dialog will pop up with the added item selected so that the user can change the name and other things - Adding groups/portals More or less the same that happens for buttons/text but the group will be added in the dialog at the correct position after dropping it. Once the dialog has been closed the group will be added to the document and the view will be refreshed. Of course the user will have the preview widget. Before that, I wanted to give the user the choice to open the dialog when he feels he wants to change something. Anyway, it is very difficult to add a single layout_group to the document and seems much more efficient to use the tree model of the layout details dialog and to refresh the whole layout. To archive all that I have to extend the interface of the layout details dialog with things like: - add_group_at_position() - select_layout_item() What do you think? Maybe there is a better solution that I miss.
(In reply to comment #37) > Some general ideas that I want to have approved before starting coding: > > - Adding Fields: > The user can simply add fields at any position he wants (at least if there is > some group). No dialog will be shown because the field is self-contained. I don't know what you mean. Why wouldn't he be able to add a field where he wants? What does self-contained mean? In general, I don't want dialogs shown automatically after the drop. > - Adding Buttons/Text > After adding the item, the LayoutDetails dialog will pop up with the added item > selected so that the user can change the name and other things No, I'd prefer them just to have default text/names, with no dialog shown automatically after the drop. > - Adding groups/portals > More or less the same that happens for buttons/text but the group will be added > in the dialog at the correct position after dropping it. Once the dialog has > been closed Again, I don't want a dialog. What would it ask? > the group will be added to the document and the view will be > refreshed. Of course the user will have the preview widget. > > Before that, I wanted to give the user the choice to open the dialog when he > feels he wants to change something. Anyway, it is very difficult to add a > single layout_group to the document and seems much more efficient to use the > tree model of the layout details dialog and to refresh the whole layout. That's fine. It will look the same to the user (well, maybe with a little flicker, but that's OK) > To archive all that I have to extend the interface of the layout details dialog > with things like: > > - add_group_at_position() > - select_layout_item() That sounds fine.
> I don't know what you mean. Why wouldn't he be able to add a field where he > wants? What does self-contained mean? In general, I don't want dialogs shown > automatically after the drop. OK, maybe "self-contained" is the wrong word. I just wanted to say that there isn't any layout information that the user would want to edit for a field, like label or name. Glom forces that fields are organized in groups and does not allow to add a field that does not belong to a group. Anyway, it's unlikely that the user will find a place where there is no group. > That's fine. It will look the same to the user (well, maybe with a little > flicker, but that's OK) OK, I have halfway implemented this but have to care about dragging items into empty groups now.
OK. By the way, I get the idea from some comments that you are using the TreeModel to read/change the groups instead of the LayoutGroup directly. If so, this does seem odd because the TreeModel is just an implementation detail of the ugly old layout dialog.
Yes, because I didn't find a way to add a layout_group to the document. The only API that exists saves all (existing) groups as a whole. And from the internal data structure I could not figure out how single groups could be added.
I think it would be best to add some API to the document class then, or to some part of the data structure that the document gives you. I can do that if you like, but I won't get to it until maybe Friday.
I will have a look at it tommorow and see what I can do. Until now I have not much clue how this data structure is organized. In any case I will post some more details (and maybe detailed questions).
OK, I think I got it. The API is actually there but it's a bit difficult to find out how it works and I had to read quite a bunch of code to find out (maybe I am also just to stupid...)! What a mad idea to use the layout dialog...
Finally I got dragging for groups working. Anyway, there is a problem with the correct positioning: The drag code determines the Gtk::Widget next to the drop zone. It then casts the widget to the corresponding LayoutWidgetBase* widget. To insert at the correct position of the group LayoutGroup::add_item() is used. For the item, LayoutWidgetBase::get_layout_item() is used. This works fine for LayoutItemField but somehow LayoutItemButton for example has no layout item attached and get_layout_item() returns 0. Thus it is not inserted at the correct position but at the end of the group.
OK, I could fixed the problem mentioned in comment #45. Anyway, seems like the layout is not saved/restored correctly when you quit glom. Have to investigate that, probably I broke something.
Would be have been clever to set the document modified when the layout changed ;-) So, comment #46 is also fixed! I think the drag and drop stuff is in a quite nice shape now. I would really like to have some feedback from your side. It might of course still have some problem here and there and it still uses a quite ugly sidebar but the rest more or less works. For the issues mentioned yesterday on IRC I added a new bug report: bug 517665
Sorry, I'm currently having difficulties getting Postgres to work at all in Ubuntu Hardy Heron. I'll try it in a Gutsy vmware if I don't fix that soon. It's probably a good idea to try using the EggToolPallette already.
I tried this on Gutsy, and I see that it's working quite well, though the drop position doesn't seem to work quite right next to a text item. It will all look even nicer when it uses eggtoolpallette. There are some extra things that need to be done to make editing with this really possible: - All layout widgets should show a context menu when you right click them, so you can edit them, for instance to choose a different field, or to set the text, or to change the number of columns. Some of them have this already. - Drag-to-move of existing layout items should be possible.
(In reply to comment #49) > I tried this on Gutsy, and I see that it's working quite well, though the drop > position doesn't seem to work quite right next to a text item. It will all look > even nicer when it uses eggtoolpallette. Yeah, text labels are a bit tricky because they don't have it's own GdkWindow. Maybe I have to do some Gtk::EventBox magic but it shouldn't be that difficult. > There are some extra things that need to be done to make editing with this > really possible: > - All layout widgets should show a context menu when you right click them, so > you can edit them, for instance to choose a different field, or to set the > text, or to change the number of columns. Some of them have this already. Technical this shouldn't be a big problem though we need some new dialog I guess. > - Drag-to-move of existing layout items should be possible. Haven't thought about this yet. Should be possible to do but the dnd code is always very tricky.
> > - All layout widgets should show a context menu when you right click them, so > > you can edit them, for instance to choose a different field, or to set the > > text, or to change the number of columns. Some of them have this already. > > Technical this shouldn't be a big problem though we need some new dialog I > guess. Most of the necessary dialogs should exist already - you can already edit these layout items in the old treeview dialog, and some layout items already have context menus.
The text item problem is now fixed. About the dialogs: Yeah, you can edit the titles and things like that in the old layout dialog but just by editing the cells so this is not really an option for the popup menu because I really don't want to show the whole layout dialog if someone selects "Change title". The only dialog that I found yet was the dialog to edit the python code of a GlomButton. What is your prefered way to edit the titles and names of groups/labels/fields/buttons, etc.?
> What is your prefered way to edit the titles and names of > groups/labels/fields/buttons, etc.? I guess you need to create new dialogs, making them generic where possible.
I tried the recent code briefly. I noticed a small problem when dragging a text item (or maybe any item) onto a group that contains fields. If I drag over the field labels then I can add at the start and end positions, but not if I drag over the field labels.
It should when you drag on a GtkEntry but it does not work yet when you drag on a GtkTextView or a GtkImage. I will try to fix this.
Dropping-above still doesn't work on a combobox (when a field has choices), and dropping-below still doesn't work for an entry. Dropping-above does work now for an entry. I'm using the small business example's contacts details to test.
It's not fully fixed yet - I have to rework the dnd logic a bit to get all cases working.
(In reply to comment #56) > Dropping-above still doesn't work on a combobox (when a field has choices), and > dropping-below still doesn't work for an entry. Dropping-above does work now > for an entry. I'm using the small business example's contacts details to test. Both should now work. Dropping on a combobox did not work at all because it has a rather strage widget tree but I have fixed this. The dropping-below problem for fields (or anything that has it's own GdkWindow) should also be fixed. I use an g_idle_add hack which seems to work quite reliable though is not entirely nice. I am going on to add more context menus to the items.
I notice that there is now lots of quite glom-specific dnd stuff in FlowTable. If possible, it would be nice if this was in FlowTableWithFields (or a further-derived class, to keep code nicely separated) so that FlowTable stays simple and generic.
It's now cleaned up and moved to FlowTableDnd. As a next I am planing to add "Remove" menuitems to all LayoutItems to avoid having to use the LayoutDialog just to remove items.
Thanks. There are a few tabs in there. Please do remove them.
More importantly, the build is broken. There are many errors but this is the first: flowtable.cc: In constructor ‘Glom::FlowTable::FlowTable()’: flowtable.cc:295: error: class ‘Glom::FlowTable’ does not have any field named ‘m_current_dnd_item’ flowtable.cc:296: error: class ‘Glom::FlowTable’ does not have any field named ‘m_dnd_in_progress’
Fixed - sorry! Files have been in conflict and where as such not commited correctly.
It's looking better all the time. Some random comments: 1. When choosing "Details" from the context menu on a button, it crashes beause of this: (glom:19303): libglademm-CRITICAL **: widget `textview_calculation' not found in glade file `/opt/gnome220/share/glom/glade//glom_developer.glade' Maybe that's something that I broke because the same thing happens from the Layout dialog. 2. The Tool palette should really be inside the Details tab, so we can have a slightly different tool palette for the list view in future. It should be detachable/dockable for people with small screens. 3. Ideally, for buttons (and maybe this is happening for other items too), the title would be on the same dialog as the details. So for buttons, the name, title and the script would be on the same dialog. It though it used to be like this, but I could be wrong. But now there is a "properties" context menu item for changing the button label. By the way, please use "Title" rather than "label" in general.
When firsting viewing details (I think) there is this warning: (glom:4040): Gtk-WARNING **: Inserting action group 'NavTablesActions' into UI manager which already has a group with this name And each time after that there is this warning: (glom:4040): Gtk-WARNING **: Inserting action group 'NavPrintLayoutsActions' into UI manager which already has a group with this name
(In reply to comment #65) > When firsting viewing details (I think) there is this warning: > (glom:4040): Gtk-WARNING **: Inserting action group 'NavTablesActions' into > UI manager which already has a group with this name > Sorry, I cannot reproduce this and I doubt that it has anything todo with my changes but I can be wrong of course. > 1. > When choosing "Details" from the context menu on a button, it crashes beause of > this: > (glom:19303): libglademm-CRITICAL **: widget `textview_calculation' not found > in glade file `/opt/gnome220/share/glom/glade//glom_developer.glade' > Maybe that's something that I broke because the same thing happens from the > Layout dialog. Fixed! > 2. > The Tool palette should really be inside the Details tab, so we can have a > slightly different tool palette for the list view in future. It should be > detachable/dockable for people with small screens. I will have a look at this now - there were some problem with the initial size of the toolbar last time I tried. > 3. > Ideally, for buttons (and maybe this is happening for other items too), the > title would be on the same dialog as the details. So for buttons, the name, > title and the script would be on the same dialog. It though it used to be like > this, but I could be wrong. But now there is a "properties" context menu item > for changing the button label. By the way, please use "Title" rather than > "label" in general. I have added a title label to the dialog now and the "Details" menu item is gone.
OK, all the requested features should now be implemented but there might be some bugs and of course a lot of things could be improved but it would be good if you could have a short look at it. One bug I know of is that when moving the mouse over an image or a bigger text field, the placeholder jumps around. I will have a look at this.
Using the Small Business Example, I notice a problem when dragging fields to other groups. Sometimes they land 1 position lower than the drag indicator showed. It doesn't happen always though. For instance try dragging First Name below the Picture from a fresh from-the-example Glom system.
Could not really reproduce the problem from comment #68 but at least fixed the flickering (comment #67) which might be the same reason.
Yes, that seems to have fixed that problem. Thanks. I now notice two other little problems: - When dragging over the label of a field, the drag position doesn't show. If I drag (vertically) over the Entry widgets of the fields then it works. - It doesn't seem to work when dragging near the button item in the small business example.
(In reply to comment #70) > - When dragging over the label of a field, the drag position doesn't show. If I > drag (vertically) over the Entry widgets of the fields then it works. hmm, this works for me! Could you please be a bit more specific how to reproduce it. E.g. which item do you drag which way in the small business example. > - It doesn't seem to work when dragging near the button item in the small > business example. What do you mean with "It doesn't work"? Is the preview shown incorrectly or is the item not dropped correctly? Thanks!
(In reply to comment #71) > (In reply to comment #70) > > - When dragging over the label of a field, the drag position doesn't show. If I > > drag (vertically) over the Entry widgets of the fields then it works. > > hmm, this works for me! Could you please be a bit more specific how to > reproduce it. E.g. which item do you drag which way in the small business > example. Yeah, it seems to work for me now. Sorry. > > - It doesn't seem to work when dragging near the button item in the small > > business example. > > What do you mean with "It doesn't work"? Is the preview shown incorrectly or is > the item not dropped correctly? This seems to work too.
Could you please add some tooltips for these eggtoolpallete items. That will make up for the icons being a bit cryptic when only items are seen. Please also make it default to showing horizontal icons+text. Maybe eggtoolpallete should be showing icons+text already, as per my GNOME settings. Please also add a Show Layout Toolbar toggle menu item to the developer menu, defaulting to off. I worry that it needs more testing and maybe some more UI work to make it seem less confusing, so it would be nice to make it optional by doing that. This will let us do a Glom 1.8 release soon, needed by Ubuntu Intrepid.
Should be done now, please note that the horizontal icons+text layout won't work with gtk+ > 2.13/14.
(In reply to comment #74) > Should be done now, please note that the horizontal icons+text layout won't > work with gtk+ > 2.13/14. That's looking good. However, there's one small problem: If you show the toolbar, switch to operator mode, then switch back to developer mode, the toolbar is not visible, though the radio menu item is still checked.
The toolbar also vanishes after dragging something to the layout. That's probably a bigger clue.
These two should be fixed now in trunk.
Yes. It's a little annoying that Show Layout Toolbar unchecks itself (and hides the toolbar) automatically while switching to operator mode and then back to developer mode, but at least it's consistent now.
Another thing: It needs a Related Records (portal) item that can be dragged to the layout. Maybe you could also dig up some icons for horizontal-line and vertical-line, which I need for the print layouts toolbar.
My commit today allows a portal to be added without specifying the relationship, specifying the parent table instead. That should help.
It's now implemented that way that the user chooses the relationship before the portal is added to the layout. I think this is the most convinient way.
Johannes, the layout palette shows up in Find mode, even as operator. It shouldn't show up in Find either as operator or developer.
Nevermind. It's easy to hide() it in the code.
> Johannes, the layout palette shows up in Find mode, even as operator. It > shouldn't show up in Find either as operator or developer. I think I fixed that a while ago. It doesn't happen now. Closing this bug. We should deal with individual problems with the drag-and-drop-layout in individual bugs. For instance, Bug #599232.