1 | package DC::UI; |
1 | package DC::UI; |
2 | |
2 | |
3 | use utf8; |
3 | use common::sense; |
4 | use strict; |
|
|
5 | |
4 | |
6 | use List::Util (); |
5 | use List::Util (); |
7 | |
6 | |
|
|
7 | use AnyEvent (); |
8 | use Guard (); |
8 | use Guard (); |
9 | |
9 | |
10 | use DC; |
10 | use DC; |
11 | use DC::Pod; |
11 | use DC::Pod; |
12 | use DC::Texture; |
12 | use DC::Texture; |
… | |
… | |
223 | |
223 | |
224 | ############################################################################# |
224 | ############################################################################# |
225 | |
225 | |
226 | package DC::UI::Base; |
226 | package DC::UI::Base; |
227 | |
227 | |
228 | use strict; |
228 | use common::sense; |
229 | |
229 | |
230 | use DC::OpenGL; |
230 | use DC::OpenGL; |
231 | |
231 | |
232 | sub new { |
232 | sub new { |
233 | my $class = shift; |
233 | my $class = shift; |
… | |
… | |
643 | |
643 | |
644 | package DC::UI::DrawBG; |
644 | package DC::UI::DrawBG; |
645 | |
645 | |
646 | our @ISA = DC::UI::Base::; |
646 | our @ISA = DC::UI::Base::; |
647 | |
647 | |
648 | use strict; |
648 | use common::sense; |
|
|
649 | |
649 | use DC::OpenGL; |
650 | use DC::OpenGL; |
650 | |
651 | |
651 | sub new { |
652 | sub new { |
652 | my $class = shift; |
653 | my $class = shift; |
653 | |
654 | |
… | |
… | |
656 | #active_bg => [1, 1, 1, 0.5], |
657 | #active_bg => [1, 1, 1, 0.5], |
657 | @_ |
658 | @_ |
658 | ) |
659 | ) |
659 | } |
660 | } |
660 | |
661 | |
|
|
662 | sub set_bg { |
|
|
663 | my ($self, $bg) = @_; |
|
|
664 | |
|
|
665 | $self->{bg} = $bg; |
|
|
666 | $self->update; |
|
|
667 | } |
|
|
668 | |
661 | sub _draw { |
669 | sub _draw { |
662 | my ($self) = @_; |
670 | my ($self) = @_; |
663 | |
671 | |
664 | my $color = $FOCUS == $self && $self->{active_bg} |
672 | my $color = $FOCUS == $self |
665 | ? $self->{active_bg} |
673 | ? $self->{active_bg} || $self->{bg} |
666 | : $self->{bg}; |
674 | : $self->{bg}; |
667 | |
675 | |
668 | if ($color && (@$color < 4 || $color->[3])) { |
676 | if ($color && (@$color < 4 || $color->[3])) { |
669 | my ($w, $h) = @$self{qw(w h)}; |
677 | my ($w, $h) = @$self{qw(w h)}; |
670 | |
678 | |
… | |
… | |
2587 | |
2595 | |
2588 | ############################################################################# |
2596 | ############################################################################# |
2589 | |
2597 | |
2590 | package DC::UI::Image; |
2598 | package DC::UI::Image; |
2591 | |
2599 | |
2592 | our @ISA = DC::UI::Base::; |
2600 | our @ISA = DC::UI::DrawBG::; |
2593 | |
2601 | |
2594 | use DC::OpenGL; |
2602 | use DC::OpenGL; |
2595 | |
2603 | |
2596 | our %texture_cache; |
2604 | our %texture_cache; |
2597 | |
2605 | |
… | |
… | |
2630 | my ($self, $cloning, $path) = @_; |
2638 | my ($self, $cloning, $path) = @_; |
2631 | |
2639 | |
2632 | $self->new (path => $path) |
2640 | $self->new (path => $path) |
2633 | } |
2641 | } |
2634 | |
2642 | |
|
|
2643 | sub set_texture { |
|
|
2644 | my ($self, $tex) = @_; |
|
|
2645 | |
|
|
2646 | $self->{tex} = $tex; |
|
|
2647 | $self->update; |
|
|
2648 | } |
|
|
2649 | |
2635 | sub size_request { |
2650 | sub size_request { |
2636 | my ($self) = @_; |
2651 | my ($self) = @_; |
2637 | |
2652 | |
2638 | (int $self->{tex}{w} * $self->{scale}, int $self->{tex}{h} * $self->{scale}) |
2653 | (int $self->{tex}{w} * $self->{scale}, int $self->{tex}{h} * $self->{scale}) |
2639 | } |
2654 | } |
2640 | |
2655 | |
2641 | sub _draw { |
2656 | sub _draw { |
2642 | my ($self) = @_; |
2657 | my ($self) = @_; |
|
|
2658 | |
|
|
2659 | $self->SUPER::_draw; |
2643 | |
2660 | |
2644 | my $tex = $self->{tex}; |
2661 | my $tex = $self->{tex}; |
2645 | |
2662 | |
2646 | my ($w, $h) = ($self->{w}, $self->{h}); |
2663 | my ($w, $h) = ($self->{w}, $self->{h}); |
2647 | |
2664 | |
… | |
… | |
2665 | package DC::UI::ImageButton; |
2682 | package DC::UI::ImageButton; |
2666 | |
2683 | |
2667 | our @ISA = DC::UI::Image::; |
2684 | our @ISA = DC::UI::Image::; |
2668 | |
2685 | |
2669 | use DC::OpenGL; |
2686 | use DC::OpenGL; |
2670 | |
|
|
2671 | my %textures; |
|
|
2672 | |
2687 | |
2673 | sub new { |
2688 | sub new { |
2674 | my $class = shift; |
2689 | my $class = shift; |
2675 | |
2690 | |
2676 | my $self = $class->SUPER::new ( |
2691 | my $self = $class->SUPER::new ( |
… | |
… | |
3040 | |
3055 | |
3041 | ############################################################################# |
3056 | ############################################################################# |
3042 | |
3057 | |
3043 | package DC::UI::Slider; |
3058 | package DC::UI::Slider; |
3044 | |
3059 | |
3045 | use strict; |
3060 | use common::sense; |
3046 | |
3061 | |
3047 | use DC::OpenGL; |
3062 | use DC::OpenGL; |
3048 | |
3063 | |
3049 | our @ISA = DC::UI::DrawBG::; |
3064 | our @ISA = DC::UI::DrawBG::; |
3050 | |
3065 | |
… | |
… | |
3136 | if ($GRAB == $self) { |
3151 | if ($GRAB == $self) { |
3137 | my ($x, $w) = $self->{vertical} ? ($y, $self->{h}) : ($x, $self->{w}); |
3152 | my ($x, $w) = $self->{vertical} ? ($y, $self->{h}) : ($x, $self->{w}); |
3138 | |
3153 | |
3139 | my (undef, $lo, $hi, $page) = @{$self->{range}}; |
3154 | my (undef, $lo, $hi, $page) = @{$self->{range}}; |
3140 | |
3155 | |
3141 | $x = ($x - $self->{click}[1]) / ($w * $self->{scale}); |
3156 | $x = ($x - $self->{click}[1]) / ($w * $self->{scale} || 1e999); |
3142 | |
3157 | |
3143 | $self->set_value ($self->{click}[0] + $x * ($hi - $page - $lo)); |
3158 | $self->set_value ($self->{click}[0] + $x * ($hi - $page - $lo)); |
3144 | } else { |
3159 | } else { |
3145 | return 0; |
3160 | return 0; |
3146 | } |
3161 | } |
… | |
… | |
3726 | aspect => 1, |
3741 | aspect => 1, |
3727 | can_events => 0, |
3742 | can_events => 0, |
3728 | @_, |
3743 | @_, |
3729 | ); |
3744 | ); |
3730 | |
3745 | |
3731 | if ($self->{anim} && $self->{animspeed}) { |
|
|
3732 | DC::weaken (my $widget = $self); |
|
|
3733 | |
|
|
3734 | $self->{animspeed} = List::Util::max 0.05, $self->{animspeed}; |
|
|
3735 | $self->{timer} = EV::periodic_ns 0, $self->{animspeed}, undef, sub { |
|
|
3736 | return unless $::CONN; |
|
|
3737 | |
|
|
3738 | my $w = $widget |
|
|
3739 | or return; |
|
|
3740 | |
|
|
3741 | ++$w->{frame}; |
|
|
3742 | $w->update_face; |
|
|
3743 | |
|
|
3744 | # somehow, $widget can go away |
|
|
3745 | $w->update; |
|
|
3746 | $w->update_timer; |
|
|
3747 | }; |
|
|
3748 | |
|
|
3749 | $self->update_face; |
|
|
3750 | $self->update_timer; |
3746 | $self->update_anim; |
3751 | } |
|
|
3752 | |
3747 | |
3753 | $self |
3748 | $self |
3754 | } |
3749 | } |
3755 | |
3750 | |
3756 | sub update_timer { |
3751 | sub update_timer { |
… | |
… | |
3779 | $tex->upload (sub { $self->reconfigure }); |
3774 | $tex->upload (sub { $self->reconfigure }); |
3780 | } |
3775 | } |
3781 | } |
3776 | } |
3782 | } |
3777 | } |
3783 | } |
3778 | } |
|
|
3779 | } |
|
|
3780 | } |
|
|
3781 | |
|
|
3782 | sub update_anim { |
|
|
3783 | my ($self) = @_; |
|
|
3784 | |
|
|
3785 | if ($self->{anim} && $self->{animspeed}) { |
|
|
3786 | DC::weaken (my $widget = $self); |
|
|
3787 | |
|
|
3788 | $self->{animspeed} = List::Util::max 0.05, $self->{animspeed}; |
|
|
3789 | $self->{timer} = EV::periodic_ns 0, $self->{animspeed}, undef, sub { |
|
|
3790 | return unless $::CONN; |
|
|
3791 | |
|
|
3792 | my $w = $widget |
|
|
3793 | or return; |
|
|
3794 | |
|
|
3795 | ++$w->{frame}; |
|
|
3796 | $w->update_face; |
|
|
3797 | |
|
|
3798 | # somehow, $widget can go away |
|
|
3799 | $w->update; |
|
|
3800 | $w->update_timer; |
|
|
3801 | }; |
|
|
3802 | |
|
|
3803 | $self->update_face; |
|
|
3804 | $self->update_timer; |
|
|
3805 | } else { |
|
|
3806 | delete $self->{timer}; |
3784 | } |
3807 | } |
3785 | } |
3808 | } |
3786 | |
3809 | |
3787 | sub size_request { |
3810 | sub size_request { |
3788 | my ($self) = @_; |
3811 | my ($self) = @_; |
… | |
… | |
3808 | my ($self) = @_; |
3831 | my ($self) = @_; |
3809 | |
3832 | |
3810 | return unless $self->{visible}; |
3833 | return unless $self->{visible}; |
3811 | |
3834 | |
3812 | $self->SUPER::update; |
3835 | $self->SUPER::update; |
|
|
3836 | } |
|
|
3837 | |
|
|
3838 | sub set_face { |
|
|
3839 | my ($self, $face) = @_; |
|
|
3840 | |
|
|
3841 | $self->{face} = $face; |
|
|
3842 | $self->reconfigure; |
|
|
3843 | } |
|
|
3844 | |
|
|
3845 | sub set_anim { |
|
|
3846 | my ($self, $anim) = @_; |
|
|
3847 | |
|
|
3848 | $self->{anim} = $anim; |
|
|
3849 | $self->update_anim; |
|
|
3850 | } |
|
|
3851 | |
|
|
3852 | sub set_animspeed { |
|
|
3853 | my ($self, $animspeed) = @_; |
|
|
3854 | |
|
|
3855 | $self->{animspeed} = $animspeed; |
|
|
3856 | $self->update_anim; |
3813 | } |
3857 | } |
3814 | |
3858 | |
3815 | sub invoke_visibility_change { |
3859 | sub invoke_visibility_change { |
3816 | my ($self) = @_; |
3860 | my ($self) = @_; |
3817 | |
3861 | |
… | |
… | |
4249 | $self |
4293 | $self |
4250 | } |
4294 | } |
4251 | |
4295 | |
4252 | sub reorder { |
4296 | sub reorder { |
4253 | my ($self) = @_; |
4297 | my ($self) = @_; |
4254 | my $NOW = EV::time; |
4298 | my $NOW = AE::time; |
4255 | |
4299 | |
4256 | # freeze display when hovering over any label |
4300 | # freeze display when hovering over any label |
4257 | return if $DC::UI::TOOLTIP->{owner} |
4301 | return if $DC::UI::TOOLTIP->{owner} |
4258 | && grep $DC::UI::TOOLTIP->{owner} == $_->{label}, |
4302 | && grep $DC::UI::TOOLTIP->{owner} == $_->{label}, |
4259 | values %{ $self->{item} }; |
4303 | values %{ $self->{item} }; |