[Goodies-commits] r7373 - in xfce4-notes-plugin/trunk: . panel-plugin
Mike Massonnet
mmassonnet at xfce.org
Tue May 19 22:27:50 CEST 2009
Author: mmassonnet
Date: 2009-05-19 20:27:50 +0000 (Tue, 19 May 2009)
New Revision: 7373
Added:
xfce4-notes-plugin/trunk/panel-plugin/application.vala
xfce4-notes-plugin/trunk/panel-plugin/note.vala
xfce4-notes-plugin/trunk/panel-plugin/window.vala
Modified:
xfce4-notes-plugin/trunk/ChangeLog
xfce4-notes-plugin/trunk/NEWS
xfce4-notes-plugin/trunk/panel-plugin/hypertextview.vala
Log:
Vala vala vala vala vala
Modified: xfce4-notes-plugin/trunk/ChangeLog
===================================================================
--- xfce4-notes-plugin/trunk/ChangeLog 2009-05-19 14:16:52 UTC (rev 7372)
+++ xfce4-notes-plugin/trunk/ChangeLog 2009-05-19 20:27:50 UTC (rev 7373)
@@ -1,3 +1,15 @@
+2009-05-19 Mike Massonnet <mmassonnet at xfce.org>
+
+Vala vala vala vala vala
+ * panel-plugin/hypertextview.vala:
+ - Changed Timeout.add_seconds_full calls against classical
+ Timeout.add_seconds calls
+ - Update tags quicker on typing space or return carrier
+ - Remove existing GLib.Sources on destruction
+ * panel-plugin/window.vala,
+ panel-plugin/note.vala:
+ Vala vala vala vala vala
+
2009-03-13 Mike Massonnet <mmassonnet at xfce.org>
Minor autofoo changes for Vala sources
Modified: xfce4-notes-plugin/trunk/NEWS
===================================================================
--- xfce4-notes-plugin/trunk/NEWS 2009-05-19 14:16:52 UTC (rev 7372)
+++ xfce4-notes-plugin/trunk/NEWS 2009-05-19 20:27:50 UTC (rev 7373)
@@ -1,3 +1,9 @@
+VERSION 1.6.5
+
+- New window menu layout with navigation for notes
+- Dropped show-tabs option for the window in favor of a navigation bar
+- New vala objects Window and Note, based on the existing code inside notes.c
+
VERSION 1.6.4
- Resize handle all around the window
Added: xfce4-notes-plugin/trunk/panel-plugin/application.vala
===================================================================
--- xfce4-notes-plugin/trunk/panel-plugin/application.vala (rev 0)
+++ xfce4-notes-plugin/trunk/panel-plugin/application.vala 2009-05-19 20:27:50 UTC (rev 7373)
@@ -0,0 +1,62 @@
+/*
+ * Notes - panel plugin for Xfce Desktop Environment
+ * Copyright (c) 2009 Mike Massonnet <mmassonnet at xfce.org>
+ *
+ * TODO:
+ * - Nothing
+ *
+ * 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 Library 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+using Gtk;
+
+namespace Xnp {
+
+ public class Application : GLib.Object {
+
+ public Application () {
+ /* TODO Load existing notes */
+ /* Load an empty note */
+ var window = new Xnp.Window ();
+ var note = window.insert_note ();
+ note.notify += note_property_notify;
+ window.show ();
+ }
+
+ /**
+ * note_property_notify:
+ * @object
+ *
+ * Emitted when a property is changed.
+ */
+ private void note_property_notify (GLib.Object object, GLib.ParamSpec pspec) {
+ var note = (Xnp.Note)object;
+ debug ("notify %s", pspec.name);
+ if (pspec.name == "name") {
+ debug ("name of note changed to `%s'", note.name);
+ }
+ }
+
+/**/
+ static int main (string[] args) {
+ Gtk.init (ref args);
+ new Xnp.Application ();
+ Gtk.main ();
+ return 0;
+ }
+
+ }
+
+}
Modified: xfce4-notes-plugin/trunk/panel-plugin/hypertextview.vala
===================================================================
--- xfce4-notes-plugin/trunk/panel-plugin/hypertextview.vala 2009-05-19 14:16:52 UTC (rev 7372)
+++ xfce4-notes-plugin/trunk/panel-plugin/hypertextview.vala 2009-05-19 20:27:50 UTC (rev 7373)
@@ -2,7 +2,8 @@
* Notes - panel plugin for Xfce Desktop Environment
* Copyright (c) 2009 Mike Massonnet <mmassonnet at xfce.org>
*
- * TODO: on set_buffer initialize the undo/redo texts
+ * TODO:
+ * - On set_buffer initialize the undo/redo texts
*
* 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
@@ -22,12 +23,13 @@
using Gtk;
using Pango;
-namespace Xfce {
+namespace Xnp {
public class HypertextView : Gtk.TextView {
- private Gdk.Cursor hand_cursor;
- private Gdk.Cursor regular_cursor;
+ private Gdk.Cursor hand_cursor = new Gdk.Cursor (Gdk.CursorType.HAND2);
+ private Gdk.Cursor regular_cursor = new Gdk.Cursor (Gdk.CursorType.XTERM);
+
private bool cursor_over_link = false;
private uint undo_timeout = 0;
@@ -38,12 +40,24 @@
private uint tag_timeout = 0;
private Gtk.TextTag tag_link;
- construct {
+ private string _font;
+ public string font {
+ default = "Sans 14";
+ get {
+ return this._font;
+ }
+ construct {
+ if (value == null)
+ value = "Sans 14";
+ this._font = value;
+ Pango.FontDescription font_descr = Pango.FontDescription.from_string (value);
+ modify_font (font_descr);
+ }
+ }
+
+ public HypertextView () {
Gtk.TextIter iter;
- this.hand_cursor = new Gdk.Cursor (Gdk.CursorType.HAND2);
- this.regular_cursor = new Gdk.Cursor (Gdk.CursorType.XTERM);
-
this.button_release_event += button_release_event_cb;
this.motion_notify_event += motion_notify_event_cb;
this.move_cursor += move_cursor_cb;
@@ -60,6 +74,13 @@
null);
}
+ ~HypertextView () {
+ if (this.undo_timeout != 0)
+ Source.remove (this.undo_timeout);
+ if (this.tag_timeout != 0)
+ Source.remove (this.tag_timeout);
+ }
+
/*
* Signal callbacks
*/
@@ -69,7 +90,7 @@
*
* Event to open links.
*/
- private bool button_release_event_cb (Xfce.HypertextView hypertextview, Gdk.EventButton event) {
+ private bool button_release_event_cb (HypertextView hypertextview, Gdk.EventButton event) {
Gtk.TextIter start, end, iter;
string link;
int x, y;
@@ -120,7 +141,7 @@
*
* Event to update the cursor of the pointer.
*/
- private bool motion_notify_event_cb (Xfce.HypertextView hypertextview, Gdk.EventMotion event) {
+ private bool motion_notify_event_cb (HypertextView hypertextview, Gdk.EventMotion event) {
Gtk.TextIter iter;
Gdk.Window win;
bool over_link;
@@ -144,16 +165,18 @@
*
* Destroys existing timeouts and executes the actions immediately.
*/
- private void move_cursor_cb (Xfce.HypertextView hypertextview, Gtk.MovementStep step, int count, bool extend_selection) {
+ private void move_cursor_cb (HypertextView hypertextview, Gtk.MovementStep step, int count, bool extend_selection) {
if (this.undo_timeout > 0) {
/* Make an undo snapshot and save cursor_position before it really moves */
Source.remove (this.undo_timeout);
+ this.undo_timeout = 0;
undo_snapshot ();
this.undo_cursor_pos = this.buffer.cursor_position;
}
if (this.tag_timeout > 0) {
Source.remove (this.tag_timeout);
+ this.tag_timeout = 0;
update_tags ();
}
}
@@ -167,15 +190,15 @@
/* Initialize undo_timeout */
if (this.undo_timeout > 0) {
Source.remove (this.undo_timeout);
+ this.undo_timeout = 0;
}
- this.undo_timeout = Timeout.add_seconds_full (Priority.DEFAULT, 2,
- undo_snapshot, undo_timeout_destroy);
+ this.undo_timeout = Timeout.add_seconds (2, undo_snapshot);
/* Reinit tag_timeout as long as the buffer is under constant changes */
if (this.tag_timeout > 0) {
Source.remove (this.tag_timeout);
- this.tag_timeout = Timeout.add_seconds_full (Priority.DEFAULT, 2,
- tag_timeout_cb, tag_timeout_destroy);
+ this.tag_timeout = 0;
+ this.tag_timeout = Timeout.add_seconds (2, tag_timeout_cb);
}
}
@@ -217,12 +240,14 @@
/* Text is inserted at the end of a tag */
else if (location.ends_tag (this.tag_link)) {
- start = location;
- start.backward_to_tag_toggle (this.tag_link);
+ if (len >= 1 && !(text[0] == ' ' || text[0] == '\n')) {
+ start = location;
+ start.backward_to_tag_toggle (this.tag_link);
- this.buffer.remove_tag (this.tag_link, start, location);
+ this.buffer.remove_tag (this.tag_link, start, location);
- tag_timeout_init ();
+ tag_timeout_init ();
+ }
}
/* Check if the word being typed is "http://" */
@@ -235,6 +260,11 @@
tag_timeout_init ();
}
+ /* Check the character space or return carrier */
+ else if (len == 1 && (text[0] == ' ' || text[0] == '\n')) {
+ update_tags ();
+ }
+
/* Text contains links */
else if (len > 1 && text.contains ("http://")) {
tag_timeout_init ();
@@ -290,10 +320,6 @@
return false;
}
- private void undo_timeout_destroy () {
- this.undo_timeout = 0;
- }
-
/**
* undo:
*
@@ -307,6 +333,7 @@
if (this.undo_timeout > 0) {
/* Make an undo snaphot */
Source.remove (this.undo_timeout);
+ this.undo_timeout = 0;
undo_snapshot ();
}
@@ -323,7 +350,10 @@
this.undo_text = this.redo_text;
this.redo_text = tmp;
- Source.remove (this.undo_timeout);
+ if (this.undo_timeout > 0) {
+ Source.remove (this.undo_timeout);
+ this.undo_timeout = 0;
+ }
}
/*
@@ -338,16 +368,12 @@
private void tag_timeout_init () {
if (this.tag_timeout > 0) {
Source.remove (this.tag_timeout);
+ this.tag_timeout = 0;
}
- this.tag_timeout = Timeout.add_seconds_full (Priority.DEFAULT, 2,
- tag_timeout_cb, tag_timeout_destroy);
+ this.tag_timeout = Timeout.add_seconds (2, tag_timeout_cb);
}
- private void tag_timeout_destroy () {
- this.tag_timeout = 0;
- }
-
/**
* update_tags:
*
@@ -356,8 +382,10 @@
public void update_tags () {
Gtk.TextIter iter, start, end, tmp;
- if (this.tag_timeout > 0)
+ if (this.tag_timeout > 0) {
Source.remove (this.tag_timeout);
+ this.tag_timeout = 0;
+ }
this.buffer.get_iter_at_offset (out iter, 0);
Added: xfce4-notes-plugin/trunk/panel-plugin/note.vala
===================================================================
--- xfce4-notes-plugin/trunk/panel-plugin/note.vala (rev 0)
+++ xfce4-notes-plugin/trunk/panel-plugin/note.vala 2009-05-19 20:27:50 UTC (rev 7373)
@@ -0,0 +1,123 @@
+/*
+ * Notes - panel plugin for Xfce Desktop Environment
+ * Copyright (c) 2009 Mike Massonnet <mmassonnet at xfce.org>
+ *
+ * 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 Library 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+using Gtk;
+using Pango;
+
+namespace Xnp {
+
+ public class Note : Gtk.Bin {
+
+ public new string name { get; set; }
+ private uint timeout;
+ public Gtk.ScrolledWindow scrolled_window;
+ public Xnp.HypertextView text_view;
+
+ public signal void save_data (string name);
+
+ public Note (string name) {
+ this.name = name;
+
+ this.scrolled_window = new Gtk.ScrolledWindow (null, null);
+ this.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
+
+ this.text_view = new Xnp.HypertextView ();
+ this.text_view.wrap_mode = Gtk.WrapMode.WORD;
+ this.text_view.left_margin = 2;
+ this.text_view.right_margin = 2;
+ this.text_view.pixels_above_lines = 1;
+ this.text_view.pixels_below_lines = 1;
+
+ this.scrolled_window.add (this.text_view);
+ this.scrolled_window.show_all ();
+ add (this.scrolled_window);
+
+ var buffer = this.text_view.get_buffer ();
+ buffer.changed += buffer_changed_cb;
+ }
+
+ ~Note () {
+ if (this.timeout != 0)
+ Source.remove (this.timeout);
+ }
+
+ public override void size_request (ref Gtk.Requisition requisition) {
+ Gtk.Requisition child_requisition;
+ if (this.child != null && (bool)(this.child.get_flags () & Gtk.WidgetFlags.VISIBLE)) {
+ this.child.size_request (out child_requisition);
+ requisition = child_requisition;
+ }
+ else {
+ requisition.width = 0;
+ requisition.height = 0;
+ }
+ }
+
+ public override void size_allocate (Gtk.Allocation allocation) {
+ this.allocation = allocation;
+ if (this.child != null && (bool)(this.child.get_flags () & Gtk.WidgetFlags.VISIBLE)) {
+ this.child.size_allocate ((Gtk.Allocation)allocation);
+ }
+ }
+
+ /*
+ * Signal callbacks
+ */
+
+ /**
+ * buffer_changed_cb:
+ *
+ * Reset the timeout as long as the buffer is under constant
+ * changes and send the save-data signal.
+ */
+ private void buffer_changed_cb () {
+ if (this.timeout > 0) {
+ Source.remove (this.timeout);
+ }
+ this.timeout = Timeout.add_seconds (60, () => {
+ save_data (name);
+ timeout = 0;
+ return false;
+ });
+ }
+
+ }
+
+}
+
+/*public class GtkSample : Window {
+
+ public GtkSample () {
+ this.title = "Sample Window";
+ this.destroy += Gtk.main_quit;
+ set_default_size (300, 300);
+ var note = new Xnp.Note ("my-note");
+ add (note);
+ }
+
+ static int main (string[] args) {
+ Gtk.init (ref args);
+ var sample = new GtkSample ();
+ sample.show_all ();
+ Gtk.main ();
+ return 0;
+ }
+
+}*/
+
Added: xfce4-notes-plugin/trunk/panel-plugin/window.vala
===================================================================
--- xfce4-notes-plugin/trunk/panel-plugin/window.vala (rev 0)
+++ xfce4-notes-plugin/trunk/panel-plugin/window.vala 2009-05-19 20:27:50 UTC (rev 7373)
@@ -0,0 +1,664 @@
+/*
+ * Notes - panel plugin for Xfce Desktop Environment
+ * Copyright (c) 2009 Mike Massonnet <mmassonnet at xfce.org>
+ *
+ * TODO:
+ * - F2/Esc/etc accelerators
+ * - Set widget name for Window
+ * - Extra window properties
+ * - Verify: unshade before hide
+ * - On del_box_clicked_cb verify if the content is empty
+ * - Display note name in title
+ * - Hide navigation bar on leave / show on motion
+ *
+ * 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 Library 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+using Gtk;
+using Pango;
+
+namespace Xnp {
+
+ public class Window : Gtk.Window {
+
+ private int width;
+ private int height;
+ private bool above;
+ private bool sticky;
+ private Gtk.AccelGroup accel_group;
+ private Gtk.Menu menu;
+ private Gtk.VBox content_box;
+ private Gtk.Notebook notebook;
+ private Gtk.HBox navigation_box;
+ private uint navigation_timeout = 0;
+ private Gtk.Button goleft_box;
+ private Gtk.Button goright_box;
+
+ private int CORNER_MARGIN = 20;
+ private Gdk.Cursor CURSOR_TOP_LC = new Gdk.Cursor (Gdk.CursorType.TOP_LEFT_CORNER);
+ private Gdk.Cursor CURSOR_TOP_RC = new Gdk.Cursor (Gdk.CursorType.TOP_RIGHT_CORNER);
+ private Gdk.Cursor CURSOR_BOTTOM_RC = new Gdk.Cursor (Gdk.CursorType.BOTTOM_RIGHT_CORNER);
+ private Gdk.Cursor CURSOR_BOTTOM = new Gdk.Cursor (Gdk.CursorType.BOTTOM_SIDE);
+ private Gdk.Cursor CURSOR_BOTTOM_LC = new Gdk.Cursor (Gdk.CursorType.BOTTOM_LEFT_CORNER);
+
+ public Window () {
+ /* Build Window properties */
+ this.title = "Notes";
+ this.deletable = false;
+ this.skip_taskbar_hint = true;
+ this.default_height = 380;
+ this.default_width = 300;
+ this.decorated = false;
+ this.icon_name = "xfce4-notes-plugin";
+ add_events (Gdk.EventMask.POINTER_MOTION_MASK|Gdk.EventMask.POINTER_MOTION_HINT_MASK|Gdk.EventMask.BUTTON_PRESS_MASK);
+
+ /* Build AccelGroup */
+ this.accel_group = new Gtk.AccelGroup ();
+ add_accel_group (this.accel_group);
+
+ /* Build Menu */
+ this.menu = build_menu ();
+ this.menu.show_all ();
+
+ /* Build Frame */
+ var frame = new Gtk.Frame (null);
+ frame.shadow_type = Gtk.ShadowType.NONE;
+ var style = frame.get_modifier_style ();
+ style.xthickness = 1;
+ style.ythickness = 3;
+ frame.modify_style (style);
+ frame.show ();
+ add (frame);
+ var vbox_frame = new Gtk.VBox (false, 0);
+ vbox_frame.spacing = 1;
+ vbox_frame.show ();
+ frame.add (vbox_frame);
+
+ /* Build title */
+ var title_box = new Gtk.HBox (false, 0);
+ var menu_box = new Gtk.EventBox ();
+ var menu_image = new Gtk.Image.from_icon_name ("xfce4-notes-plugin", Gtk.IconSize.MENU);
+ menu_box.add (menu_image);
+ menu_box.set_size_request (22, 22);
+ title_box.pack_start (menu_box, false, false, 4);
+ var title_evbox = new Gtk.EventBox ();
+ var title = new Gtk.Label ("<b>"+this.title+"</b>");
+ title.use_markup = true;
+ title.ellipsize = Pango.EllipsizeMode.END;
+ title_evbox.add (title);
+ title_box.pack_start (title_evbox, true, true, 0);
+ var close_box = new Gtk.Button ();
+ close_box.set_relief (Gtk.ReliefStyle.NONE);
+ close_box.can_focus = false;
+ var close_label = new Gtk.Label ("<b>x</b>");
+ close_label.use_markup = true;
+ close_box.add (close_label);
+ close_box.set_size_request (22, 22);
+ title_box.pack_start (close_box, false, false, 4);
+ title_box.show_all ();
+ vbox_frame.pack_start (title_box, false, false, 0);
+
+ /* Build content box */
+ this.content_box = new Gtk.VBox (false, 0);
+ this.content_box.show ();
+ vbox_frame.pack_start (this.content_box, true, true, 0);
+
+ /* Build Notebook */
+ this.notebook = new Gtk.Notebook ();
+ this.notebook.show_border = false;
+ this.notebook.show_tabs = false;
+ this.notebook.show ();
+ this.content_box.pack_start (this.notebook, true, true, 0);
+
+ /* Build navigation toolbar */
+ this.navigation_box = new Gtk.HBox (false, 2);
+ this.goleft_box = new Gtk.Button ();
+ this.goleft_box.set_relief (Gtk.ReliefStyle.NONE);
+ this.goleft_box.can_focus = false;
+ this.goleft_box.sensitive = false;
+ var goleft_label = new Gtk.Label ("<b><</b>");
+ goleft_label.use_markup = true;
+ this.goleft_box.add (goleft_label);
+ this.goleft_box.set_size_request (22, 22);
+ this.navigation_box.pack_start (this.goleft_box, true, false, 0);
+ var add_box = new Gtk.Button ();
+ add_box.set_tooltip_text (Gtk.accelerator_get_label ('N', Gdk.ModifierType.CONTROL_MASK));
+ add_box.set_relief (Gtk.ReliefStyle.NONE);
+ add_box.can_focus = false;
+ var add_label = new Gtk.Label ("<b>+</b>");
+ add_label.use_markup = true;
+ add_box.add (add_label);
+ add_box.set_size_request (22, 22);
+ this.navigation_box.pack_start (add_box, true, false, 0);
+ var del_box = new Gtk.Button ();
+ del_box.set_tooltip_text (Gtk.accelerator_get_label ('W', Gdk.ModifierType.CONTROL_MASK));
+ del_box.set_relief (Gtk.ReliefStyle.NONE);
+ del_box.can_focus = false;
+ var del_label = new Gtk.Label ("<b>−</b>");
+ del_label.use_markup = true;
+ del_box.add (del_label);
+ del_box.set_size_request (22, 22);
+ this.navigation_box.pack_start (del_box, true, false, 0);
+ this.goright_box = new Gtk.Button ();
+ this.goright_box.set_relief (Gtk.ReliefStyle.NONE);
+ this.goright_box.can_focus = false;
+ this.goright_box.sensitive = false;
+ var goright_label = new Gtk.Label ("<b>></b>");
+ goright_label.use_markup = true;
+ this.goright_box.add (goright_label);
+ this.goright_box.set_size_request (22, 22);
+ this.navigation_box.pack_start (this.goright_box, true, false, 0);
+ this.navigation_box.show_all ();
+ this.navigation_box.hide ();
+ this.content_box.pack_start (this.navigation_box, false, false, 0);
+
+ /* Connect mouse click signals */
+ menu_box.button_press_event += menu_box_pressed_cb;
+ close_box.clicked += hide_cb;
+ add_box.clicked += () => { insert_note (); };
+ del_box.clicked += () => { delete_current_note (); };
+ this.goleft_box.clicked += () => { notebook.prev_page (); };
+ this.goright_box.clicked += () => { notebook.next_page (); };
+
+ /* Connect extra signals */
+ delete_event += () => {
+ /* Replace ALT+F4 action */
+ hide_cb ();
+ return true;
+ };
+ leave_notify_event += () => {
+ /* Hide the navigation when the mouse pointer is leaving the window */
+ navigation_timeout = Timeout.add_seconds (1, () => {
+ navigation_box.hide ();
+ navigation_timeout = 0;
+ return false;
+ });
+ return false;
+ };
+ motion_notify_event += () => {
+ /* Show the navigation when the mouse pointer is hovering the window */
+ if (navigation_timeout != 0) {
+ Source.remove (navigation_timeout);
+ navigation_timeout = 0;
+ }
+ navigation_box.show ();
+ return false;
+ };
+ leave_notify_event += window_leaved_cb;
+ motion_notify_event += window_motion_cb;
+ button_press_event += window_pressed_cb;
+ window_state_event += window_state_cb;
+ title_evbox.button_press_event += title_evbox_pressed_cb;
+ title_evbox.scroll_event += title_evbox_scrolled_cb;
+ this.notebook.page_added += (n, c, p) => {
+ notebook.set_current_page ((int)p);
+ update_navigation_sensitivity ((int)p);
+ };
+ this.notebook.page_removed += (n, c, p) => {
+ update_navigation_sensitivity ((int)p);
+ };
+ this.notebook.switch_page += (n, c, p) => {
+ update_navigation_sensitivity ((int)p);
+ };
+ }
+
+ /*
+ * Signal callbacks
+ */
+
+ /**
+ * menu_box_pressed_cb:
+ *
+ * Popup the window menu.
+ */
+ private bool menu_box_pressed_cb (Gtk.EventBox box, Gdk.EventButton event) {
+ this.menu.popup (null, null, menu_position, 0, Gtk.get_current_event_time ());
+ return false;
+ }
+
+ /**
+ * menu_position:
+ *
+ * Menu position function for the window menu.
+ */
+ private void menu_position (Gtk.Menu menu, out int x, out int y, out bool push_in) {
+ int winx, winy, width, height, depth;
+ Gtk.Requisition requisition;
+ window.get_geometry (out winx, out winy, out width, out height, out depth);
+ window.get_origin (out x, out y);
+ menu.size_request (out requisition);
+
+ if (y + content_box.allocation.y + requisition.height > Gdk.Screen.height ()) {
+ /* Show menu above */
+ y -= requisition.height;
+ }
+ else {
+ /* Show menu below */
+ y += content_box.allocation.y;
+ }
+ if (x + requisition.width > Gdk.Screen.width ()) {
+ /* Adjust menu left */
+ debug ("%d %d", Gdk.Screen.width (), x);
+ x = x - menu.requisition.width + content_box.allocation.y;
+ }
+ }
+
+ /**
+ * hide_cb:
+ *
+ * Save position before hidding.
+ */
+ private void hide_cb () {
+ int winx, winy;
+ get_position (out winx, out winy);
+ hide ();
+ move (winx, winy);
+ }
+
+ /**
+ * window_leaved_cb:
+ *
+ * Reset the mouse cursor.
+ */
+ private bool window_leaved_cb () {
+ window.set_cursor (null);
+ return true;
+ }
+
+ /**
+ * window_motion_cb:
+ *
+ * Update mouse cursor.
+ */
+ private bool window_motion_cb (Gtk.Widget widget, Gdk.EventMotion event) {
+ if (event.x > 4 && event.y > 4
+ && event.x < allocation.width - 4
+ && event.y < allocation.height - 4) {
+ window.set_cursor (null);
+ return false;
+ }
+
+ // Top left corner
+ if (event.x <= 4
+ && event.y <= this.CORNER_MARGIN)
+ window.set_cursor (this.CURSOR_TOP_LC);
+ // Top right corner
+ else if (event.x >= allocation.width - 4
+ && event.y <= this.CORNER_MARGIN)
+ window.set_cursor (this.CURSOR_TOP_RC);
+ // Bottom right corner
+ else if (event.x >= allocation.width - this.CORNER_MARGIN
+ && event.y >= allocation.height - this.CORNER_MARGIN)
+ window.set_cursor (this.CURSOR_BOTTOM_RC);
+ // Bottom
+ else if (event.x > this.CORNER_MARGIN
+ && event.y > allocation.height - this.CORNER_MARGIN
+ && event.x < allocation.width - this.CORNER_MARGIN)
+ window.set_cursor (this.CURSOR_BOTTOM);
+ // Bottom left corner
+ else if (event.x <= this.CORNER_MARGIN
+ && event.y >= allocation.height - this.CORNER_MARGIN)
+ window.set_cursor (this.CURSOR_BOTTOM_LC);
+ // Default
+ else
+ window.set_cursor (null);
+
+ return true;
+ }
+
+ /**
+ * window_pressed_cb:
+ *
+ * Start a window resize depending on mouse pointer location.
+ */
+ private bool window_pressed_cb (Gtk.Widget widget, Gdk.EventButton event) {
+ Gdk.WindowEdge edge;
+ if (event.x > 4 && event.y > 4
+ && event.x < allocation.width - 4
+ && event.y < allocation.height - 4)
+ return false;
+
+ // Top left corner
+ if (event.x <= 4
+ && event.y <= this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.NORTH_WEST;
+ // Top right corner
+ else if (event.x >= allocation.width - 4
+ && event.y <= this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.NORTH_EAST;
+ // Right
+ else if (event.y > this.CORNER_MARGIN
+ && event.x > allocation.width - this.CORNER_MARGIN
+ && event.y < allocation.height - this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.EAST;
+ // Bottom right corner
+ else if (event.x >= allocation.width - this.CORNER_MARGIN
+ && event.y >= allocation.height - this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.SOUTH_EAST;
+ // Bottom
+ else if (event.x > this.CORNER_MARGIN
+ && event.y > allocation.height - this.CORNER_MARGIN
+ && event.x < allocation.width - this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.SOUTH;
+ // Bottom left corner
+ else if (event.x <= this.CORNER_MARGIN
+ && event.y >= allocation.height - this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.SOUTH_WEST;
+ // Left
+ else if (event.y > this.CORNER_MARGIN && event.x < this.CORNER_MARGIN
+ && event.y < allocation.height - this.CORNER_MARGIN)
+ edge = Gdk.WindowEdge.WEST;
+ else
+ return false;
+
+ begin_resize_drag (edge, (int)event.button,
+ (int)event.x_root, (int)event.y_root, event.time);
+
+ return true;
+ }
+
+ /**
+ * window_state_cb:
+ *
+ * Watch window manager actions always on top and sticky
+ * window.
+ */
+ private bool window_state_cb (Gtk.Widget widget, Gdk.EventWindowState event) {
+ if ((bool)(event.changed_mask & Gdk.WindowState.ABOVE)) {
+ /* FIXME above state is never notified despit
+ * of xfwm4 switching the state */
+ this.above = (bool)(event.new_window_state & Gdk.WindowState.ABOVE);
+ }
+ if ((bool)(event.changed_mask & Gdk.WindowState.STICKY)) {
+ this.sticky = (bool)(event.new_window_state & Gdk.WindowState.STICKY);
+ }
+ return false;
+ }
+
+ /**
+ * title_evbox_pressed_cb:
+ *
+ * Raise/lower the window and popup window menu.
+ */
+ private bool title_evbox_pressed_cb (Gtk.EventBox box, Gdk.EventButton event) {
+ if (event.type != Gdk.EventType.BUTTON_PRESS)
+ return false;
+ if (event.button == 1) {
+ this.window.show ();
+ int winx, winy, curx, cury;
+ get_position (out winx, out winy);
+ get_pointer (out curx, out cury);
+ winx += curx;
+ winy += cury;
+ begin_move_drag (1, winx, winy, Gtk.get_current_event_time ());
+ }
+ else if (event.button == 2) {
+ this.window.lower ();
+ }
+ else if (event.button == 3) {
+ this.menu.popup (null, null, null, 0, Gtk.get_current_event_time ());
+ }
+ return false;
+ }
+
+ /**
+ * title_evbox_scrolled_cb:
+ *
+ * Shade/unshade the window and set transparency by holding ALT.
+ */
+ private bool title_evbox_scrolled_cb (Gtk.EventBox box, Gdk.EventScroll event) {
+ if ((bool)(event.state & Gdk.ModifierType.MOD1_MASK)) {
+ if (event.direction == Gdk.ScrollDirection.UP) {
+ opacity += 0.1;
+ } else if (event.direction == Gdk.ScrollDirection.DOWN) {
+ if (opacity - 0.1 >= 0.1)
+ opacity -= 0.1;
+ }
+ }
+ else {
+ if (event.direction == Gdk.ScrollDirection.UP) {
+ shade ();
+ }
+ else if (event.direction == Gdk.ScrollDirection.DOWN) {
+ unshade ();
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Window menu
+ */
+
+ /**
+ * build_menu:
+ *
+ * Build the window menu.
+ */
+ private Gtk.Menu build_menu () {
+ var menu = new Gtk.Menu ();
+ menu.set_accel_group (this.accel_group);
+
+ var mi = new Gtk.MenuItem.with_mnemonic ("_Go");
+ menu.append (mi);
+
+ var menu_go = new Gtk.Menu ();
+ mi.set_submenu (menu_go);
+
+ mi = new Gtk.SeparatorMenuItem ();
+ menu_go.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_ADD, null);
+ mi.add_accelerator ("activate", this.accel_group, 'N',
+ Gdk.ModifierType.SHIFT_MASK | Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.MASK);
+ menu_go.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_REMOVE, null);
+ mi.add_accelerator ("activate", this.accel_group, 'W',
+ Gdk.ModifierType.SHIFT_MASK | Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.MASK);
+ menu_go.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_PROPERTIES, null);
+ menu.append (mi);
+
+ /* Note items */
+ mi = new Gtk.SeparatorMenuItem ();
+ menu.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_NEW, null);
+ mi.add_accelerator ("activate", this.accel_group, 'N',
+ Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.MASK);
+ mi.activate += () => { insert_note (); };
+ menu.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_DELETE, null);
+ mi.add_accelerator ("activate", this.accel_group, 'W',
+ Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.MASK);
+ mi.activate += () => { delete_current_note (); };
+ menu.append (mi);
+
+ mi = new Gtk.MenuItem.with_mnemonic ("_Rename");
+ mi.activate += () => { rename_current_note (); };
+ menu.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_UNDO, null);
+ mi.add_accelerator ("activate", this.accel_group, 'Z',
+ Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.MASK);
+ mi.activate += () => {
+ int page = notebook.get_current_page ();
+ Gtk.Widget child = notebook.get_nth_page (page);
+ ((Xnp.Note)child).text_view.undo ();
+ };
+ menu.append (mi);
+
+ /* Window options */
+ mi = new Gtk.SeparatorMenuItem ();
+ menu.append (mi);
+
+ mi = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_SELECT_FONT, null);
+ menu.append (mi);
+
+ mi = new Gtk.CheckMenuItem.with_label ("Always on top");
+ menu.append (mi);
+
+ mi = new Gtk.CheckMenuItem.with_label ("Sticky window");
+ menu.append (mi);
+
+ return menu;
+ }
+
+ /*
+ * Shade/unshade
+ */
+
+ /**
+ * shade:
+ *
+ * Shade the window (roll up) to show only the title bar.
+ */
+ private void shade () {
+ if ((bool)(this.content_box.get_flags () & Gtk.WidgetFlags.VISIBLE)) {
+ this.content_box.hide ();
+ get_size (out this.width, out this.height);
+ resize (this.width, 1);
+ }
+ }
+
+ /**
+ * unshade:
+ *
+ * Unshade the window (roll down).
+ */
+ private void unshade () {
+ if (!(bool)(this.content_box.get_flags () & Gtk.WidgetFlags.VISIBLE)) {
+ this.content_box.show ();
+ get_size (out this.width, null);
+ resize (this.width, this.height);
+ }
+ }
+
+ /*
+ * Tabs, navigation
+ */
+
+ /**
+ * insert_note:
+ *
+ * Create a new note and insert it inside the notebook after
+ * the current position.
+ */
+ public Xnp.Note insert_note () {
+ int position = this.notebook.get_current_page () + 1;
+ var note = new Xnp.Note ("my-note");
+ note.save_data += (o, n) => { print ("note `%s' save-data\n", n); };
+ note.show ();
+ this.notebook.insert_page (note, null, position);
+ return note;
+ }
+
+ /**
+ * delete_current_note:
+ *
+ * Delete the current note.
+ */
+ public void delete_current_note () {
+ this.delete_note (this.notebook.get_current_page ());
+ }
+
+ /**
+ * delete_note:
+ *
+ * Delete note at position @position.
+ */
+ public void delete_note (int position) {
+ var child = this.notebook.get_nth_page (position);
+
+ if (((Xnp.Note)child).text_view.buffer.get_char_count () > 0) {
+ var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
+ Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Are you sure you want to delete this note?");
+ int res = dialog.run ();
+ dialog.destroy ();
+ if (res != Gtk.ResponseType.YES)
+ return;
+ }
+
+ this.notebook.remove_page (position);
+ child.destroy ();
+ if (this.notebook.get_n_pages () == 0)
+ this.insert_note ();
+ }
+
+ /**
+ * rename_current_note:
+ *
+ * Rename the current note.
+ */
+ public void rename_current_note () {
+ int position = this.notebook.get_current_page ();
+ if (position == -1)
+ return;
+ var note = (Xnp.Note)(this.notebook.get_nth_page (position));
+
+ var dialog = new Gtk.Dialog.with_buttons ("Rename note", (Gtk.Window)get_toplevel (),
+ Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT,
+ Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK);
+ dialog.set_default_response (Gtk.ResponseType.OK);
+ dialog.resizable = false;
+ dialog.icon_name = Gtk.STOCK_EDIT;
+ dialog.border_width = 4;
+ dialog.vbox.border_width = 6;
+
+ var entry = new Gtk.Entry ();
+ entry.text = note.name;
+ entry.activates_default = true;
+ dialog.vbox.add (entry);
+ dialog.vbox.show_all ();
+
+ int res = dialog.run ();
+ if (res == Gtk.ResponseType.OK)
+ note.name = entry.text;
+ dialog.destroy ();
+ }
+
+ /**
+ * update_navigation_sensitivity:
+ *
+ * Update the goleft/right sensitivities.
+ */
+ private void update_navigation_sensitivity (int page_num) {
+ int n_pages = notebook.get_n_pages ();
+ if (n_pages <= 1) {
+ this.goleft_box.sensitive = false;
+ this.goright_box.sensitive = false;
+ }
+ else {
+ this.goleft_box.sensitive = page_num == 0 ? false : true;
+ this.goright_box.sensitive = page_num + 1 == n_pages ? false : true;
+ }
+ }
+/*
+ static int main (string[] args) {
+ Gtk.init (ref args);
+ var sample = new Xnp.Window ("Note");
+ sample.show ();
+ Gtk.main ();
+ return 0;
+ }
+*/
+
+ }
+
+}
+
More information about the Goodies-commits
mailing list