aboutsummaryrefslogtreecommitdiff
path: root/src/MTools/Comp/MAntiRecouvrementItem.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/MTools/Comp/MAntiRecouvrementItem.pm')
-rw-r--r--src/MTools/Comp/MAntiRecouvrementItem.pm191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/MTools/Comp/MAntiRecouvrementItem.pm b/src/MTools/Comp/MAntiRecouvrementItem.pm
new file mode 100644
index 0000000..625cefc
--- /dev/null
+++ b/src/MTools/Comp/MAntiRecouvrementItem.pm
@@ -0,0 +1,191 @@
+package MTools::Comp::MAntiRecouvrementItem;
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU LGPL Libray 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 Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA,
+# or refer to http://www.gnu.org/copyleft/lgpl.html
+#
+##################################################################
+
+
+# Les objets heritant de MAntiRecouvrementItem peuvent etre geres par un objet MAntiRecouvrement et ainsi pris en charge
+# par un algorithme d'anti-recouvrement.
+#
+# parametres :
+# * $parent : parent de l'objet...
+# * %options : table de hash permettant d'initialiser les proprietes
+# Les ?v?nements :
+# * TRANSLATED : notifie lorsque l'objet est translate...
+# attibuts :
+# followed_by : MAntiRecouvrementItem permet aux objets contenus dans ce tableau de suivre ses deplacements
+# (permet un chainage des objets)
+# Les propietes :
+# * xmin, ymin, xmax, ymax : definissent les caract?risiques de l'espace dans lequel l'objet est contraint.
+# * height, width : definissent la base rectangulaire de l'objet
+# * auto_sizing : si width ou height ne sont pas pass?s en param?tre, les caracteristiques
+# sont auto-determinees en fonction de la bbox de l'objet. On peut bien evidemment choisir cette definition automatique, cependant
+# attention, la bbox de l'objet ne correspond par toujours a la bbox visible de l'objet.
+# * x, y : determinent la position de l'objet et sont mis a jour automatiquement au cours des deplacement de l'objet.
+# * anchors : permet d'active ou ne le suivi des objets contenus dans 'followed_by'
+# Les fonctions :
+# * update_bbox : permet de demander une remise ? jour du calcul automatique des dimensions de l'objet (util uniquement si auto_sizing == 1)
+
+use MTools;
+
+use vars qw /@ISA/;
+
+
+use MTools::GUI::MGroup;
+require Exporter;
+
+BEGIN
+{
+ @ISA = qw /MTools::GUI::MGroup Exporter/;
+ @EXPORT = qw / translate scale rotate /;
+}
+
+use strict;
+use Tk;
+
+sub new {
+ my ($class, $parent, %options) = @_;
+ my $self = new MTools::GUI::MGroup ($parent);
+ bless $self, $class;
+
+ $self -> recordEvent ('TRANSLATED');
+ $self -> recordProperty ('auto_sizing', (!defined $options{width}) || (!defined $options{height}));
+ $self -> recordProperty ('height', 0);
+ $self -> recordProperty ('width', 0);
+ $self -> recordProperty ('x', 0);
+ $self -> recordProperty ('y', 0);
+ $self -> recordProperty ('xmin', 0);
+ $self -> recordProperty ('ymin', 0);
+ $self -> recordProperty ('xmax', 1500);
+ $self -> recordProperty ('ymax', 1500);
+ $self -> recordProperty ('anchors', 1);
+
+ $self -> recordEvent ('__HANDLE_MOVING');
+ $self -> recordEvent ('__PUSH_BACK');
+ $self -> recordEvent ('__ENQUEUE_MOVING');
+
+ $self -> mconfigure (%options);
+ return $self;
+}
+
+sub translate {
+ my ($self, $delta_x, $delta_y) = @_;
+ if ($self -> {__added})
+ {
+ if ((abs ($delta_x) >= $self -> mget ('width') / 2) or (abs ($delta_y) >= $self -> mget ('height') / 2))
+ {
+ my ($mini_dx, $mini_dy) = (int ($delta_x / 2), int ($delta_y / 2));
+ $self -> translate ($mini_dx, $mini_dy);
+ $self -> translate ($delta_x - $mini_dx, $delta_y - $mini_dy);
+ }
+ else
+ {
+ $self -> __try_move ($delta_x, $delta_y, []);
+ $self -> notify ('__HANDLE_MOVING');
+ }
+ }
+ else
+ {
+ $self -> __update_xy ($delta_x, $delta_y);
+ }
+}
+
+sub __search {
+ my ($val, @tab) = @_;
+ my $result = 0;
+ if (($#tab != -1) and (defined $val))
+ {
+ foreach (@tab)
+ {
+ if (($_ eq $val) or ($_ =~ m/$val/))
+ {
+ $result = 1;
+ last;
+ }
+ }
+ }
+ return $result;
+}
+
+sub __try_move {
+ my ($self, $delta_x, $delta_y, $path) = @_;
+ return if __search ($self, @{$path});
+ push (@{$path}, $self);
+ $self -> __update_xy ($delta_x, $delta_y);
+
+ my $label_coords_x = $self -> mget ('x');
+ my $label_coords_y = $self -> mget ('y');
+ my $x_min = $self -> mget ('xmin');
+ my $x_max = $self -> mget ('xmax');
+ my $y_min = $self -> mget ('ymin');
+ my $y_max = $self -> mget ('ymax');
+
+ my ($push_x, $push_y) = (0, 0);
+ $push_x = $x_min - $label_coords_x if $label_coords_x < $x_min;
+ $push_x = $x_max - $label_coords_x if $label_coords_x > $x_max;
+ $push_y = $y_min - $label_coords_y if $label_coords_y < $y_min;
+ $push_y = $y_max - $label_coords_y if $label_coords_y > $y_max;
+ $self -> notify ('__PUSH_BACK', $self, $push_x, $push_y, $path) if (($push_x != 0) or ($push_y != 0));
+
+ if ($self -> mget ('anchors'))
+ {
+ if (defined $self -> {followed_by})
+ {
+ foreach (@{$self -> {followed_by}})
+ {
+ $_ -> __try_move($delta_x + $push_x, $delta_y + $push_y, $path);
+ }
+ }
+ }
+
+ my @other_path = @{$path};
+ $self -> notify ('__ENQUEUE_MOVING', $self, $delta_x + $push_x, $delta_y + $push_y, [@other_path]);
+ pop @{$path};
+}
+
+sub __update_xy {
+ my ($self, $delta_x, $delta_y) = @_;
+ MTools::translate ($self, $delta_x, $delta_y);
+ $self -> mconfigure ('x' => $self -> mget ('x') + $delta_x);
+ $self -> mconfigure ('y' => $self -> mget ('y') + $delta_y);
+ $self -> notify ('TRANSLATED', $delta_x, $delta_y);
+}
+
+sub scale {
+ my ($self, @params) = @_;
+ MTools::scale ($self, @params);
+ $self -> update_bbox ();
+ $self -> translate (0, 0);
+}
+
+sub rotate {
+ my ($self, @params) = @_;
+ MTools::rotate ($self, @params);
+ $self -> update_bbox ();
+ $self -> translate (0, 0);
+}
+
+sub update_bbox {
+ my ($self) = @_;
+ if ($self -> mget ('auto_sizing'))
+ {
+ my @rect = $self -> bbox ();
+ $self -> mconfigure (width => $rect [2] - $rect [0]);
+ $self -> mconfigure (height => $rect [3] - $rect [1]);
+ }
+}
+
+1;