App-DrivePlayer

 view release on metacpan or  search on metacpan

lib/App/DrivePlayer/GUI.pm  view on Meta::CPAN

        Gtk3::Image->new_from_icon_name('folder-new', 'small-toolbar'),
        'Add Folder'
    );
    $add_btn->signal_connect(clicked => sub { $self->_add_folder_dialog() });
    $tb->insert($add_btn, -1);

    $tb->insert(Gtk3::SeparatorToolItem->new(), -1);

    my $settings_btn = Gtk3::ToolButton->new(
        Gtk3::Image->new_from_icon_name('preferences-system', 'small-toolbar'),
        'Settings'
    );
    $settings_btn->signal_connect(clicked => sub { $self->_settings_dialog() });
    $tb->insert($settings_btn, -1);

    return $tb;
}

sub _build_sidebar {
    my ($self) = @_;
    my $sw = Gtk3::ScrolledWindow->new();
    $sw->set_policy('automatic', 'automatic');
    $sw->set_size_request(100, 1);
    $sw->set_propagate_natural_height(FALSE);

    # TreeStore: label (str), type (str: 'category'|'artist'|'album'|'folder'),
    #            value (str: artist name, album name, folder_id)
    my $store = Gtk3::TreeStore->new('Glib::String', 'Glib::String', 'Glib::String');
    $self->sidebar_store($store);

    my $view = Gtk3::TreeView->new($store);
    $view->set_headers_visible(FALSE);
    $view->get_selection()->set_mode('single');
    $view->signal_connect('cursor-changed'   => sub { $self->_sidebar_activated($view) });
    $view->signal_connect('button-press-event' => sub { $self->_sidebar_button_press($view, $_[1]) });
    $self->sidebar_view($view);

    $view->set_size_request(100, 1);

    my $renderer = Gtk3::CellRendererText->new();
    $renderer->set(ellipsize => 'end');
    my $col = Gtk3::TreeViewColumn->new_with_attributes('', $renderer, text => 0);
    $col->set_sizing('fixed');
    $col->set_expand(TRUE);
    $view->append_column($col);
    $view->set_fixed_height_mode(TRUE);

    $sw->add($view);

    my $hbox = Gtk3::Box->new('horizontal', 0);
    $hbox->pack_start($self->_build_alpha_strip(), FALSE, FALSE, 0);
    $hbox->pack_start($sw, TRUE, TRUE, 0);
    return $hbox;
}

sub _build_alpha_strip {
    my ($self) = @_;

    my $css = Gtk3::CssProvider->new();
    $css->load_from_data(
        'treeview.alpha-nav { font-size: 10px; padding: 0; }'
        . ' treeview.alpha-nav row { min-height: 0; padding: 1px 0; }'
    );

    my $store = Gtk3::ListStore->new('Glib::String');
    for my $letter ('#', 'A' .. 'Z') {
        my $iter = $store->append();
        $store->set($iter, 0, $letter);
    }

    my $view = Gtk3::TreeView->new($store);
    $view->set_headers_visible(FALSE);
    $view->set_fixed_height_mode(TRUE);
    $view->set_can_focus(FALSE);
    $view->set_activate_on_single_click(TRUE);
    $view->get_style_context()->add_class('alpha-nav');
    $view->get_style_context()->add_provider($css, 600);
    $self->alpha_view($view);

    my $renderer = Gtk3::CellRendererText->new();
    $renderer->set(xalign => 0.5);
    my $col = Gtk3::TreeViewColumn->new_with_attributes('', $renderer, text => 0);
    $col->set_sizing('fixed');
    $col->set_fixed_width(32);
    $view->append_column($col);

    $view->signal_connect('row-activated' => sub {
        my ($tv, $path, $col) = @_;
        my $iter = $store->get_iter($path) or return;
        my $letter = $store->get($iter, 0);
        $self->_sidebar_jump_to_letter($letter);
        $tv->get_selection()->unselect_all();
    });

    my $sw = Gtk3::ScrolledWindow->new();
    $sw->set_policy('never', 'automatic');
    $sw->set_size_request(32, 1);
    $sw->set_propagate_natural_height(FALSE);
    $sw->add($view);
    return $sw;
}

sub _sidebar_jump_to_letter {
    my ($self, $letter) = @_;
    my $cat_label = $self->_alpha_category or return;
    my $store = $self->sidebar_store;
    my $view  = $self->sidebar_view;

    my $cat_iter = $store->get_iter_first() or return;
    my $target;
    while (1) {
        if (($store->get($cat_iter, 0) // '') eq $cat_label) {
            $target = $store->get_path($cat_iter);  # snapshot path before iter moves
            last;
        }
        last unless $store->iter_next($cat_iter);
    }
    return unless $target;

    my $target_iter = $store->get_iter($target) or return;
    my $n = $store->iter_n_children($target_iter);



( run in 0.369 second using v1.01-cache-2.11-cpan-5735350b133 )