exampleappwin.c 5.19 KB
Newer Older
1 2
#include <gtk/gtk.h>

Matthias Clasen's avatar
Matthias Clasen committed
3 4 5
#include "exampleapp.h"
#include "exampleappwin.h"

6 7 8
struct _ExampleAppWindow
{
  GtkApplicationWindow parent;
Matthias Clasen's avatar
Matthias Clasen committed
9 10
};

11
typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
Matthias Clasen's avatar
Matthias Clasen committed
12

13 14 15 16 17 18
struct _ExampleAppWindowPrivate
{
  GSettings *settings;
  GtkWidget *stack;
  GtkWidget *search;
  GtkWidget *searchbar;
Matthias Clasen's avatar
Matthias Clasen committed
19 20 21 22 23
};

G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);

static void
24
search_text_changed (GtkEntry *entry)
Matthias Clasen's avatar
Matthias Clasen committed
25
{
26
  ExampleAppWindow *win;
27 28 29 30 31 32 33 34 35 36 37 38
  ExampleAppWindowPrivate *priv;
  const gchar *text;
  GtkWidget *tab;
  GtkWidget *view;
  GtkTextBuffer *buffer;
  GtkTextIter start, match_start, match_end;

  text = gtk_entry_get_text (entry);

  if (text[0] == '\0')
    return;

39
  win = EXAMPLE_APP_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry)));
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
  priv = example_app_window_get_instance_private (win);

  tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
  view = gtk_bin_get_child (GTK_BIN (tab));
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

  /* Very simple-minded search implementation */
  gtk_text_buffer_get_start_iter (buffer, &start);
  if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
                                    &match_start, &match_end, NULL))
    {
      gtk_text_buffer_select_range (buffer, &match_start, &match_end);
      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
                                    0.0, FALSE, 0.0, 0.0);
    }
Matthias Clasen's avatar
Matthias Clasen committed
55 56 57
}

static void
58 59
visible_child_changed (GObject    *stack,
                       GParamSpec *pspec)
Matthias Clasen's avatar
Matthias Clasen committed
60
{
61
  ExampleAppWindow *win;
62
  ExampleAppWindowPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
63

64
  if (gtk_widget_in_destruction (GTK_WIDGET (stack)))
65 66
    return;

67 68
  win = EXAMPLE_APP_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (stack)));

69 70
  priv = example_app_window_get_instance_private (win);
  gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->searchbar), FALSE);
Matthias Clasen's avatar
Matthias Clasen committed
71 72 73 74 75
}

static void
example_app_window_init (ExampleAppWindow *win)
{
76
  ExampleAppWindowPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
77

78 79 80
  priv = example_app_window_get_instance_private (win);
  gtk_widget_init_template (GTK_WIDGET (win));
  priv->settings = g_settings_new ("org.gtk.exampleapp");
Matthias Clasen's avatar
Matthias Clasen committed
81

82 83 84
  g_settings_bind (priv->settings, "transition",
                   priv->stack, "transition-type",
                   G_SETTINGS_BIND_DEFAULT);
Matthias Clasen's avatar
Matthias Clasen committed
85

86 87 88
  g_object_bind_property (priv->search, "active",
                          priv->searchbar, "search-mode-enabled",
                          G_BINDING_BIDIRECTIONAL);
Matthias Clasen's avatar
Matthias Clasen committed
89 90 91 92 93
}

static void
example_app_window_dispose (GObject *object)
{
94 95
  ExampleAppWindow *win;
  ExampleAppWindowPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
96

97 98
  win = EXAMPLE_APP_WINDOW (object);
  priv = example_app_window_get_instance_private (win);
Matthias Clasen's avatar
Matthias Clasen committed
99

100
  g_clear_object (&priv->settings);
Matthias Clasen's avatar
Matthias Clasen committed
101

102
  G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
Matthias Clasen's avatar
Matthias Clasen committed
103 104 105 106 107
}

static void
example_app_window_class_init (ExampleAppWindowClass *class)
{
108 109 110 111
  G_OBJECT_CLASS (class)->dispose = example_app_window_dispose;

  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
                                               "/org/gtk/exampleapp/window.ui");
112

113 114 115
  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
116 117 118

  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), visible_child_changed);
Matthias Clasen's avatar
Matthias Clasen committed
119 120 121 122 123
}

ExampleAppWindow *
example_app_window_new (ExampleApp *app)
{
124
  return g_object_new (EXAMPLE_APP_WINDOW_TYPE, "application", app, NULL);
Matthias Clasen's avatar
Matthias Clasen committed
125 126 127 128 129 130
}

void
example_app_window_open (ExampleAppWindow *win,
                         GFile            *file)
{
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  ExampleAppWindowPrivate *priv;
  gchar *basename;
  GtkWidget *scrolled, *view;
  gchar *contents;
  gsize length;
  GtkTextBuffer *buffer;
  GtkTextTag *tag;
  GtkTextIter start_iter, end_iter;

  priv = example_app_window_get_instance_private (win);
  basename = g_file_get_basename (file);

  scrolled = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolled);
  gtk_widget_set_hexpand (scrolled, TRUE);
  gtk_widget_set_vexpand (scrolled, TRUE);
  view = gtk_text_view_new ();
  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
  gtk_widget_show (view);
  gtk_container_add (GTK_CONTAINER (scrolled), view);
  gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);

  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

  if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
    {
      gtk_text_buffer_set_text (buffer, contents, length);
      g_free (contents);
    }

  tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
  g_settings_bind (priv->settings, "font",
                   tag, "font",
                   G_SETTINGS_BIND_DEFAULT);

  gtk_text_buffer_get_start_iter (buffer, &start_iter);
  gtk_text_buffer_get_end_iter (buffer, &end_iter);
  gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);

  g_free (basename);

  gtk_widget_set_sensitive (priv->search, TRUE);
Matthias Clasen's avatar
Matthias Clasen committed
174
}