Leser: 1
![]() |
|< 1 2 3 4 >| | ![]() |
38 Einträge, 4 Seiten |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use FindBin qw($Bin); chdir($Bin);
use lib $FindBin::Bin . '/LIBS'; use X; #in zusätzlichen sub dir "X", daher X::
#use SDL::X;
my $container = X->new();
$GFXButton = X::GFXButton;
$|=1;
use SDL;
use SDL::App;
use SDL::Event;
use SDL::Surface;
use SDL::Color;
use SDL::Rect;
my $app = SDL::App->new(-width => 730,-height => 430,-depth => 16,);
$event = new SDL::Event();
$img = SDL::Surface->new( -name => 'x.png' ); $img2 = SDL::Surface->new( -name => 'x_on.png' ); $img3 = SDL::Surface->new( -name => 'x_click.png' );
#Button hinzufügen...(test)
for my $i (0..15) { for my $x (0..10) { $id++;
$container->GFXButton_add($id,$app,(65*$x),(25*$i),$img,$img2,$img3, 'loslos'); }}
while(1)
{
#process event queue
$event->pump;
$event->poll;
my $etype=$event->type;
# handle user events
last if ($etype eq SDL_QUIT );
last if (SDL::GetKeyState(SDLK_ESCAPE));
($active_element, $B_event_sub) = $container->checkall($event->button_x,$event->button_y);
if($etype eq SDL_MOUSEBUTTONDOWN && $active_element)
{
$active_element->button_down();
if($B_event_sub) {&{$B_event_sub}($active_element);};
}
#if ( $active_element ) { $active_element->set('PRESSED',1); };
if($etype eq SDL_MOUSEBUTTONUP) {$GFXButton->buttons_up($container);$GFXButton->destroy_buttons($container);}
}
#Button Event
sub loslos
{
my $self = shift; my ($ID, $IMG ) = $self->get("ID", "IMG");
print "\n $ID - $IMG ";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package X;
use X::GFXButton;
my $GFXButton = X::GFXButton;
#Erzeugen
sub new {
my ($class,@params) = @_;
my $self = {};
bless($self,$class);
$self->{BUTTS} = [];
return($self);
}
#------------ Alle Elemente Prüfen --------------------
sub checkall
{
my ($self, $mx, $my) = @_;
my $active_element = 0;
my $B_event_sub = 0;
#Buttons Prüfen
for(@{$self->{BUTTS}}) {
if($_->check_button($mx,$my)){$active_element = $_;}
}
#Events bearbeiten....
if($active_element) {$B_event_sub = $active_element->{DOSUB};}
return ($active_element, $B_event_sub); #Object and the sub
}
#------------------------ ELEMENTE ------------------------
sub GFXButton_add
{return $GFXButton->new(@_);}
1;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package X::GFXButton;
use strict;
#----------------------------------------------------- INI --------------------------------------------------------
#Erzeugen
sub new {
my ($class,@params) = @_;
my $self = {};
bless($self,$class);
#for(qw(ID APP X Y IMG IMGHV)){$self->{$_} = shift(@params);}
$self->{CONTAINER} = shift(@params); #Container
$self->{ID} = shift(@params); #ID oder Name
$self->{APP} = shift(@params); #SDL APP
$self->{X} = shift(@params);
$self->{Y} = shift(@params);
$self->{IMG} = shift(@params); #IMG normal
$self->{IMGHV} = shift(@params); #IMG hover
$self->{IMG_click} = shift(@params); #IMG click
$self->{DOSUB} = shift(@params);#Button's sub
$self->{TXT} = shift(@params); #Button's Text
$self->{HV} = 0; #Hover state
$self->draw($self->{IMG}); #Display
push( @{$self->{CONTAINER}->{BUTTS}} , $self);
return($self);
}
sub check_button
{
my ($self, $mx, $my) = @_;
my $img = $self->{IMG};
#Hover - Effekt
if($mx > $self->{X} && $mx < ($self->{X}+ $img->width) && $my > $self->{Y} && $my < ($self->{Y}+ $img->height) )
{
if($self->{PRESSED} eq 1){$self->draw($self->{IMG_click});} else
{
if(not $self->{HV}) {$self->{HV}=1; $self->draw($self->{IMGHV});}
}
return $self;
} else
{
if($self->{PRESSED} eq 1){$self->draw($self->{IMG_click});} else
{
if($self->{HV}) {$self->{HV}=0; $self->draw($self->{IMG});}
}
}
return 0;
}
#---------------------------------------------------------- CODE OK ----------------------------------------------------------
#Grafik darstellen
sub draw
{
my ($self, $img) = @_;
my $dest_rect = SDL::Rect->new(-height => $img->height(),-width => $img->width(),-x=> $self->{X},-y => $self->{Y});
$img->blit( SDL::Rect->new(-height => $img->height(),-width => $img->width(),-x => 0, -y => 0), $self->{APP}, $dest_rect );
$self->{APP}->update( $dest_rect );
}
#Button geklickt darstellen
sub button_down { $_->{PRESSED} = 1;}
#Bei MausUP Buttons normal zeichnen
sub buttons_up {
my ($self, $container) = @_;
for(@{$container->{BUTTS}})
{$_->{PRESSED} = 0; $_->draw($_->{IMG});}
}
#Button_on
#Button_off
#Buttons_on
#Buttons_off
#Buttons nicht mehr prüfen
sub destroy_buttons {
my ($self, $container) = @_;
$container->{BUTTS} = [];}
#Parameter zurückgeben (mehrere)
sub get
{my ($self, @values) = @_; my @out = ();for(@values) {push(@out,$self->{"$_"}); } return @out;}
#Einelnen Parameter setzen
sub set
{my ($self, $param, $value) = @_; $self->{$param} = $value;}
1;
1
2
3
4
5
6
7
8
9
10
#Bei MausUP Buttons normal zeichnen
sub buttons_up {
my ($self, $container) = @_;
for(@{$container->{BUTTS}})
{$_->{PRESSED} = 0; $_->draw($_->{IMG});}
}
Aufruf:
$GFXButton->buttons_up($container);
1
2
3
4
5
6
7
8
9
10
11
$container->add_button(%button_args);
{
package Container;
sub add_button {
my($self, %button_args) = @_;
my $button = Button->new(%button_args, -container => $self);
push @{$self->buttons}, $button;
$button;
}
}
QuoteWenn du eine Rückreferenz von Button auf Container brauchst: dann übergib einfach die Container-Referenz und speichere sie irgendwo im Button-Objekt. Denk aber daran, dass du diese Referenz per Scalar::Util::weaken "schwach" machst, weil du dir ansonsten eine zirkuläre Referenz baust, die Perl nicht automatisch auflösen kann.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
my $container = X->new(); #conti erzeugen
$container->GFXButton_add(PARAMENTer);
#--sub-- des contis, gibt
$GFXButton = X::GFXButton;
sub GFXButton_add
{return $GFXButton->new(@_);}
#--new-methode von GFXButton ---
#Erzeugen
sub new {
my ($class,@params) = @_;
my $self = {};
bless($self,$class);
#for(qw(ID APP X Y IMG IMGHV)){$self->{$_} = shift(@params);}
$self->{CONTAINER} = shift(@params); #Container
$self->{ID} = shift(@params); &n
bsp; #ID oder Name
$self->{APP} = shift(@params);
......
......
......
push( @{$self->{CONTAINER}->{BUTTS} } , $self);
return($self);
}
1
2
3
4
5
6
7
use Scalar::Util qw(weaken);
...
sub GFXButton::new {
my($class, $container, ...) = @_;
weaken $container;
... Rest des Codes ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Scalar::Util qw(weaken);
use Devel::Peek;
sub Container::DESTROY {
warn "Container $_[0] is destroyed!";
}
{
my $container = bless {}, "Container";
Dump $container;
my $button = bless { container => $container }, "Button";
push @{$container->{buttons}}, $button;
Dump $container;
weaken $button->{container};
Dump $container;
}
__END__
$self->{CONTAINER} = shift(@params); #Container
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
my $self = shift;
my $bg = shift;
my $fg = shift;
# Button Objekt, Fordergrund- und Hintergrundfarbe
# werden übergeben.
my $width = int($self->{FONT}->width($self->{TEXT}) + 16);
my $height = int($self->{SIZE} + 20);
# Die Höhe und Breite von $border (s.u.) bekommst du
# durch den Font, den man benutzen möchte und eine
# SIZE Option, welche der -size Option im Font gleicht.
# Rechtecke zeichnen:
my $border = SDL::Rect->new
(-height => $height,
-width => $width,
-x => $self->{X},
-y => $self->{Y});
my $inline = SDL::Rect->new
(-height => $height-4,
-width => $width-4,
-x => $self->{X}+2,
-y => $self->{Y}+2);
# $inline kleiner als $border, da man ja den Rand auch noch
# sehen soll.
# Rechtecke füllen:
$self->{APP} -> fill($border,$bg);
$self->{APP} -> fill($inline,$fg);
# Text-Position berechnen:
# X bekommst du, indem du einfach die X-Position des
# Rechteckes + 8 nimmst.
# Y bekommst du, indem du die Höhe des Rechteckes / 2
# teilst, die Y-Position des Rechteckes addierst und die
# Höhe des Textes anhand des benutzten Fonts / 2 geteilt
# subtraierst.
# Allerdings nur, wenn du möchtest, dass der Text in der
# Mitte steht und nicht so dicht am Rand.
my $nx = $self->{X} + 8;
my $ny = int((($height / 2) + $self->{Y}) - $self->{FONT}->height($self->{TEXT}) / 2);
# Text ausgeben:
$self->{FONT} -> print ($self->{APP},$nx,$ny,$self->{TEXT});
# Bereich 'neu laden' und
# APP flippen:
$self->{APP} -> update($border);
$self->{APP} -> flip ();
1
2
3
4
5
6
#Umleitung zur fastdraw-Methode
sub draw_butt {
$_[0]->{CONTAINER}->fastdraw($_[1], $_[0]->{X}, $_[0]->{Y});
if($_[0]->{TXT} ne '') {} #Im Notfall wieder einbauen
}
![]() |
|< 1 2 3 4 >| | ![]() |
38 Einträge, 4 Seiten |