summaryrefslogtreecommitdiff
path: root/src/gui_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui_gtk.cc')
-rw-r--r--src/gui_gtk.cc177
1 files changed, 168 insertions, 9 deletions
diff --git a/src/gui_gtk.cc b/src/gui_gtk.cc
index 20a6147..c02bdf6 100644
--- a/src/gui_gtk.cc
+++ b/src/gui_gtk.cc
@@ -17,6 +17,7 @@
#include "gui_main.hh"
#include "gui_menu.hh"
#include "gui_message.hh"
+#include "gui_progress.hh"
#include "gui_statusbar.hh"
#include "gui_textwnd.hh"
#include "looper.hh"
@@ -635,6 +636,16 @@ public:
return package_.get();
}
+ void set_content(std::string const& name, AttributedText* text) override;
+
+ AttributedText* content() const {
+ return content_;
+ }
+
+ std::string const& content_name() const {
+ return content_name_;
+ }
+
ListModel* gtklistmodel() const {
return listmodel_.get();
}
@@ -789,6 +800,8 @@ private:
shared_gobject<MainApp> app_;
shared_gobject<ListModel> listmodel_;
std::unique_ptr<AttributedText> package_;
+ AttributedText* content_;
+ std::string content_name_;
std::unique_ptr<GtkConfig> config_;
Observers<GuiMain::Listener*> observers_;
GuiMenu* menu_;
@@ -1777,6 +1790,109 @@ protected:
gulong changed_handler_;
};
+class GtkGuiProgress : public virtual GuiProgress, public GtkGuiWindow {
+public:
+ GtkGuiProgress(std::string const& title, std::string const& text,
+ float min, float max)
+ : title_(title), text_(text), min_(min), max_(max), value_(min),
+ dialog_(nullptr), progress_(nullptr) {
+ }
+
+ ~GtkGuiProgress() override {
+ if (dialog_) gtk_widget_destroy(dialog_);
+ }
+
+ void set_title(std::string const& title) override {
+ title_ = title;
+ GtkGuiWindow::set_title(title);
+ }
+ std::string const& title() const override {
+ return title_;
+ }
+
+ void* impl() const override {
+ return dialog_;
+ }
+
+ void add_listener(GuiProgress::Listener* listener) override {
+ observers_.insert(listener);
+ }
+
+ void remove_listener(GuiProgress::Listener* listener) override {
+ observers_.erase(listener);
+ }
+
+ void set_progress(float value) override {
+ value_ = value;
+ if (progress_) {
+ sync_value();
+ }
+ }
+
+ void show(GuiWindow* parent) override {
+ if (dialog_) {
+ gtk_window_present(GTK_WINDOW(dialog_));
+ assert(false);
+ return;
+ }
+
+ dialog_ = gtk_dialog_new();
+ g_signal_connect(G_OBJECT(dialog_), "delete-event",
+ G_CALLBACK(delete_event), this);
+ gtk_window_set_title(GTK_WINDOW(dialog_), title_.c_str());
+ gtk_window_set_modal(GTK_WINDOW(dialog_), true);
+ auto wnd = reinterpret_cast<GtkWindow*>(parent->impl());
+ gtk_window_set_transient_for(GTK_WINDOW(dialog_), wnd);
+ auto label = gtk_label_new(text_.c_str());
+ progress_ = gtk_progress_bar_new();
+ sync_value();
+ auto content = gtk_dialog_get_content_area(GTK_DIALOG(dialog_));
+ gtk_box_pack_start(GTK_BOX(content), label, true, true, 5);
+ gtk_box_pack_end(GTK_BOX(content), progress_, true, true, 5);
+ gtk_widget_show_all(dialog_);
+ }
+
+private:
+ void sync_value() {
+ assert(progress_);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_),
+ (value_ - min_) / (max_ - min_));
+ }
+
+ bool notify_about_to_close() {
+ auto it = observers_.notify();
+ while (it.has_next()) {
+ if (!it.next()->about_to_close(this)) return false;
+ }
+ return true;
+ }
+
+ static gboolean delete_event(GtkWidget* widget, GdkEvent*,
+ gpointer user_data) {
+ auto me = reinterpret_cast<GtkGuiProgress*>(user_data);
+ assert(me->dialog_ == widget);
+ me->dialog_ = nullptr;
+ auto progress = me->progress_;
+ me->progress_ = nullptr;
+ if (me->notify_about_to_close()) {
+ gtk_widget_destroy(widget);
+ return false;
+ }
+ me->dialog_ = widget;
+ me->progress_ = progress;
+ return true;
+ }
+
+ std::string title_;
+ std::string text_;
+ float min_;
+ float max_;
+ float value_;
+ Observers<GuiProgress::Listener*> observers_;
+ GtkWidget* dialog_;
+ GtkWidget* progress_;
+};
+
struct _MainApp
{
GtkApplication parent_;
@@ -1789,6 +1905,8 @@ struct _MainAppWindow
GtkWidget* paned_;
GtkWidget* top_;
GtkWidget* bottom_;
+ GtkWidget* bottom_content_;
+ GtkWidget* bottom_package_;
};
G_DEFINE_TYPE(MainApp, main_app, GTK_TYPE_APPLICATION);
@@ -1836,17 +1954,32 @@ MainAppWindow* main_app_window_new(MainApp *app) {
gtk_container_add(GTK_CONTAINER(top_scroll), ret->top_);
gtk_paned_add1(GTK_PANED(ret->paned_), top_scroll);
}
- ret->bottom_ = gtk_text_view_new();
- gtk_text_view_set_editable(GTK_TEXT_VIEW(ret->bottom_), false);
- gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(ret->bottom_), false);
- gtk_text_view_set_monospace(GTK_TEXT_VIEW(ret->bottom_), true);
+ ret->bottom_package_ = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(ret->bottom_package_), false);
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(ret->bottom_package_), false);
+ gtk_text_view_set_monospace(GTK_TEXT_VIEW(ret->bottom_package_), true);
if (app->main_->package()) {
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(ret->bottom_),
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(ret->bottom_package_),
static_cast<GtkAttributedText*>(app->main_->package())->buffer());
}
- auto bottom_scroll = gtk_scrolled_window_new(nullptr, nullptr);
- gtk_container_add(GTK_CONTAINER(bottom_scroll), ret->bottom_);
- gtk_paned_add2(GTK_PANED(ret->paned_), bottom_scroll);
+ ret->bottom_content_ = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(ret->bottom_content_), false);
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(ret->bottom_content_), false);
+ gtk_text_view_set_monospace(GTK_TEXT_VIEW(ret->bottom_content_), true);
+ if (app->main_->content()) {
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(ret->bottom_content_),
+ static_cast<GtkAttributedText*>(app->main_->content())->buffer());
+ }
+ ret->bottom_ = gtk_notebook_new();
+ auto scroll = gtk_scrolled_window_new(nullptr, nullptr);
+ gtk_container_add(GTK_CONTAINER(scroll), ret->bottom_package_);
+ auto label = gtk_label_new("Package");
+ gtk_notebook_append_page(GTK_NOTEBOOK(ret->bottom_), scroll, label);
+ scroll = gtk_scrolled_window_new(nullptr, nullptr);
+ gtk_container_add(GTK_CONTAINER(scroll), ret->bottom_content_);
+ label = gtk_label_new(app->main_->content_name().c_str());
+ gtk_notebook_append_page(GTK_NOTEBOOK(ret->bottom_), scroll, label);
+ gtk_paned_add2(GTK_PANED(ret->paned_), ret->bottom_);
gtk_box_pack_start(GTK_BOX(box), ret->paned_, true, true, 0);
auto statusbar = static_cast<GtkGuiStatusBar*>(app->main_->statusbar());
if (statusbar) {
@@ -1989,11 +2122,30 @@ void GtkGuiMain::set_package(std::unique_ptr<AttributedText>&& text) {
} else {
buf = gtk_text_buffer_new(NULL);
}
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(wnd->bottom_), buf);
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(wnd->bottom_package_), buf);
if (!package_) g_object_unref(buf);
}
}
+void GtkGuiMain::set_content(std::string const& name, AttributedText* text) {
+ content_name_ = name;
+ content_ = text;
+ auto wnd = reinterpret_cast<MainAppWindow*>(window());
+ if (wnd) {
+ GtkTextBuffer* buf;
+ if (content_) {
+ buf = static_cast<GtkAttributedText*>(content_)->buffer();
+ } else {
+ buf = gtk_text_buffer_new(NULL);
+ }
+ gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(wnd->bottom_),
+ gtk_widget_get_parent(wnd->bottom_content_),
+ content_name_.c_str());
+ gtk_text_view_set_buffer(GTK_TEXT_VIEW(wnd->bottom_content_), buf);
+ if (!content_) g_object_unref(buf);
+ }
+}
+
void GtkGuiMain::set_split(double split) {
split_ = std::max(0.0, std::min(split, 1.0));
auto wnd = reinterpret_cast<MainAppWindow*>(window());
@@ -2449,3 +2601,10 @@ GuiTextWindow* GuiTextWindow::create(std::string const& title,
AttributedText const* text) {
return new GtkGuiTextWindow(title, width, height, text);
}
+
+// static
+GuiProgress* GuiProgress::create(std::string const& title,
+ std::string const& text,
+ float min, float max) {
+ return new GtkGuiProgress(title, text, min, max);
+}