From 485e7d382e130e8267dae337dc335ae75e5c2ef4 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 28 Mar 2007 02:18:05 +0000 Subject: WriteRoom/DarkRoom clone --- editor.cc | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 editor.cc (limited to 'editor.cc') diff --git a/editor.cc b/editor.cc new file mode 100644 index 0000000..7f591b7 --- /dev/null +++ b/editor.cc @@ -0,0 +1,224 @@ +/* $Id$ */ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This program is simply a sensory-deprivation themed text editor, for concentration purposes. + * CTRL+SHIFT+BACKSPACE quits, CTRL+SHIFT+S saves. The first line is used as the filename. + * Compile with -DSCROLL option to enable a vertical scrollbar. + */ + +#include +#include + +#include +#include +#include + +using namespace std; + +void Destroy(); +gboolean Accel(GtkAccelGroup * accel_group, GObject * acceleratable, guint keyval, GdkModifierType modifier); +void modify_cursor_color(GtkWidget * widget, GdkColor * color); + +GtkWindow *window = NULL; +GtkWidget *scroll = NULL; +GtkWidget *edit = NULL; + +/* the main program is given as a DLL when compiled for Windows to allow the main program to locate the GTK + * runtimes before executing the program itself. This is irrelevant to any other platform. */ + +#ifdef _WIN32 +#include +extern "C" +__declspec(dllexport) int +Main(int argc, char *argv[]) +#else +int +main(int argc, char *argv[]) +#endif +{ + gtk_init(&argc, &argv); + + /* create the window */ + window = (GtkWindow *) gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_fullscreen(window); + gtk_window_set_title(window, "Editor"); + gtk_window_set_keep_above(window, true); + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 400); + g_signal_connect(window, "delete_event", G_CALLBACK(Destroy), NULL); + edit = gtk_text_view_new(); + + /* set the side margins for maximum readability */ + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(edit), 256); + gtk_text_view_set_right_margin(GTK_TEXT_VIEW(edit), 256); + gtk_widget_set_name(edit, "GtkEditorView"); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(edit), GTK_WRAP_WORD); + scroll = gtk_scrolled_window_new(NULL, NULL); + + /* simply add a scroll window to allow for convenient scrolling + * capabilities like the mouse wheel */ + gtk_container_add(GTK_CONTAINER(window), scroll); + ((GtkScrolledWindow *) scroll)->hscrollbar_policy = GTK_POLICY_NEVER; +#ifdef SCROLL + ((GtkScrolledWindow *) scroll)->vscrollbar_policy = GTK_POLICY_AUTOMATIC; +#else + ((GtkScrolledWindow *) scroll)->vscrollbar_policy = GTK_POLICY_NEVER; +#endif + gtk_container_add(GTK_CONTAINER(scroll), edit); + + GdkColor color; + gdk_color_parse("black", &color); + gtk_widget_modify_base(edit, GTK_STATE_NORMAL, &color); + + gdk_color_parse("green", &color); + gtk_widget_modify_text(edit, GTK_STATE_NORMAL, &color); + + gdk_color_parse("yellow", &color); + modify_cursor_color(edit, &color); + + /* set the font to monospace */ + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit)); + PangoFontDescription *font_desc = pango_font_description_from_string("Courier New,Monospace 12"); + gtk_widget_modify_font(edit, font_desc); + pango_font_description_free(font_desc); + + /* if specified in the command prompt, attempt to open a file */ + if (argc > 1) { + ifstream file(argv[1]); + if (file) { + /* prepend the file name on its own line for saving + * purposes */ + string body = argv[1]; + body.append("\n"); + while (file && file.peek() != EOF) + body += file.get(); + gtk_text_buffer_set_text(buffer, body.c_str(), body.length()); + } + } else { + /* if no file is specified, simply provide a quick + * introduction */ + string intro = "filename.txt\n\n" + "CTRL+SHIFT+BACKSPACE to quit (without saving)\n" + "CTRL+SHIFT+S to save (first line is used as filename)\n"; + + /* Comment the next line if you don 't want the initial text + * shown. */ + gtk_text_buffer_set_text(buffer, intro.c_str(), intro.length()); + } + + GtkAccelGroup *accel = gtk_accel_group_new(); + GClosure *closure; + GdkModifierType CTRL_SHIFT = (GdkModifierType) (GDK_CONTROL_MASK | GDK_SHIFT_MASK); + + /* add the quit shortcut */ + closure = g_cclosure_new(G_CALLBACK(Accel), NULL, NULL); + gtk_accel_group_connect(accel, GDK_BackSpace, CTRL_SHIFT, (GtkAccelFlags) 0, closure); + + /* add the save shortcut */ + closure = g_cclosure_new(G_CALLBACK(Accel), NULL, NULL); + gtk_accel_group_connect(accel, GDK_S, CTRL_SHIFT, (GtkAccelFlags) 0, closure); + + gtk_window_add_accel_group(window, accel); + gtk_widget_show_all(GTK_WIDGET(window)); + + /* enter the main application loop */ + gtk_main(); + + return 0; +} + +void +Destroy() +{ + gtk_main_quit(); +} +gboolean +Accel(GtkAccelGroup * accel_group, GObject * acceleratable, guint keyval, GdkModifierType modifier) +{ + if (keyval == GDK_BackSpace) + Destroy(); + else if (keyval == GDK_S || keyval == GDK_s) { + GtkTextIter start, end; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit)); + + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_iter_at_line(buffer, &end, 1); + gchar *line = gtk_text_buffer_get_slice(buffer, &start, &end, false); + if (!line) + return true; + + if (line[0]) { + for (int i = 0; line[i] != 0; i++) { + if (line[i] == '\b' || line[i] == '\r' || line[i] == '\n') + line[i] = 0; + } + ofstream file(line); + start = end; + gtk_text_buffer_get_end_iter(buffer, &end); + gchar *body = gtk_text_buffer_get_slice(buffer, &start, &end, false); + file << body; + g_free(body); + file.close(); + } + g_free(line); + } + return true; +} +/* + * Thanks to gedit source: + * A hack to change the cursor color (widget must be named!) + */ + +void +modify_cursor_color(GtkWidget * widget, GdkColor * color) +{ + static const char cursor_color_rc[] = + "style \"editor\"\n" + "{\n" + "GtkTextView::cursor-color=\"#%04x%04x%04x\"\n" + "}\n" + "widget \"*.%s\" style : application \"editor\"\n"; + + const gchar *name; + gchar *rc_temp; + + name = gtk_widget_get_name(widget); + if (!name) + return; + + if (color) { + rc_temp = g_strdup_printf(cursor_color_rc, + color->red, + color->green, + color->blue, + name); + } else { + GtkRcStyle *rc_style; + + rc_style = gtk_widget_get_modifier_style(widget); + rc_temp = g_strdup_printf(cursor_color_rc, + rc_style->text[GTK_STATE_NORMAL].red, + rc_style->text[GTK_STATE_NORMAL].green, + rc_style->text[GTK_STATE_NORMAL].blue, + name); + } + + gtk_rc_parse_string(rc_temp); + gtk_widget_reset_rc_styles(widget); + + g_free(rc_temp); +} -- cgit v1.2.3