glom r1598 - in trunk: . glom/mode_data glom/utility_widgets
- From: jhs svn gnome org
- To: svn-commits-list gnome org
- Subject: glom r1598 - in trunk: . glom/mode_data glom/utility_widgets
- Date: Tue, 29 Apr 2008 17:39:20 +0100 (BST)
Author: jhs
Date: Tue Apr 29 16:39:20 2008
New Revision: 1598
URL: http://svn.gnome.org/viewvc/glom?rev=1598&view=rev
Log:
2008-04-29 Johannes Schmid <johannes schmid openismus com>
* glom/mode_data/flowtablewithfields.cc:
* glom/mode_data/flowtablewithfields.h
(on_dnd_add_layout_item)
Added new method to reparent items from other flowtables.
* glom/utility_widgets/flowtable_dnd.cc (start_dnd), (on_drag_motion),
(on_drag_data_received), (dnd_item_at_position),
(dnd_datawidget_from_item), (find_current_dnd_item),
(on_child_drag_motion), (on_child_drag_data_get),
(on_child_drag_begin), (on_child_drag_end):
* glom/utility_widgets/flowtable_dnd.h
Implemented drag sources for LayoutWidgets and allow dragging in and between
flowtables. Only works for labels as I didn\'t find out yet how to set other
widgets as drag sources.
* glom/utility_widgets/layoutwidgetbase.cc
(set_dnd_in_progress), (get_dnd_in_progress):
* glom/utility_widgets/layoutwidgetbase.h:
Added some need methods for drag and drop
Modified:
trunk/ChangeLog
trunk/glom/mode_data/flowtablewithfields.cc
trunk/glom/mode_data/flowtablewithfields.h
trunk/glom/utility_widgets/flowtable_dnd.cc
trunk/glom/utility_widgets/flowtable_dnd.h
trunk/glom/utility_widgets/layoutwidgetbase.cc
trunk/glom/utility_widgets/layoutwidgetbase.h
Modified: trunk/glom/mode_data/flowtablewithfields.cc
==============================================================================
--- trunk/glom/mode_data/flowtablewithfields.cc (original)
+++ trunk/glom/mode_data/flowtablewithfields.cc Tue Apr 29 16:39:20 2008
@@ -1272,6 +1272,15 @@
signal_layout_changed().emit();
}
+void FlowTableWithFields::on_dnd_add_layout_item (LayoutWidgetBase* above,
+ sharedptr<LayoutItem>& item)
+{
+ dnd_add_to_layout_group (item, above);
+
+ // Don't do this here - it's done in the drag_end handler
+ // signal_layout_changed().emit();
+}
+
void FlowTableWithFields::on_dnd_add_placeholder(LayoutWidgetBase* above)
{
if(m_placeholder)
Modified: trunk/glom/mode_data/flowtablewithfields.h
==============================================================================
--- trunk/glom/mode_data/flowtablewithfields.h (original)
+++ trunk/glom/mode_data/flowtablewithfields.h Tue Apr 29 16:39:20 2008
@@ -55,11 +55,11 @@
:
#ifdef GLOM_ENABLE_CLIENT_ONLY
public FlowTable,
+ public LayoutWidgetUtils,
#else
public FlowTableDnd,
#endif
- public View_Composite_Glom,
- public LayoutWidgetUtils
+ public View_Composite_Glom
{
public:
FlowTableWithFields(const Glib::ustring& table_name = Glib::ustring());
@@ -216,6 +216,8 @@
virtual void on_dnd_add_layout_item_button (LayoutWidgetBase* above);
virtual void on_dnd_add_layout_item_text (LayoutWidgetBase* above);
virtual void on_dnd_add_layout_notebook (LayoutWidgetBase* above);
+ virtual void on_dnd_add_layout_item (LayoutWidgetBase* above,
+ sharedptr<LayoutItem>& item);
bool get_field_information (sharedptr<LayoutItem>& item);
void dnd_notify_failed_drop();
Modified: trunk/glom/utility_widgets/flowtable_dnd.cc
==============================================================================
--- trunk/glom/utility_widgets/flowtable_dnd.cc (original)
+++ trunk/glom/utility_widgets/flowtable_dnd.cc Tue Apr 29 16:39:20 2008
@@ -19,6 +19,7 @@
*/
#include "flowtable_dnd.h"
+#include "../mode_data/flowtablewithfields.h"
#include "eggtoolpalette/eggtoolpalette.h"
#include "placeholder-glom.h"
#include "dragbutton.h"
@@ -29,13 +30,18 @@
namespace Glom
{
+
+const std::string MOVE_TARGET = "FlowTableMoveTarget";
FlowTableDnd::FlowTableDnd() :
- m_current_dnd_item(0)
+ m_current_dnd_item(0),
+ m_internal_drag (false)
{
std::list<Gtk::TargetEntry> drag_targets;
- Gtk::TargetEntry drag_target(egg_tool_palette_get_drag_target_item());
- drag_targets.push_back(drag_target);
+ Gtk::TargetEntry toolbar_target (egg_tool_palette_get_drag_target_item());
+ Gtk::TargetEntry move_target(MOVE_TARGET);
+ drag_targets.push_back(toolbar_target);
+ drag_targets.push_back(move_target);
drag_dest_set(drag_targets);
}
@@ -64,31 +70,39 @@
}
if (!(child.get_flags() & Gtk::NO_WINDOW))
{
- std::list<Gtk::TargetEntry> new_targets;
- Gtk::TargetEntry target(egg_tool_palette_get_drag_target_item());
- new_targets.push_back(target);
+ // Needed to move items around
+ std::list<Gtk::TargetEntry> source_targets;
+ source_targets.push_back (Gtk::TargetEntry (MOVE_TARGET));
+ child.drag_source_set (source_targets, Gdk::BUTTON1_MASK|Gdk::BUTTON3_MASK,
+ Gdk::ACTION_MOVE | Gdk::ACTION_COPY);
+
+ std::list<Gtk::TargetEntry> drag_targets;
+ Gtk::TargetEntry toolbar_target (egg_tool_palette_get_drag_target_item());
+ Gtk::TargetEntry move_target(MOVE_TARGET);
+ drag_targets.push_back(toolbar_target);
+ drag_targets.push_back(move_target);
+
Glib::RefPtr<Gtk::TargetList> targets =
child.drag_dest_get_target_list ();
// The widget has already a default drag destination - add more targets
if (targets)
{
- targets->add (new_targets);
+ targets->add (drag_targets);
child.drag_dest_set_target_list (targets);
}
else
- child.drag_dest_set(new_targets, Gtk::DEST_DEFAULT_ALL,
+ child.drag_dest_set(drag_targets, Gtk::DEST_DEFAULT_ALL,
Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
-
- // Needed to move items around
- //child.drag_source_set (new_targets, Gdk::BUTTON1_MASK|Gdk::BUTTON3_MASK,
- // Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
-
+
// It's important to connect this one BEFORE
child.signal_drag_motion().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_motion), &child),
false);
child.signal_drag_data_received().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_data_received), &child));
child.signal_drag_leave().connect (sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_leave));
- child.signal_drag_data_get().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_data_get), &child));
+
+ child.signal_drag_begin().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_begin), &child), false);
+ child.signal_drag_end().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_end), &child), false);
+ child.signal_drag_data_get().connect (sigc::bind<Gtk::Widget*>(sigc::mem_fun (*this, &FlowTableDnd::on_child_drag_data_get), &child), false);
}
}
@@ -124,7 +138,7 @@
y += get_allocation().get_y();
m_current_dnd_item = dnd_item_at_position(x, y);
- LayoutWidgetBase* above = dnd_datawidget_from_item();
+ LayoutWidgetBase* above = dnd_datawidget_from_item(0);
// above might be 0 here...
on_dnd_add_placeholder(above);
@@ -136,13 +150,14 @@
Gtk::Widget* palette = drag_get_source_widget (drag_context);
while (palette && !EGG_IS_TOOL_PALETTE (palette->gobj()))
palette = palette->get_parent();
+
+ on_dnd_remove_placeholder();
+ LayoutWidgetBase* above = dnd_datawidget_from_item(0);
if (palette)
{
GtkWidget* tool_item = egg_tool_palette_get_drag_item (EGG_TOOL_PALETTE (palette->gobj()), selection_data.gobj());
LayoutWidgetBase::enumType type =
static_cast<LayoutWidgetBase::enumType>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tool_item), "glom-type")));
- on_dnd_remove_placeholder();
- LayoutWidgetBase* above = dnd_datawidget_from_item();
switch (type)
{
case LayoutWidgetBase::TYPE_FIELD:
@@ -164,6 +179,29 @@
std::cerr << "Unknown drop type: " << type << std::endl;
}
}
+ else
+ {
+ gpointer* data = (gpointer*)selection_data.get_data();
+ LayoutWidgetBase* base = (LayoutWidgetBase*)*data;
+ if (base)
+ {
+ sharedptr<LayoutItem> item = base->get_layout_item();
+ if (item)
+ {
+ sharedptr<LayoutGroup> group = sharedptr<LayoutGroup>::cast_dynamic(get_layout_item());
+ LayoutGroup::type_list_items items = group->m_list_items;
+ if (std::find (items.begin(), items.end(), item) != items.end())
+ {
+ m_internal_drag = true;
+ group->remove_item(item);
+ }
+ else
+ m_internal_drag = false;
+ on_dnd_add_layout_item (above, item);
+ base->set_dnd_in_progress(false);
+ }
+ }
+ }
}
void FlowTableDnd::on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& drag_context, guint time)
@@ -193,7 +231,9 @@
rect.set_width (rect.get_width() + m_padding + second_rect.get_width());
}
- int cur_column = rect.get_x() / column_width;
+ int cur_column = 0;
+ if (column_width != 0)
+ cur_column = rect.get_x() / column_width;
if (cur_column != column)
{
@@ -219,29 +259,35 @@
return 0;
}
-LayoutWidgetBase* FlowTableDnd::dnd_datawidget_from_item()
+LayoutWidgetBase* FlowTableDnd::dnd_datawidget_from_item(FlowTable::FlowTableItem* item)
{
// Test if we have a datawidget below which we want to add
LayoutWidgetBase* above = 0;
- if(m_current_dnd_item)
+ FlowTableItem* used_item;
+ if (item)
+ used_item = item;
+ else
+ used_item = m_current_dnd_item;
+
+ if(used_item)
{
- if(m_current_dnd_item->m_first)
+ if(used_item->m_first)
{
- Gtk::Alignment* alignment = dynamic_cast <Gtk::Alignment*>(m_current_dnd_item->m_first);
+ Gtk::Alignment* alignment = dynamic_cast <Gtk::Alignment*>(used_item->m_first);
if (alignment)
{
above = dynamic_cast<LayoutWidgetBase*>(alignment->get_child());
}
}
- if(!above && m_current_dnd_item->m_first)
- above = dynamic_cast<LayoutWidgetBase*>(m_current_dnd_item->m_first);
- if(!above && m_current_dnd_item->m_second)
+ if(!above && used_item->m_first)
+ above = dynamic_cast<LayoutWidgetBase*>(used_item->m_first);
+ if(!above && used_item->m_second)
{
- above = dynamic_cast<LayoutWidgetBase*>(m_current_dnd_item->m_second);
+ above = dynamic_cast<LayoutWidgetBase*>(used_item->m_second);
// Special case for labels
if (!above)
{
- Gtk::Alignment* alignment = dynamic_cast <Gtk::Alignment*>(m_current_dnd_item->m_second);
+ Gtk::Alignment* alignment = dynamic_cast <Gtk::Alignment*>(used_item->m_second);
if (alignment)
{
above = dynamic_cast<LayoutWidgetBase*>(alignment->get_child());
@@ -252,9 +298,9 @@
return above;
}
-bool FlowTableDnd::on_child_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time,
- Gtk::Widget* child)
+FlowTable::FlowTableItem* FlowTableDnd::find_current_dnd_item (Gtk::Widget* child, int x, int y)
{
+ FlowTableItem* item;
type_vecChildren::iterator cur_child;
for (cur_child = m_children.begin();
cur_child != m_children.end(); cur_child++)
@@ -281,9 +327,9 @@
}
}
if (cur_child != m_children.end())
- m_current_dnd_item = &(*cur_child);
+ item = &(*cur_child);
else
- m_current_dnd_item = 0;
+ item = 0;
// Allow dragging at-the-end
if (cur_child == --m_children.end())
@@ -292,12 +338,20 @@
if (y > (rect.get_y() + rect.get_height() / 2) &&
y < (rect.get_y() + rect.get_height()))
{
- m_current_dnd_item = 0; // means end
+ item = 0; // means end
}
- }
+ }
+ return item;
+}
+
+bool FlowTableDnd::on_child_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time,
+ Gtk::Widget* child)
+{
+ find_current_dnd_item(child, x, y);
+
on_dnd_remove_placeholder ();
- LayoutWidgetBase* above = dnd_datawidget_from_item();
+ LayoutWidgetBase* above = dnd_datawidget_from_item(0);
// above might be 0 here...
on_dnd_add_placeholder(above);
@@ -317,10 +371,54 @@
}
void FlowTableDnd::on_child_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& drag_context,
- const Gtk::SelectionData& selection_data, guint, guint time,
+ Gtk::SelectionData& selection_data, guint, guint time,
Gtk::Widget* child)
{
- std::cout << __FUNCTION__ << std::endl;
+ FlowTableItem* item = find_current_dnd_item (child);
+ LayoutWidgetBase* base = dnd_datawidget_from_item (item);
+ if (base)
+ {
+ gpointer data = base;
+ selection_data.set ("LayoutWidgetBase*", 8, (guint8*)&data,
+ sizeof(gpointer*));
+ }
+}
+
+void FlowTableDnd::on_child_drag_begin (const Glib::RefPtr<Gdk::DragContext>& drag_context,
+ Gtk::Widget* child)
+{
+ FlowTableItem* item = find_current_dnd_item (child);
+ if (!item)
+ return;
+ if (item->m_first)
+ item->m_first->hide();
+ if (item->m_second)
+ item->m_second->hide();
+ LayoutWidgetBase* base = dnd_datawidget_from_item (item);
+ base->set_dnd_in_progress();
+}
+
+void FlowTableDnd::on_child_drag_end (const Glib::RefPtr<Gdk::DragContext>& drag_context,
+ Gtk::Widget* child)
+{
+ FlowTableItem* item = find_current_dnd_item (child);
+ LayoutWidgetBase* base = dnd_datawidget_from_item (item);
+ if (base->get_dnd_in_progress())
+ {
+ if (!item)
+ return;
+ if (item->m_first)
+ item->m_first->show();
+ if (item->m_second)
+ item->m_second->show();
+ }
+ else if (!m_internal_drag)
+ {
+ sharedptr<LayoutItem> item = base->get_layout_item();
+ sharedptr<LayoutGroup> group = sharedptr<LayoutGroup>::cast_dynamic(get_layout_item());
+ group->remove_item(item);
+ }
+ signal_layout_changed().emit();
}
void FlowTableDnd::set_design_mode(bool value)
Modified: trunk/glom/utility_widgets/flowtable_dnd.h
==============================================================================
--- trunk/glom/utility_widgets/flowtable_dnd.h (original)
+++ trunk/glom/utility_widgets/flowtable_dnd.h Tue Apr 29 16:39:20 2008
@@ -23,6 +23,7 @@
#include <gtkmm.h>
#include "flowtable.h"
+#include "layoutwidgetutils.h"
#ifdef GLOM_ENABLE_CLIENT_ONLY
#error FlowTableDnd does not work in Client-only mode
@@ -31,7 +32,9 @@
namespace Glom
{
-class FlowTableDnd : public FlowTable
+class FlowTableDnd :
+ public FlowTable,
+ public LayoutWidgetUtils
{
public:
FlowTableDnd();
@@ -47,8 +50,10 @@
virtual void on_child_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& drag_context, int, int,
const Gtk::SelectionData& selection_data, guint, guint time, Gtk::Widget* child);
virtual void on_child_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& drag_context,
- const Gtk::SelectionData& selection_data, guint, guint time, Gtk::Widget* child);
-
+ Gtk::SelectionData& selection_data, guint, guint time, Gtk::Widget* child);
+ virtual void on_child_drag_begin (const Glib::RefPtr<Gdk::DragContext>& drag_context, Gtk::Widget* child);
+ virtual void on_child_drag_end (const Glib::RefPtr<Gdk::DragContext>& drag_context, Gtk::Widget* child);
+
virtual void start_dnd (Gtk::Widget& child);
virtual void stop_dnd (Gtk::Widget& child);
@@ -60,6 +65,8 @@
virtual void on_dnd_add_layout_item_button (LayoutWidgetBase* above) = 0;
virtual void on_dnd_add_layout_item_text (LayoutWidgetBase* above) = 0;
virtual void on_dnd_add_layout_notebook (LayoutWidgetBase* above) = 0;
+ virtual void on_dnd_add_layout_item (LayoutWidgetBase* above,
+ sharedptr<LayoutItem>& item) = 0;
virtual void on_dnd_add_placeholder(LayoutWidgetBase* above) = 0;
virtual void on_dnd_remove_placeholder() = 0;
@@ -68,10 +75,13 @@
bool dnd_remove_placeholder_real();
FlowTableItem* dnd_item_at_position(int x, int y);
- LayoutWidgetBase* dnd_datawidget_from_item();
+ LayoutWidgetBase* dnd_datawidget_from_item(FlowTableItem* item);
private:
+ FlowTableItem* find_current_dnd_item (Gtk::Widget* child, int x = -1, int y = -1);
FlowTableItem* m_current_dnd_item;
+
+ bool m_internal_drag;
};
} // namespace Glom
Modified: trunk/glom/utility_widgets/layoutwidgetbase.cc
==============================================================================
--- trunk/glom/utility_widgets/layoutwidgetbase.cc (original)
+++ trunk/glom/utility_widgets/layoutwidgetbase.cc Tue Apr 29 16:39:20 2008
@@ -27,7 +27,8 @@
LayoutWidgetBase::LayoutWidgetBase()
#ifndef GLOM_ENABLE_CLIENT_ONLY
-: m_pLayoutItem(0)
+: m_pLayoutItem(0),
+ m_drag_in_progress(false)
#endif // !GLOM_ENABLE_CLIENT_ONLY
{
@@ -102,4 +103,15 @@
widget.modify_base(Gtk::STATE_NORMAL, Gdk::Color(bg));
}
+void LayoutWidgetBase::set_dnd_in_progress(bool drag)
+{
+ m_drag_in_progress = drag;
+}
+
+bool LayoutWidgetBase::get_dnd_in_progress()
+{
+ return m_drag_in_progress;
+}
+
+
} //namespace Glom
Modified: trunk/glom/utility_widgets/layoutwidgetbase.h
==============================================================================
--- trunk/glom/utility_widgets/layoutwidgetbase.h (original)
+++ trunk/glom/utility_widgets/layoutwidgetbase.h Tue Apr 29 16:39:20 2008
@@ -77,6 +77,11 @@
virtual void set_read_only(bool read_only = true);
+#ifndef GLOM_ENABLE_CLIENT_ONLY
+ void set_dnd_in_progress(bool drag = true);
+ bool get_dnd_in_progress();
+#endif // !GLOM_ENABLE_CLIENT_ONLY
+
protected:
virtual App_Glom* get_application() const; // = 0;
@@ -95,6 +100,7 @@
type_signal_user_requested_layout m_signal_user_requested_layout;
type_signal_user_requested_layout_properties m_signal_user_requested_layout_properties;
+ bool m_drag_in_progress;
#endif // !GLOM_ENABLE_CLIENT_ONLY
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]