Разделение экрана с сеткой GTK + / gtkmm

Я пытаюсь сделать окно с gtkmm, в котором у меня есть два текстовых представления. Текстовые представления должны быть организованы как вертикальный разделенный экран.
Как это:
Разделенный экран

Позже я хочу снова и снова разделять экран по вертикали и горизонтали и изменять размер разделенных областей, как в emacs.

Я думал, что простой разделенный экран должен быть легким, но я застрял уже там.
Я думал об использовании Gtk :: Grid в качестве контейнера макета, и каждый раз, когда пользователь хочет разделить экран, я думал о добавлении строки или столбца и добавлении нового текстового представления во вновь создаваемой области.

Вот мой код:

main.cc

#include <gtkmm/application.h>

#include "examplewindow.h"
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

ExampleWindow window;

//Shows the window and returns when it is closed.
return app->run(window);
}

examplewindow.h

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
ExampleWindow();
virtual ~ExampleWindow();

protected:
Gtk::Grid main_grid;
Gtk::ScrolledWindow scrolled_window1;
Gtk::ScrolledWindow scrolled_window2;
Gtk::TextView text_view1;
Gtk::TextView text_view2;

Glib::RefPtr<Gtk::TextBuffer> text_buffer1, text_buffer2;

void fill_buffers();
};

#endif //GTKMM_EXAMPLEWINDOW_H

examplewindow.cc

#include "examplewindow.h"
ExampleWindow::ExampleWindow() {
set_title("Gtk splitted textviews");
set_border_width(12);

add(main_grid);

scrolled_window1.add(text_view1);
scrolled_window1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
scrolled_window2.add(text_view2);
scrolled_window1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);

main_grid.insert_column(0);
main_grid.attach(scrolled_window1, 0, 0, 1, 1);
//scrolled_window1.set_hexpand(true);
//scrolled_window1.set_vexpand(true);

main_grid.attach(scrolled_window2, 1, 0, 1, 1);
//scrolled_window1.set_hexpand(true);
//scrolled_window1.set_vexpand(true);

fill_buffers();
text_view1.set_buffer(text_buffer1);
text_view2.set_buffer(text_buffer2);

show_all_children();
}

ExampleWindow::~ExampleWindow() {}

void ExampleWindow::fill_buffers() {
text_buffer1 = Gtk::TextBuffer::create();
text_buffer1->set_text("This is the text from TextBuffer #1.");

text_buffer2 = Gtk::TextBuffer::create();
text_buffer2->set_text(
"This is some alternative text, from TextBuffer #2.");

}

построить с:

g++ examplewindow.cc main.cc -o splittv `pkg-config gtkmm-3.0 --cflags --libs`

Это дает такой результат:
Слишком маленькие текстовые представления

Виды текста явно малы. Если я установлю для hexpand и vexpand значение true в обоих текстовых представлениях, text_view1 подавит text_view2.

0

Решение

Как @Gerhardh предложенный в комментарии вы можете использовать GtkPaned

#include <gtkmm.h>
#include <memory>
#include <string>

struct Body
{
inline static int i=0;
Gtk::Box Box;
Gtk::Button SplitHButton, SplitVButton, CloseButton;
Gtk::Label Label;
Body()
{
SplitHButton.set_label("h");
SplitVButton.set_label("v");
Label.set_text(std::to_string(i++));
CloseButton.set_label("c");
Box.add(SplitHButton);
Box.add(SplitVButton);
Box.add(Label);
Box.add(CloseButton);
Box.show_all();
}
};

struct Pane
{
Gtk::Paned PaneWidget;
std::shared_ptr<Pane> ChildPane1, ChildPane2;
Body Body1, Body2;
Pane(Gtk::Orientation orientation=Gtk::ORIENTATION_HORIZONTAL):
PaneWidget(orientation)
{
PaneWidget.add1(Body1.Box);
PaneWidget.add2(Body2.Box);

Body1.SplitHButton.signal_clicked().connect([this]{Split(ChildPane1, Gtk::ORIENTATION_HORIZONTAL, Body1, true);});
Body1.SplitVButton.signal_clicked().connect([this]{Split(ChildPane1, Gtk::ORIENTATION_VERTICAL, Body1, true);});
Body2.SplitHButton.signal_clicked().connect([this]{Split(ChildPane2, Gtk::ORIENTATION_HORIZONTAL, Body2, false);});
Body2.SplitVButton.signal_clicked().connect([this]{Split(ChildPane2, Gtk::ORIENTATION_VERTICAL, Body2, false);});

PaneWidget.show_all();
}

void Split(std::shared_ptr<Pane>& pane, Gtk::Orientation orientation, Body& body, bool leftTop)
{
pane = std::make_shared<Pane>(orientation);
PaneWidget.remove(body.Box);
if(leftTop)
PaneWidget.add1(pane->PaneWidget);
else
PaneWidget.add2(pane->PaneWidget);

auto lambda = [&]{
PaneWidget.remove(pane->PaneWidget);
if(leftTop)
PaneWidget.add1(body.Box);
else
PaneWidget.add2(body.Box);
PaneWidget.show_all();
pane.reset();
};

pane->Body1.CloseButton.signal_clicked().connect(lambda);
pane->Body2.CloseButton.signal_clicked().connect(lambda);
}
};

int main()
{
auto GtkApp = Gtk::Application::create();
Gtk::Window w;
Pane p;
w.add(p.PaneWidget);
w.resize(800,600);
w.show_all();
GtkApp->run(w);
return 0;
}

введите описание изображения здесь

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector