dk / Prima

prima.eu.org
Other
106 stars 27 forks source link

Feature wish: Spinner widget and indeterminate mode in Prima::Sliders::Gauge #50

Closed MaxPerl closed 7 years ago

MaxPerl commented 7 years ago

Dear Dimitry, I have created a little spinner widget similar as in Gtk3 (see GtkSpinner Widget ). Perhaps this would be a good idea for Prima. There is no progress widget with indeterminate time (I will try to add an indeterminate modus to Prima::Sliders::Gauge but this will last some time).

I noticed some problems:

1) Why does this not work:

sub init
{
    my $self = shift;
    my %profile = $self-> SUPER::init(@_);

    for (qw( style scaleFactor start_angle end_angle is_active colors))
    {$self-> $_($profile{$_}); }

    return %profile;
}

I get the error:

Use of uninitialized value $MySpinner::scale_factor in multiplication (*)

Instead of this I have to do my %profile = $self->SUPER::init(@_); later. I think it is just a problem of understanding in my person..,

2) If color is passed not as BAREWORD but in single or double quotes I get the following errors:

Argument "cl::Blue" isn't numeric in subroutine entry at ./14_toggle_button.pl line 94. Argument "cl::White" isn't numeric in subroutine entry at ./14_toggle_button.pl line 117. and so on....

I am looking forward for your feedback and help.

Best wishes, Max

PS.: I implemented the Module in a little demo program with a button. Then you can see the Widget in action 14_toggle_button.txt

MaxPerl commented 7 years ago

And the standard circle style 14_toggle_button.txt

dk commented 7 years ago

Hi Max,

I think it is a great idea! I can't see why the first problem is there, because I cannot reproduce it, but IIUC if you have skipped the init() altogether, that will be the cause - init() is needed for initial assignment of variables, profile_default() doesn't do that for you. The second problem is quite correct - you write cl::Blacl, not 'cl::Black'. cl:: is just another modeul namespace.

I have design suggestions:

my $timer = Timer->new(...)

you can do

$self->{timer} = Timer->new(...)

Also, you can create it directly inside init(), but before assigning the variables, so that start/stop don't have to check if the timer is created yet.

Great idea!

MaxPerl commented 7 years ago

Dear Dimitry, Thanks for your great suggestions and ideas. I think most of them I could implement. Only the following things doesn't work as expected:

1) Setting up "color" as property name doesn't work (I think there is a conflict with the color property of Prima::Canvas or something else). At the moment I moved to "Color". This works just fine

2) Could you check the active function. I don't know whether I understood you correctly. Is this the way you want to go? I like it very much now..

3) For "Drawing the spinner so it covers the whole widget" I really need some time. I think for the circle style it should be no problem. But for the drop style it could be very difficult. But I will give it a try. I see the advantages of covering the whole widget, too.

I will put it altogether to a Module and add a POD documentation the next week. Do you think, the module would be worth to insert it to the core of Prima. Or shall I create a separate module?

Enclosed the new version: 14_toggle_button.txt

dk commented 7 years ago

Hi Max,

Great, I think this is going the right direction! Here's the comments:

1: color - almost there. This is exactly because there are existing color and hiliteColor properties, I suggested to reuse them. Basically, you don't need to define 'sub color' and 'sub hiliteColor', and so it just works.

  1. Yes, almost there - the second branch of 'if' just needs to return the current active status (the 'getter' role). You can also choose to remove 'sub stop' and 'sub start' for brevity sake, too.

  2. Yes, that could be a bit difficult indeed. I'd suggest you do this:

    • calculate $min_extent = ($width > $height) ? $height : $width
    • calculate $scale_factor from $min_extent
    • remove 'sub scaleFactor' from being the global property

I think that the module is definitely worth adding to the core. But the code needs to be polished a bit to look like the rest of the toolkit. Here's what I can suggest:

$self->{timer} = Timer->new( ... , name => 'Timer', delegations => ['Tick'] ); ... sub Timer_Tick {

}

( you can take a look at f.ex. Prima/PrintDialog, on delegations => ['Change'] / Printers_Change code ). This way the programmer can override the Timer_Tick.

The nice-to-have would be to make the spinners not black and white, but using gray levels. This will be tricky, but at least Prima has ability calculate the color shades of of two colors (see f.ex. implementation of gradient_bar in Prima/Drawable/Basic.pm ). If that will be too hard, I can help here.

Other than this I think this is all going good! After you have shaped the code, you're welcome to send the pull request as Prima/Spinner.pm (and possibly example/spinner.pl ) and I'll merge.

Hope this all makes sense! :)

Dmitry

MaxPerl commented 7 years ago

I opened a Pull request where we can continue the discussion. Therefore I close this thread...