2017-09-14 5 views
0

gtkmmで2つのテキストビューを持つウィンドウを作成しようとします。テキストビューは垂直分割画面として配置する必要があります。そのような : Split screenGTK +/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` 

これは、その結果を生成します。 Too small text views

は、テキストビューは、小規模に明らかにされています。両方のテキストビューでhexpandとvexpandをtrueに設定すると、text_view1はtext_view2を抑止します。

+1

を使用することができますコメントで示唆したように、私は[ 'GtkPaned'](https://developer.gnome.org/gtk3に探し始めるだろう/stable/GtkPaned.html) – Gerhardh

+0

コードに入力ミスがあります。 scrolled_window1にhexpandとvexpandを2回設定します。おそらく、秒をscrolled_window2に変更したいと考えています。 – JohnKoch

答えて

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; 
} 

enter image description here

関連する問題