Не могу отменить выбор элемента ListBox, щелкнув по нему - PullRequest
0 голосов
/ 26 октября 2019

Я использую gtkmm v3.22.

У меня есть ListBox, который содержит ListBoxRows, который я могу выбрать (для правильной оценки я использую SELECTION_MULTIPLE). Я пытаюсь отменить выбор некоторых выбранных элементов, щелкая по ним, используя on_button_release_event, но не могу заставить его работать. Вот код:

//=======================================================
// Adapted from GTKMM3/C++11 ListBox Example / W.Moore
// https://stackoverflow.com/questions/34253297/how-to-add-text-box-in-gtkmmgtklistbox-using-c/41388444#41388444
//=======================================================
#include <gtkmm.h>
#include <iostream>
#include <string>
#include <initializer_list>
#include <stdio.h>

using namespace std;

class MyListRow;
//======================================================
// My List Box
//======================================================
class MyListBox : public Gtk::ListBox
{
public:
    MyListBox();
    MyListBox(initializer_list<string> list);
    void api_AddRow(string line);
    void print(MyListRow *p);
    void on_row_selected (MyListRow *p)
    {
        print(p);
    }
protected:
    void on_row_selected(Gtk::ListBoxRow *p)
    {
        on_row_selected((MyListRow*)p);
    }
};

//======================================================
// My List Row
//======================================================
class MyListRow : public Gtk::ListBoxRow
{
public:
    MyListRow(const string text)
      : label{text}
    {
       add_events(Gdk::BUTTON_RELEASE_MASK);
       add(label);
       set_halign(Gtk::Align::ALIGN_START);
       label.set_size_request(150); 
       show_all_children();
    }
    bool on_button_release_event (GdkEventButton* release_event)
    {
        if (release_event->button==1 && is_selected()) {
            get_parent()->unselect_row(this);
            return true;
        } else
            return false;
        if (release_event->button==1 && is_selected()) {
            get_parent()->unselect_row(this);
            return true;
        } else
            return false;
    }
    void print()
    {
        printf("Selected %s\n", label.get_text().c_str());
    }

protected:
    Gtk::Label label;
        inline MyListBox *get_parent() {
            return (MyListBox*)ListBoxRow::get_parent();
        }
};

void MyListBox::print(MyListRow *p)
    {
        p->print();
    }

inline MyListBox::MyListBox()
{
    set_selection_mode(Gtk::SELECTION_MULTIPLE);
    show_all_children();
}

inline MyListBox::MyListBox(initializer_list<string> list)
{
    set_selection_mode(Gtk::SELECTION_MULTIPLE);
    for (auto s : list) {
        api_AddRow(s);
    }
}

inline void MyListBox::api_AddRow(string text)
{
    auto row = Gtk::manage(new MyListRow{text});
    append(*row);
    row->show();
}

//======================================================
// My Window
//======================================================
class MyWindow : public Gtk::Window {
  public:
    MyWindow();

  protected:
    MyListBox listbox1 {
        "List Item 1",
        "List Item 2",
        "List Item 3",
        "List Item 4",
        "List Item 5",
        "List Item 6",
        "List Item 7"
    };

};

inline MyWindow::MyWindow() {
  add(listbox1);
  set_title("ListBox Example");
  set_border_width(6);
  set_default_size(300, 100);

  show_all_children();
}

//======================================================
// Main
//======================================================
int main(int argc, char** argv) {
    auto appMain = Gtk::Application::create(argc, argv, "org.gtkmm.example");
    MyWindow MyWindow1;
    appMain->run(MyWindow1);
    return 0;
}

Чтобы увидеть, что происходит, запустите его под GDB и установите точку останова на Gtk::Widget::on_button_release_event. Это покажет, что событие отпускания кнопки передается в Listbox, тогда как предполагалось, что оно было первоначально передано в ListBoxRow (если строка уже была выбрана, она вернула бы true и распространение не продолжалось бы дальше). [Дальнейшая точка останова на линии print(p) в MyListBox позволит вам увидеть адрес MyListBox.]

Что я делаю не так?

...