Branch: refs/heads/master Author: Frank Lanitz frank@frank.uvena.de Committer: Frank Lanitz frank@frank.uvena.de Date: Thu, 23 Apr 2015 09:10:14 UTC Commit: 8f7031940c5650fe0d4b0f2867a4f4dca93e941e https://github.com/geany/geany-plugins/commit/8f7031940c5650fe0d4b0f2867a4f4...
Log Message: ----------- Merge pull request #211 from codebrainz/overview-plugin
Add new "Overview" plugin
Modified Paths: -------------- MAINTAINERS Makefile.am build/overview.m4 configure.ac overview/AUTHORS overview/COPYING overview/ChangeLog overview/Makefile.am overview/NEWS overview/README overview/data/Makefile.am overview/data/prefs.ui overview/overview/Makefile.am overview/overview/overviewcolor.c overview/overview/overviewcolor.h overview/overview/overviewplugin.c overview/overview/overviewplugin.h overview/overview/overviewprefs.c overview/overview/overviewprefs.h overview/overview/overviewprefspanel.c overview/overview/overviewprefspanel.h overview/overview/overviewscintilla.c overview/overview/overviewscintilla.h overview/overview/overviewui.c overview/overview/overviewui.h overview/wscript_build po/POTFILES.in
Modified: MAINTAINERS 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -180,6 +180,12 @@ M: Matthew Brush matt@geany.org W: http://plugins.geany.org/multiterm.html S: Maintained
+overview +P: Matthew Brush matt@geany.org +M: Matthew Brush matt@geany.org +W: https://github.com/codebrainz/overview-plugin +S: Maintained + pairtaghighlighter P: Volodymyr Kononenko vm@kononenko.ws M: Volodymyr Kononenko vm@kononenko.ws
Modified: Makefile.am 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -115,6 +115,10 @@ if ENABLE_MULTITERM SUBDIRS += multiterm endif
+if ENABLE_OVERVIEW +SUBDIRS += overview +endif + if ENABLE_PAIRTAGHIGHLIGHTER SUBDIRS += pairtaghighlighter endif
Modified: build/overview.m4 12 lines changed, 12 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,12 @@ +AC_DEFUN([GP_CHECK_OVERVIEW], +[ + GP_ARG_DISABLE([overview], [auto]) + + GP_COMMIT_PLUGIN_STATUS([Overview]) + + AC_CONFIG_FILES([ + overview/Makefile + overview/data/Makefile + overview/overview/Makefile + ]) +])
Modified: configure.ac 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -56,6 +56,7 @@ GP_CHECK_GENIUSPASTE GP_CHECK_GITCHANGEBAR GP_CHECK_MARKDOWN GP_CHECK_MULTITERM +GP_CHECK_OVERVIEW GP_CHECK_PAIRTAGHIGHLIGHTER GP_CHECK_POHELPER GP_CHECK_PRETTYPRINTER
Modified: overview/AUTHORS 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online
Modified: overview/COPYING 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online
Modified: overview/ChangeLog 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online
Modified: overview/Makefile.am 3 lines changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,3 @@ +include $(top_srcdir)/build/vars.auxfiles.mk +SUBDIRS = overview data +plugin = overview
Modified: overview/NEWS 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online
Modified: overview/README 0 lines changed, 0 insertions(+), 0 deletions(-) =================================================================== No diff available, check online
Modified: overview/data/Makefile.am 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,2 @@ +overviewdatadir = $(pkgdatadir)/overview +overviewdata_DATA = prefs.ui
Modified: overview/data/prefs.ui 356 lines changed, 356 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,356 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="2.24"/> + <!-- interface-naming-policy project-wide --> + <object class="GtkAdjustment" id="overview-scroll-lines-adjustment"> + <property name="upper">100</property> + <property name="value">1</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="overview-width-adjustment"> + <property name="lower">16</property> + <property name="upper">512</property> + <property name="value">120</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="overview-zoom-adjustment"> + <property name="lower">-10</property> + <property name="upper">20</property> + <property name="value">-10</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkTable" id="overview-prefs-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="n_rows">5</property> + <property name="n_columns">2</property> + <property name="column_spacing">4</property> + <property name="row_spacing">2</property> + <child> + <object class="GtkLabel" id="overview-zoom-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">The amount to zoom the overview sidebar. This should probably negative if you want the sidebar zoomed out.</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Zoom Level:</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="overview-zoom-spin"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">The amount to zoom the overview sidebar. This should probably negative if you want the sidebar zoomed out.</property> + <property name="invisible_char">•</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <property name="adjustment">overview-zoom-adjustment</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="overview-width-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">The width of the overview sidebar.</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Width:</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="overview-width-spin"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">The width of the overview sidebar.</property> + <property name="invisible_char">•</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <property name="adjustment">overview-width-adjustment</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="overview-scroll-lines-spin"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">The number of lines to scroll at a time when scrolling the overview sidebar.</property> + <property name="invisible_char">•</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="primary_icon_sensitive">True</property> + <property name="secondary_icon_sensitive">True</property> + <property name="adjustment">overview-scroll-lines-adjustment</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="overview-scroll-lines-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">The number of lines to scroll at a time when scrolling the overview sidebar.</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Scroll Lines:</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="overview-options-frame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkAlignment" id="overview-options-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="bottom_padding">6</property> + <property name="left_padding">6</property> + <property name="right_padding">6</property> + <child> + <object class="GtkVBox" id="overview-options-vbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child> + <object class="GtkCheckButton" id="overview-position-left-check"> + <property name="label" translatable="yes">Position on left</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Position the overview bar on the left rather than the right (requires Geany 1.25 or greater).</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="overview-hide-tooltip-check"> + <property name="label" translatable="yes">Hide tooltip</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Hide the tooltip that is displayed when mousing over the overview that shows line, column and position information.</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="overview-hide-scrollbar-check"> + <property name="label" translatable="yes">Hide editor scrollbar</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Whether to hide Geany's regular editor scrollbar while the overview bar is visible.</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="overview-overlay-disable-check"> + <property name="label" translatable="yes">Disable overlay</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Turn off drawing overlay, which shows the region of the main editor view that is currently in view, ontop of the overview bar.</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="overview-options-frame-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Options</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="overview-overlay-frame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkAlignment" id="overview-overlay-frame-align"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="bottom_padding">6</property> + <property name="left_padding">6</property> + <property name="right_padding">6</property> + <child> + <object class="GtkTable" id="overview-overlay-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="column_spacing">4</property> + <property name="row_spacing">2</property> + <child> + <object class="GtkLabel" id="overview-overlay-color-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">The color and opacity of the overlay drawn ontop of the overlay sidebar.</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Color:</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="overview-overlay-outline-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">The color and opacity of the border drawn around the revealed area in the overview sidebar. Set to the same as Overlay Color to disable.</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Outline Color:</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="overview-overlay-outline-color"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="tooltip_text" translatable="yes">The color and opacity of the border drawn around the revealed area in the overview sidebar. Set to the same as Overlay Color to disable.</property> + <property name="use_alpha">True</property> + <property name="color">#000000000000</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="overview-overlay-color"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="tooltip_text" translatable="yes">The color and opacity of the overlay drawn ontop of the overlay sidebar.</property> + <property name="use_alpha">True</property> + <property name="color">#000000000000</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="overview-overlay-inverted-check"> + <property name="label" translatable="yes">Draw over visible area</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">When checked it will draw the overlay ontop of the area that is visible in the main editor view, when unckecked, it will do the opposite and draw the overlay everywhere but the visible area, "revealing" the visible part.</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="oveview-overlay-frame-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Overlay</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> +</interface>
Modified: overview/overview/Makefile.am 29 lines changed, 29 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,29 @@ +include $(top_srcdir)/build/vars.build.mk + +plugin = overview + +geanyplugins_LTLIBRARIES = overview.la + +overview_la_SOURCES = \ + overviewcolor.c \ + overviewcolor.h \ + overviewplugin.c \ + overviewplugin.h \ + overviewprefs.c \ + overviewprefs.h \ + overviewprefspanel.c \ + overviewprefspanel.h \ + overviewscintilla.c \ + overviewscintilla.h \ + overviewui.c \ + overviewui.h + +overview_la_CFLAGS = \ + $(AM_CFLAGS) \ + -I$(srcdir)/.. \ + -DOVERVIEW_PREFS_UI_FILE=""$(pkgdatadir)/overview/prefs.ui"" + +overview_la_LIBADD = \ + $(COMMONLIBS) + +include $(top_srcdir)/build/cppcheck.mk
Modified: overview/overview/overviewcolor.c 305 lines changed, 305 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,305 @@ +/* + * overviewcolor.c - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "overviewcolor.h" +#include <string.h> + +OverviewColor * +overview_color_copy (OverviewColor *color) +{ + OverviewColor *new_color = g_slice_new0 (OverviewColor); + memcpy (new_color, color, sizeof (OverviewColor)); + return new_color; +} + +void +overview_color_free (OverviewColor *color) +{ + if (color != NULL) + g_slice_free (OverviewColor, color); +} + +gboolean +overview_color_equal (const OverviewColor *color1, + const OverviewColor *color2) +{ + return (color1->red == color2->red && + color1->green == color2->green && + color1->blue == color2->blue && + color1->alpha == color2->alpha); +} + +gboolean +overview_color_parse (OverviewColor *color, + const gchar *color_str) +{ + g_return_val_if_fail (color != NULL, FALSE); + g_return_val_if_fail (color_str != NULL, FALSE); + +#if GTK_CHECK_VERSION (3, 0, 0) + GdkRGBA gcolor; + if (gdk_rgba_parse (&gcolor, color_str)) + { + overview_color_from_rgba (color, &gcolor); + return TRUE; + } +#else + GdkColor gcolor; + if (gdk_color_parse (color_str, &gcolor)) + { + overview_color_from_gdk_color (color, &gcolor, 1.0); + return TRUE; + } +#endif + + return FALSE; +} + +gchar * +overview_color_to_string (const OverviewColor *color) +{ + g_return_val_if_fail (color != NULL, NULL); + +#if GTK_CHECK_VERSION (3, 0, 0) + GdkRGBA gcolor; + overview_color_to_rgba (color, &gcolor); + return gdk_rgba_to_string (&gcolor); +#else + GdkColor gcolor; + overview_color_to_gdk_color (color, &gcolor); + return gdk_color_to_string (&gcolor); +#endif +} + +void +overview_color_from_gdk_color (OverviewColor *color, + const GdkColor *gcolor, + gdouble alpha) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (gcolor != NULL); + + color->red = (gdouble) gcolor->red / G_MAXUINT16; + color->green = (gdouble) gcolor->green / G_MAXUINT16; + color->blue = (gdouble) gcolor->blue / G_MAXUINT16; + color->alpha = alpha; +} + +void +overview_color_to_gdk_color (const OverviewColor *color, + GdkColor *gcolor) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (gcolor != NULL); + + gcolor->red = (guint16)(color->red * G_MAXUINT16); + gcolor->green = (guint16)(color->green * G_MAXUINT16); + gcolor->blue = (guint16)(color->blue * G_MAXUINT16); +} + +#if GTK_CHECK_VERSION (3, 0, 0) +void +overview_color_from_rgba (OverviewColor *color, + const GdkRGBA *rgba) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (rgba != NULL); + + color->red = rgba->red; + color->green = rgba->green; + color->blue = rgba->blue; + color->alpha = rgba->alpha; +} + +void +overview_color_to_rgba (const OverviewColor *color, + GdkRGBA *rgba) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (rgba != NULL); + + rgba->red = color->red; + rgba->green = color->green; + rgba->blue = color->blue; + rgba->alpha = color->alpha; +} +#endif + +void +overview_color_from_int (OverviewColor *color, + guint32 abgr, + gboolean with_alpha) +{ + g_return_if_fail (color != NULL); + guint8 r = abgr & 0xFF; + guint8 g = (abgr>>8) & 0xFF; + guint8 b = (abgr>>16) & 0xFF; + guint8 a = 255; + + if (with_alpha) + a = (abgr>>24) & 0xFF; + + color->red = (gdouble)r / G_MAXUINT8; + color->green = (gdouble)g / G_MAXUINT8; + color->blue = (gdouble)b / G_MAXUINT8; + color->alpha = (gdouble)a / G_MAXUINT8; +} + +guint32 +overview_color_to_int (const OverviewColor *color, + gboolean with_alpha) +{ + g_return_val_if_fail (color != NULL, 0); + + guint32 r = (guint8)(color->red * 255.0); + guint32 g = (guint8)(color->green * 255.0); + guint32 b = (guint8)(color->blue * 255.0); + guint32 a = 0; + + if (with_alpha) + a = (guint8)(color->alpha * 255.0); + + return (a<<24) | (b<<16) | (g<<8) | r; +} + +gboolean +overview_color_from_keyfile (OverviewColor *color, + GKeyFile *keyfile, + const gchar *section, + const gchar *option, + GError **error) +{ + gchar *color_key; + gchar *alpha_key; + gchar *clr_str; + gdouble alpha; + + g_return_val_if_fail (color != NULL, FALSE); + g_return_val_if_fail (keyfile != NULL, FALSE); + g_return_val_if_fail (section != NULL, FALSE); + g_return_val_if_fail (option != NULL, FALSE); + + color_key = g_strdup_printf ("%s-color", option); + alpha_key = g_strdup_printf ("%s-alpha", option); + + clr_str = g_key_file_get_string (keyfile, section, color_key, error); + if (*error != NULL) + { + g_free (color_key); + g_free (alpha_key); + return FALSE; + } + + g_free (color_key); + + alpha = g_key_file_get_double (keyfile, section, alpha_key, error); + if (*error != NULL) + { + g_free (alpha_key); + g_free (clr_str); + return FALSE; + } + + g_free (alpha_key); + + if (alpha < 0.0 || alpha > 1.0) + g_warning ("alpha value '%g' from keyfile out of 0-1 range", alpha); + + overview_color_parse (color, clr_str); + color->alpha = alpha; + + g_free (clr_str); + + return TRUE; +} + +gboolean +overview_color_to_keyfile (const OverviewColor *color, + GKeyFile *keyfile, + const gchar *section, + const gchar *option) +{ + gchar *color_key; + gchar *alpha_key; + gchar *clr_str; + + g_return_val_if_fail (color != NULL, FALSE); + g_return_val_if_fail (keyfile != NULL, FALSE); + g_return_val_if_fail (section != NULL, FALSE); + g_return_val_if_fail (option != NULL, FALSE); + + color_key = g_strdup_printf ("%s-color", option); + alpha_key = g_strdup_printf ("%s-alpha", option); + + clr_str = overview_color_to_string (color); + g_key_file_set_string (keyfile, section, color_key, clr_str); + g_free (color_key); + g_free (clr_str); + + g_key_file_set_double (keyfile, section, alpha_key, color->alpha); + g_free (alpha_key); + + return TRUE; +} + +void +overview_color_from_color_button (OverviewColor *color, + GtkColorButton *button) +{ + GdkColor gcolor; + guint16 alpha; + gdouble falpha; + gtk_color_button_get_color (button, &gcolor); + alpha = gtk_color_button_get_alpha (button); + falpha = (gdouble) alpha / (gdouble) G_MAXUINT16; + overview_color_from_gdk_color (color, &gcolor, falpha); +} + +void +overview_color_to_color_button (const OverviewColor *color, + GtkColorButton *button) +{ + GdkColor gcolor; + guint16 alpha; + overview_color_to_gdk_color (color, &gcolor); + gtk_color_button_set_color (button, &gcolor); + alpha = (guint16)(color->alpha * (gdouble) G_MAXUINT16); + gtk_color_button_set_alpha (button, alpha); +} + +GType +overview_color_get_type (void) +{ + static GType type = 0; + if (type == 0) + { + type = + g_boxed_type_register_static ("OverviewColor", + (GBoxedCopyFunc) overview_color_copy, + (GBoxedFreeFunc) overview_color_free); + } + return type; +}
Modified: overview/overview/overviewcolor.h 79 lines changed, 79 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,79 @@ +/* + * overviewcolor.h - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef OVERVIEW_COLOR_H_ +#define OVERVIEW_COLOR_H_ + +#include <gtk/gtk.h> + +#define OVERVIEW_TYPE_COLOR (overview_color_get_type ()) +#define OVERVIEW_COLOR_INIT { 0.0, 0.0, 0.0, 1.0 } + +typedef struct +{ + gdouble red; + gdouble green; + gdouble blue; + gdouble alpha; +} +OverviewColor; + +GType overview_color_get_type (void); +OverviewColor *overview_color_copy (OverviewColor *color); +void overview_color_free (OverviewColor *color); +gboolean overview_color_equal (const OverviewColor *color1, + const OverviewColor *color2); +gboolean overview_color_parse (OverviewColor *color, + const gchar *color_str); +gchar *overview_color_to_string (const OverviewColor *color); +void overview_color_from_gdk_color (OverviewColor *color, + const GdkColor *gcolor, + gdouble alpha); +void overview_color_to_gdk_color (const OverviewColor *color, + GdkColor *gcolor); +#if GTK_CHECK_VERSION (3, 0, 0) +void overview_color_from_rgba (OverviewColor *color, + const GdkRGBA *rgba); +void overview_color_to_rgba (const OverviewColor *color, + GdkRGBA *rgba); +#endif +void overview_color_from_int (OverviewColor *color, + guint32 abgr, + gboolean with_alpha); +guint32 overview_color_to_int (const OverviewColor *color, + gboolean with_alpha); +gboolean overview_color_from_keyfile (OverviewColor *color, + GKeyFile *keyfile, + const gchar *section, + const gchar *option, + GError **error); +gboolean overview_color_to_keyfile (const OverviewColor *color, + GKeyFile *keyfile, + const gchar *section, + const gchar *option); + +void overview_color_from_color_button (OverviewColor *color, + GtkColorButton *button); +void overview_color_to_color_button (const OverviewColor *color, + GtkColorButton *button); + +#endif /* OVERVIEW_COLOR_H_ */
Modified: overview/overview/overviewplugin.c 232 lines changed, 232 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,232 @@ +/* + * overviewplugin.c - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "overviewplugin.h" +#include "overviewscintilla.h" +#include "overviewprefs.h" +#include "overviewprefspanel.h" +#include "overviewui.h" +#include <errno.h> + +GeanyPlugin *geany_plugin; +GeanyData *geany_data; +GeanyFunctions *geany_functions; + +PLUGIN_VERSION_CHECK (224) + +PLUGIN_SET_INFO ( + "Overview", + _("Provides an overview of the active document"), + "0.01", + "Matthew Brush matt@geany.org") + +static OverviewPrefs *overview_prefs = NULL; + +static void write_config (void); + +static void +on_visible_pref_notify (OverviewPrefs *prefs, + GParamSpec *pspec, + gpointer user_data) +{ + write_config (); +} + +static void +toggle_visibility (void) +{ + gboolean visible = TRUE; + g_object_get (overview_prefs, "visible", &visible, NULL); + g_object_set (overview_prefs, "visible", !visible, NULL); +} + +enum +{ + KB_TOGGLE_VISIBLE, + KB_TOGGLE_POSITION, + KB_TOGGLE_INVERTED, + NUM_KB +}; + +static gboolean +on_kb_activate (guint keybinding_id) +{ + switch (keybinding_id) + { + case KB_TOGGLE_VISIBLE: + toggle_visibility (); + break; + case KB_TOGGLE_POSITION: + { + GtkPositionType pos; + g_object_get (overview_prefs, "position", &pos, NULL); + pos = (pos == GTK_POS_LEFT) ? GTK_POS_RIGHT : GTK_POS_LEFT; + g_object_set (overview_prefs, "position", pos, NULL); + break; + } + case KB_TOGGLE_INVERTED: + { + gboolean inv = FALSE; + g_object_get (overview_prefs, "overlay-inverted", &inv, NULL); + g_object_set (overview_prefs, "overlay-inverted", !inv, NULL); + break; + } + default: + break; + } + return TRUE; +} + +static gchar * +get_config_file (void) +{ + gchar *dir; + gchar *fn; + static const gchar *def_config = OVERVIEW_PREFS_DEFAULT_CONFIG; + + dir = g_build_filename (geany_data->app->configdir, "plugins", "overview", NULL); + fn = g_build_filename (dir, "prefs.conf", NULL); + + if (! g_file_test (fn, G_FILE_TEST_IS_DIR)) + { + if (g_mkdir_with_parents (dir, 0755) != 0) + { + g_critical ("failed to create config dir '%s': %s", dir, g_strerror (errno)); + g_free (dir); + g_free (fn); + return NULL; + } + } + + g_free (dir); + + if (! g_file_test (fn, G_FILE_TEST_EXISTS)) + { + GError *error = NULL; + if (!g_file_set_contents (fn, def_config, -1, &error)) + { + g_critical ("failed to save default config to file '%s': %s", + fn, error->message); + g_error_free (error); + g_free (fn); + return NULL; + } + } + + return fn; +} + +static void +write_config (void) +{ + gchar *conf_file; + GError *error = NULL; + conf_file = get_config_file (); + if (! overview_prefs_save (overview_prefs, conf_file, &error)) + { + g_critical ("failed to save preferences to file '%s': %s", conf_file, error->message); + g_error_free (error); + } + g_free (conf_file); +} + +void +plugin_init (G_GNUC_UNUSED GeanyData *data) +{ + gchar *conf_file; + GError *error = NULL; + GeanyKeyGroup *key_group; + + plugin_module_make_resident (geany_plugin); + + overview_prefs = overview_prefs_new (); + conf_file = get_config_file (); + if (! overview_prefs_load (overview_prefs, conf_file, &error)) + { + g_critical ("failed to load preferences file '%s': %s", conf_file, error->message); + g_error_free (error); + } + g_free (conf_file); + + overview_ui_init (overview_prefs); + + key_group = plugin_set_key_group (geany_plugin, + "overview", + NUM_KB, + on_kb_activate); + + keybindings_set_item (key_group, + KB_TOGGLE_VISIBLE, + NULL, 0, 0, + "toggle-visibility", + _("Toggle Visibility"), + overview_ui_get_menu_item ()); + + keybindings_set_item (key_group, + KB_TOGGLE_POSITION, + NULL, 0, 0, + "toggle-position", + _("Toggle Left/Right Position"), + NULL); + + keybindings_set_item (key_group, + KB_TOGGLE_INVERTED, + NULL, 0, 0, + "toggle-inverted", + _("Toggle Overlay Inversion"), + NULL); + + g_signal_connect (overview_prefs, "notify::visible", G_CALLBACK (on_visible_pref_notify), NULL); +} + +void +plugin_cleanup (void) +{ + write_config (); + overview_ui_deinit (); + + if (OVERVIEW_IS_PREFS (overview_prefs)) + g_object_unref (overview_prefs); + overview_prefs = NULL; +} + +static void +on_prefs_stored (OverviewPrefsPanel *panel, + OverviewPrefs *prefs, + gpointer user_data) +{ + write_config (); + overview_ui_queue_update (); +} + +GtkWidget * +plugin_configure (GtkDialog *dialog) +{ + GtkWidget *panel; + panel = overview_prefs_panel_new (overview_prefs, dialog); + g_signal_connect (panel, "prefs-stored", G_CALLBACK (on_prefs_stored), NULL); + return panel; +}
Modified: overview/overview/overviewplugin.h 37 lines changed, 37 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,37 @@ +/* + * overviewplugin.h - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef OVERVIEW_PLUGIN_H +#define OVERVIEW_PLUGIN_H + +#include <gtk/gtk.h> +#include <gdk/gdk.h> +#include <geanyplugin.h> + +extern GeanyData *geany_data; +extern GeanyPlugin *geany_plugin; +extern GeanyFunctions *geany_functions; + +void overview_plugin_queue_update (void); +gboolean overview_geany_supports_left_position (void); + +#endif // OVERVIEW_PLUGIN_H
Modified: overview/overview/overviewprefs.c 447 lines changed, 447 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,447 @@ +/* + * overviewprefs.c - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "overviewprefs.h" +#include "overviewcolor.h" +#include "overviewscintilla.h" +#include <string.h> +#include <stdarg.h> + +enum +{ + PROP_0, + PROP_WIDTH, + PROP_ZOOM, + PROP_SHOW_TOOLTIP, + PROP_SHOW_SCROLLBAR, + PROP_DOUBLE_BUFFERED, + PROP_SCROLL_LINES, + PROP_OVERLAY_ENABLED, + PROP_OVERLAY_COLOR, + PROP_OVERLAY_OUTLINE_COLOR, + PROP_OVERLAY_INVERTED, + PROP_POSITION, + PROP_VISIBLE, + N_PROPERTIES +}; + +struct OverviewPrefs_ +{ + GObject parent; + guint width; + gint zoom; + gboolean show_tt; + gboolean show_sb; + gboolean dbl_buf; + gint scr_lines; + gboolean ovl_en; + OverviewColor ovl_clr; + OverviewColor out_clr; + gboolean ovl_inv; + GtkPositionType position; + gboolean visible; +}; + +struct OverviewPrefsClass_ +{ + GObjectClass parent_class; +}; + +static void overview_prefs_finalize (GObject *object); +static void overview_prefs_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void overview_prefs_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + + +static GParamSpec *pspecs[N_PROPERTIES] = { NULL }; + +G_DEFINE_TYPE (OverviewPrefs, overview_prefs, G_TYPE_OBJECT) + +static void +overview_prefs_class_init (OverviewPrefsClass *klass) +{ + GObjectClass *g_object_class; + + g_object_class = G_OBJECT_CLASS (klass); + + g_object_class->finalize = overview_prefs_finalize; + g_object_class->set_property = overview_prefs_set_property; + g_object_class->get_property = overview_prefs_get_property; + + pspecs[PROP_WIDTH] = g_param_spec_uint ("width", "Width", "Width of the overview", 16, 512, 120, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_ZOOM] = g_param_spec_int ("zoom", "Zoom", "Zoom level of the view", -10, 20, -10, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_SHOW_TOOLTIP] = g_param_spec_boolean ("show-tooltip", "ShowTooltip", "Whether to show informational tooltip over the overview", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_SHOW_SCROLLBAR] = g_param_spec_boolean ("show-scrollbar", "ShowScrollbar", "Whether to show the normal editor scrollbar", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_DOUBLE_BUFFERED] = g_param_spec_boolean ("double-buffered", "DoubleBuffered", "Whether the overview drawing is double-buffered", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_SCROLL_LINES] = g_param_spec_uint ("scroll-lines", "ScrollLines", "The number of lines to scroll the overview by", 1, 512, 1, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_OVERLAY_ENABLED] = g_param_spec_boolean ("overlay-enabled", "OverlayEnabled", "Whether an overlay is drawn overtop the overview", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_OVERLAY_COLOR] = g_param_spec_boxed ("overlay-color", "OverlayColor", "The color of the overlay", OVERVIEW_TYPE_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_OVERLAY_OUTLINE_COLOR] = g_param_spec_boxed ("overlay-outline-color", "OverlayOutlineColor", "The color of the outlines drawn around the overlay", OVERVIEW_TYPE_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_OVERLAY_INVERTED] = g_param_spec_boolean ("overlay-inverted", "OverlayInverted", "Whether to invert the drawing of the overlay", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_POSITION] = g_param_spec_enum ("position", "Position", "Where to draw the overview", GTK_TYPE_POSITION_TYPE, GTK_POS_RIGHT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + pspecs[PROP_VISIBLE] = g_param_spec_boolean ("visible", "Visible", "Whether the overview is shown", TRUE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + g_object_class_install_properties (g_object_class, N_PROPERTIES, pspecs); +} + +static void +overview_prefs_finalize (GObject *object) +{ + g_return_if_fail (OVERVIEW_IS_PREFS (object)); + G_OBJECT_CLASS (overview_prefs_parent_class)->finalize (object); +} + +static void +overview_prefs_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + OverviewPrefs *self = OVERVIEW_PREFS (object); + + switch (prop_id) + { + case PROP_WIDTH: + self->width = g_value_get_uint (value); + g_object_notify (object, "width"); + break; + case PROP_ZOOM: + self->zoom = g_value_get_int (value); + g_object_notify (object, "zoom"); + break; + case PROP_SHOW_TOOLTIP: + self->show_tt = g_value_get_boolean (value); + g_object_notify (object, "show-tooltip"); + break; + case PROP_SHOW_SCROLLBAR: + self->show_sb = g_value_get_boolean (value); + g_object_notify (object, "show-scrollbar"); + break; + case PROP_DOUBLE_BUFFERED: + self->dbl_buf = g_value_get_boolean (value); + g_object_notify (object, "double-buffered"); + break; + case PROP_SCROLL_LINES: + self->scr_lines = g_value_get_uint (value); + g_object_notify (object, "scroll-lines"); + break; + case PROP_OVERLAY_ENABLED: + self->ovl_en = g_value_get_boolean (value); + g_object_notify (object, "overlay-enabled"); + break; + case PROP_OVERLAY_COLOR: + { + OverviewColor *src = g_value_get_boxed (value); + if (src != NULL) + memcpy (&self->ovl_clr, src, sizeof (OverviewColor)); + g_object_notify (object, "overlay-color"); + break; + } + case PROP_OVERLAY_OUTLINE_COLOR: + { + OverviewColor *src = g_value_get_boxed (value); + if (src != NULL) + memcpy (&self->out_clr, src, sizeof (OverviewColor)); + g_object_notify (object, "overlay-outline-color"); + break; + } + case PROP_OVERLAY_INVERTED: + self->ovl_inv = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), "overlay-inverted"); + break; + case PROP_POSITION: + self->position = g_value_get_enum (value); + g_object_notify (G_OBJECT (self), "position"); + break; + case PROP_VISIBLE: + self->visible = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), "visible"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +overview_prefs_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + OverviewPrefs *self = OVERVIEW_PREFS (object); + + switch (prop_id) + { + case PROP_WIDTH: + g_value_set_uint (value, self->width); + break; + case PROP_ZOOM: + g_value_set_int (value, self->zoom); + break; + case PROP_SHOW_TOOLTIP: + g_value_set_boolean (value, self->show_tt); + break; + case PROP_SHOW_SCROLLBAR: + g_value_set_boolean (value, self->show_sb); + break; + case PROP_DOUBLE_BUFFERED: + g_value_set_boolean (value, self->dbl_buf); + break; + case PROP_SCROLL_LINES: + g_value_set_uint (value, self->scr_lines); + break; + case PROP_OVERLAY_ENABLED: + g_value_set_boolean (value, self->ovl_en); + break; + case PROP_OVERLAY_COLOR: + g_value_set_boxed (value, &self->ovl_clr); + break; + case PROP_OVERLAY_OUTLINE_COLOR: + g_value_set_boxed (value, &self->out_clr); + break; + case PROP_OVERLAY_INVERTED: + g_value_set_boolean (value, self->ovl_inv); + break; + case PROP_POSITION: + g_value_set_enum (value, self->position); + break; + case PROP_VISIBLE: + g_value_set_boolean (value, self->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +overview_prefs_init (OverviewPrefs *self) +{ + self->position = GTK_POS_RIGHT; + self->visible = TRUE; +} + +OverviewPrefs * +overview_prefs_new (void) +{ + return g_object_new (OVERVIEW_TYPE_PREFS, NULL); +} + +gboolean +overview_prefs_load (OverviewPrefs *self, + const gchar *filename, + GError **error) +{ + gchar *contents = NULL; + gsize size = 0; + g_return_val_if_fail (OVERVIEW_IS_PREFS (self), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + if (! g_file_get_contents (filename, &contents, &size, error)) + return FALSE; + if (! overview_prefs_from_data (self, contents, size, error)) + { + g_free (contents); + return FALSE; + } + g_free (contents); + return TRUE; +} + +gboolean +overview_prefs_save (OverviewPrefs *self, + const gchar *filename, + GError **error) + +{ + gchar *contents = NULL; + gsize size = 0; + g_return_val_if_fail (OVERVIEW_IS_PREFS (self), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + contents = overview_prefs_to_data (self, &size, error); + if (contents == NULL) + return FALSE; + if (! g_file_set_contents (filename, contents, size, error)) + { + g_free (contents); + return FALSE; + } + g_free (contents); + return TRUE; +} + +#define GET(T, k, v) \ + do { \ + if (g_key_file_has_key (kf, "overview", k, NULL)) { \ + v = g_key_file_get_##T (kf, "overview", k, error); \ + if (error != NULL && *error != NULL) { \ + g_key_file_free (kf); \ + return FALSE; \ + } else { \ + g_object_notify (G_OBJECT (self), k); \ + } \ + } \ + } while (0) + +gboolean +overview_prefs_from_data (OverviewPrefs *self, + const gchar *contents, + gssize size, + GError **error) +{ + GKeyFile *kf; + gchar *pos; + + g_return_val_if_fail (OVERVIEW_IS_PREFS (self), FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + + kf = g_key_file_new (); + + if (! g_key_file_load_from_data (kf, contents, size, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, + error)) + { + g_key_file_free (kf); + return FALSE; + } + + GET (uint64, "width", self->width); + GET (integer, "zoom", self->zoom); + GET (boolean, "show-tooltip", self->show_tt); + GET (boolean, "show-scrollbar", self->show_sb); + GET (boolean, "double-buffered", self->dbl_buf); + GET (uint64, "scroll-lines", self->scr_lines); + GET (boolean, "overlay-enabled", self->ovl_en); + GET (boolean, "overlay-inverted", self->ovl_inv); + GET (boolean, "visible", self->visible); + + if (g_key_file_has_key (kf, "overview", "position", NULL)) + { + pos = g_key_file_get_string (kf, "overview", "position", error); + if (error != NULL && *error != NULL) + return FALSE; + if (g_ascii_strcasecmp (pos, "right") == 0) + self->position = GTK_POS_RIGHT; + else if (g_ascii_strcasecmp (pos, "left") == 0) + self->position = GTK_POS_LEFT; + else + { + g_warning ("unknown value '%s' for 'position' key", pos); + self->position = GTK_POS_RIGHT; + } + g_free (pos); + } + + if (g_key_file_has_key (kf, "overview", "overlay-color", NULL) && + g_key_file_has_key (kf, "overview", "overlay-alpha", NULL)) + { + if (! overview_color_from_keyfile (&self->ovl_clr, kf, "overview", "overlay", error)) + { + g_key_file_free (kf); + return FALSE; + } + g_object_notify (G_OBJECT (self), "overlay-color"); + } + + if (g_key_file_has_key (kf, "overview", "overlay-outline-color", NULL) && + g_key_file_has_key (kf, "overview", "overlay-outline-alpha", NULL)) + { + if (! overview_color_from_keyfile (&self->out_clr, kf, "overview", "overlay-outline", error)) + { + g_key_file_free (kf); + return FALSE; + } + g_object_notify (G_OBJECT (self), "overlay-outline-color"); + } + + g_key_file_free (kf); + + return TRUE; +} + +#define SET(T, k, v) g_key_file_set_##T (kf, "overview", k, v) + +gchar * +overview_prefs_to_data (OverviewPrefs *self, + gsize *size, + GError **error) +{ + GKeyFile *kf; + gchar *contents; + + g_return_val_if_fail (OVERVIEW_IS_PREFS (self), NULL); + + kf = g_key_file_new (); + + SET (uint64, "width", self->width); + SET (integer, "zoom", self->zoom); + SET (boolean, "show-tooltip", self->show_tt); + SET (boolean, "show-scrollbar", self->show_sb); + SET (boolean, "double-buffered", self->dbl_buf); + SET (uint64, "scroll-lines", self->scr_lines); + SET (boolean, "overlay-enabled", self->ovl_en); + SET (boolean, "overlay-inverted", self->ovl_inv); + SET (boolean, "visible", self->visible); + + g_key_file_set_string (kf, "overview", "position", + self->position == GTK_POS_LEFT ? "left" : "right"); + + overview_color_to_keyfile (&self->ovl_clr, kf, "overview", "overlay"); + overview_color_to_keyfile (&self->out_clr, kf, "overview", "overlay-outline"); + + contents = g_key_file_to_data (kf, size, error); + g_key_file_free (kf); + return contents; +} + +#define BIND(prop) \ + g_object_bind_property (self, prop, sci, prop, G_BINDING_SYNC_CREATE) + +void +overview_prefs_bind_scintilla (OverviewPrefs *self, + GObject *sci) +{ + g_return_if_fail (OVERVIEW_IS_PREFS (self)); + g_return_if_fail (OVERVIEW_IS_SCINTILLA (sci)); + + BIND ("width"); + BIND ("zoom"); + BIND ("show-tooltip"); + BIND ("show-scrollbar"); + BIND ("double-buffered"); + BIND ("scroll-lines"); + BIND ("overlay-enabled"); + BIND ("overlay-color"); + BIND ("overlay-outline-color"); + BIND ("overlay-inverted"); + BIND ("visible"); +}
Modified: overview/overview/overviewprefs.h 78 lines changed, 78 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,78 @@ +/* + * overviewprefs.h - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef OVERVIEWPREFS_H_ +#define OVERVIEWPREFS_H_ 1 + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define OVERVIEW_TYPE_PREFS (overview_prefs_get_type ()) +#define OVERVIEW_PREFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVERVIEW_TYPE_PREFS, OverviewPrefs)) +#define OVERVIEW_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVERVIEW_TYPE_PREFS, OverviewPrefsClass)) +#define OVERVIEW_IS_PREFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVERVIEW_TYPE_PREFS)) +#define OVERVIEW_IS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVERVIEW_TYPE_PREFS)) +#define OVERVIEW_PREFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVERVIEW_TYPE_PREFS, OverviewPrefsClass)) + +typedef struct OverviewPrefs_ OverviewPrefs; +typedef struct OverviewPrefsClass_ OverviewPrefsClass; + +GType overview_prefs_get_type (void); +OverviewPrefs *overview_prefs_new (void); +gboolean overview_prefs_load (OverviewPrefs *prefs, + const gchar *filename, + GError **error); +gboolean overview_prefs_save (OverviewPrefs *prefs, + const gchar *filename, + GError **error); +gboolean overview_prefs_from_data (OverviewPrefs *prefs, + const gchar *contents, + gssize size, + GError **error); +gchar* overview_prefs_to_data (OverviewPrefs *prefs, + gsize *size, + GError **error); +void overview_prefs_bind_scintilla (OverviewPrefs *prefs, + GObject *sci); + +#define OVERVIEW_PREFS_DEFAULT_CONFIG \ + "[overview]\n" \ + "width = 120\n" \ + "zoom = -10\n" \ + "show-tooltip = true\n" \ + "double-buffered = true\n" \ + "scroll-lines = 4\n" \ + "show-scrollbar = true\n" \ + "overlay-enabled = true\n" \ + "overlay-color = #000000\n" \ + "overlay-alpha = 0.10\n" \ + "overlay-outline-color = #000000\n" \ + "overlay-outline-alpha = 0.10\n" \ + "overlay-inverted = true\n" \ + "position = right\n" \ + "visible = true\n" \ + "\n" + +G_END_DECLS + +#endif /* OVERVIEWPREFS_H_ */
Modified: overview/overview/overviewprefspanel.c 264 lines changed, 264 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,264 @@ +/* + * overviewprefspanel.c - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "overviewprefspanel.h" +#include "overviewcolor.h" +#include "overviewplugin.h" +#include "overviewui.h" + +struct OverviewPrefsPanel_ +{ + GtkFrame parent; + OverviewPrefs *prefs; + GtkWidget *prefs_table; + GtkWidget *width_spin; + GtkWidget *zoom_spin; + GtkWidget *scr_lines_spin; + GtkWidget *pos_left_check; + GtkWidget *hide_tt_check; + GtkWidget *hide_sb_check; + GtkWidget *ovl_dis_check; + GtkWidget *ovl_inv_check; + GtkWidget *ovl_clr_btn; + GtkWidget *out_clr_btn; +}; + +struct OverviewPrefsPanelClass_ +{ + GtkFrameClass parent_class; +}; + +static void overview_prefs_panel_finalize (GObject *object); + +G_DEFINE_TYPE (OverviewPrefsPanel, overview_prefs_panel, GTK_TYPE_FRAME) + +static void +overview_prefs_panel_class_init (OverviewPrefsPanelClass *klass) +{ + GObjectClass *g_object_class; + + g_object_class = G_OBJECT_CLASS (klass); + + g_object_class->finalize = overview_prefs_panel_finalize; + + g_signal_new ("prefs-stored", + G_TYPE_FROM_CLASS (g_object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, OVERVIEW_TYPE_PREFS); + + g_signal_new ("prefs-loaded", + G_TYPE_FROM_CLASS (g_object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, OVERVIEW_TYPE_PREFS); +} + +static void +overview_prefs_panel_finalize (GObject *object) +{ + OverviewPrefsPanel *self; + + g_return_if_fail (OVERVIEW_IS_PREFS_PANEL (object)); + + self = OVERVIEW_PREFS_PANEL (object); + + g_object_unref (self->prefs); + + G_OBJECT_CLASS (overview_prefs_panel_parent_class)->finalize (object); +} + +static GtkWidget * +builder_get_widget (GtkBuilder *builder, + const gchar *name) +{ + GObject *result = NULL; + gchar *real_name; + + real_name = g_strdup_printf ("overview-%s", name); + result = gtk_builder_get_object (builder, real_name); + + if (! G_IS_OBJECT (result)) + g_critical ("unable to find widget '%s' in UI file", real_name); + else if (! GTK_IS_WIDGET (result)) + g_critical ("object '%s' in UI file is not a widget", real_name); + + g_free (real_name); + + return (GtkWidget*) result; +} + +static void +overview_prefs_panel_store_prefs (OverviewPrefsPanel *self) +{ + guint width; + gint zoom; + guint scr_lines; + gboolean pos_left = FALSE; + OverviewColor ovl_clr = {0,0,0,0}; + OverviewColor out_clr = {0,0,0,0}; + + width = gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->width_spin)); + zoom = gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->zoom_spin)); + scr_lines = gtk_spin_button_get_value (GTK_SPIN_BUTTON (self->scr_lines_spin)); + pos_left = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->pos_left_check)); + overview_color_from_color_button (&ovl_clr, GTK_COLOR_BUTTON (self->ovl_clr_btn)); + overview_color_from_color_button (&out_clr, GTK_COLOR_BUTTON (self->out_clr_btn)); + + g_object_set (self->prefs, + "width", width, + "zoom", zoom, + "scroll-lines", scr_lines, + "position", pos_left ? GTK_POS_LEFT : GTK_POS_RIGHT, + "show-tooltip", !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->hide_tt_check)), + "show-scrollbar", !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->hide_sb_check)), + "overlay-enabled", !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->ovl_dis_check)), + "overlay-inverted", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->ovl_inv_check)), + "overlay-color", &ovl_clr, + "overlay-outline-color", &out_clr, + NULL); + + g_signal_emit_by_name (self, "prefs-stored", self->prefs); +} + +static void +overview_prefs_panel_load_prefs (OverviewPrefsPanel *self) +{ + gint zoom = 0; + guint width = 0; + guint scr_lines = 0; + gboolean show_tt = FALSE; + gboolean show_sb = FALSE; + gboolean ovl_en = FALSE; + gboolean ovl_inv = FALSE; + GtkPositionType pos = FALSE; + OverviewColor *ovl_clr = NULL; + OverviewColor *out_clr = NULL; + + g_object_get (self->prefs, + "width", &width, + "zoom", &zoom, + "scroll-lines", &scr_lines, + "position", &pos, + "show-tooltip", &show_tt, + "show-scrollbar", &show_sb, + "overlay-enabled", &ovl_en, + "overlay-inverted", &ovl_inv, + "overlay-color", &ovl_clr, + "overlay-outline-color", &out_clr, + NULL); + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->width_spin), width); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->zoom_spin), zoom); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->scr_lines_spin), scr_lines); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->pos_left_check), (pos == GTK_POS_LEFT)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->hide_tt_check), !show_tt); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->hide_sb_check), !show_sb); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->ovl_inv_check), ovl_inv); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->ovl_dis_check), !ovl_en); + overview_color_to_color_button (ovl_clr, GTK_COLOR_BUTTON (self->ovl_clr_btn)); + overview_color_to_color_button (out_clr, GTK_COLOR_BUTTON (self->out_clr_btn)); + + overview_color_free (ovl_clr); + overview_color_free (out_clr); + + g_signal_emit_by_name (self, "prefs-loaded", self->prefs); +} + +static void +overview_prefs_panel_init (OverviewPrefsPanel *self) +{ + GtkBuilder *builder; + GError *error = NULL; + GtkWidget *overlay_frame; + + builder = gtk_builder_new (); + if (! gtk_builder_add_from_file (builder, OVERVIEW_PREFS_UI_FILE, &error)) + { + g_critical ("failed to open UI file '%s': %s", OVERVIEW_PREFS_UI_FILE, error->message); + g_error_free (error); + g_object_unref (builder); + return; + } + + self->prefs_table = builder_get_widget (builder, "prefs-table"); + self->width_spin = builder_get_widget (builder, "width-spin"); + self->zoom_spin = builder_get_widget (builder, "zoom-spin"); + self->scr_lines_spin = builder_get_widget (builder, "scroll-lines-spin"); + self->pos_left_check = builder_get_widget (builder, "position-left-check"); + self->hide_tt_check = builder_get_widget (builder, "hide-tooltip-check"); + self->hide_sb_check = builder_get_widget (builder, "hide-scrollbar-check"); + self->ovl_inv_check = builder_get_widget (builder, "overlay-inverted-check"); + self->ovl_clr_btn = builder_get_widget (builder, "overlay-color"); + self->out_clr_btn = builder_get_widget (builder, "overlay-outline-color"); + + // The "Draw over visible area" checkbox hides/shows the "Overlay" frame + self->ovl_dis_check = builder_get_widget (builder, "overlay-disable-check"); + overlay_frame = builder_get_widget (builder, "overlay-frame"); + g_object_bind_property (self->ovl_dis_check, "active", overlay_frame, "sensitive", G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); + + gtk_widget_show_all (self->prefs_table); + gtk_container_add (GTK_CONTAINER (self), self->prefs_table); + g_object_unref (builder); + +#ifndef OVERVIEW_UI_SUPPORTS_LEFT_POSITION + gtk_widget_set_no_show_all (self->pos_left_check, TRUE); + gtk_widget_hide (self->pos_left_check); +#endif +} + +static void +on_host_dialog_response (GtkDialog *dialog, + gint response_id, + OverviewPrefsPanel *self) +{ + switch (response_id) + { + case GTK_RESPONSE_APPLY: + case GTK_RESPONSE_OK: + overview_prefs_panel_store_prefs (self); + break; + case GTK_RESPONSE_CANCEL: + default: + break; + } +} + +GtkWidget * +overview_prefs_panel_new (OverviewPrefs *prefs, + GtkDialog *host_dialog) +{ + OverviewPrefsPanel *self; + self = g_object_new (OVERVIEW_TYPE_PREFS_PANEL, NULL); + self->prefs = g_object_ref (prefs); + g_signal_connect (host_dialog, "response", G_CALLBACK (on_host_dialog_response), self); + overview_prefs_panel_load_prefs (self); + return GTK_WIDGET (self); +}
Modified: overview/overview/overviewprefspanel.h 47 lines changed, 47 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,47 @@ +/* + * overviewprefspanel.h - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef OVERVIEWPREFSPANEL_H_ +#define OVERVIEWPREFSPANEL_H_ 1 + +#include "overviewprefs.h" +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define OVERVIEW_TYPE_PREFS_PANEL (overview_prefs_panel_get_type ()) +#define OVERVIEW_PREFS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVERVIEW_TYPE_PREFS_PANEL, OverviewPrefsPanel)) +#define OVERVIEW_PREFS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVERVIEW_TYPE_PREFS_PANEL, OverviewPrefsPanelClass)) +#define OVERVIEW_IS_PREFS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVERVIEW_TYPE_PREFS_PANEL)) +#define OVERVIEW_IS_PREFS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVERVIEW_TYPE_PREFS_PANEL)) +#define OVERVIEW_PREFS_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVERVIEW_TYPE_PREFS_PANEL, OverviewPrefsPanelClass)) + +typedef struct OverviewPrefsPanel_ OverviewPrefsPanel; +typedef struct OverviewPrefsPanelClass_ OverviewPrefsPanelClass; + +GType overview_prefs_panel_get_type (void); +GtkWidget *overview_prefs_panel_new (OverviewPrefs *prefs, + GtkDialog *host_dialog); + +G_END_DECLS + +#endif /* OVERVIEWPREFSPANEL_H_ */
Modified: overview/overview/overviewscintilla.c 1299 lines changed, 1299 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,1299 @@ +/* + * overviewscintilla.c - This file is part of the Geany Overview plugin + * + * Copyright (c) 2015 Matthew Brush mbrush@codebrainz.ca + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "overviewscintilla.h" +#include "overviewplugin.h" +#include <string.h> + +#define OVERVIEW_SCINTILLA_CURSOR GDK_ARROW +#define OVERVIEW_SCINTILLA_CURSOR_CLICK GDK_ARROW +#define OVERVIEW_SCINTILLA_CURSOR_SCROLL GDK_SB_V_DOUBLE_ARROW +#define OVERVIEW_SCINTILLA_ZOOM_MIN -100 +#define OVERVIEW_SCINTILLA_ZOOM_MAX 100 +#define OVERVIEW_SCINTILLA_ZOOM_DEF -20 +#define OVERVIEW_SCINTILLA_WIDTH_MIN 16 +#define OVERVIEW_SCINTILLA_WIDTH_MAX 512 +#define OVERVIEW_SCINTILLA_WIDTH_DEF 120 +#define OVERVIEW_SCINTILLA_SCROLL_LINES 1 + +#ifndef SC_MAX_MARGIN +# define SC_MAX_MARGIN 4 +#endif + +#define sci_send(sci, msg, wParam, lParam) \ + scintilla_send_message (SCINTILLA (sci), SCI_##msg, (uptr_t)(wParam), (sptr_t)(lParam)) + +static const OverviewColor def_overlay_color = { 0.0, 0.0, 0.0, 0.25 }; +static const OverviewColor def_overlay_outline_color = { 0.0, 0.0, 0.0, 0.0 }; + +enum +{ + PROP_0, + PROP_SCINTILLA, + PROP_CURSOR, + PROP_VISIBLE_RECT, + PROP_WIDTH, + PROP_ZOOM, + PROP_SHOW_TOOLTIP, + PROP_OVERLAY_ENABLED, + PROP_OVERLAY_COLOR, + PROP_OVERLAY_OUTLINE_COLOR, + PROP_OVERLAY_INVERTED, + PROP_DOUBLE_BUFFERED, + PROP_SCROLL_LINES, + PROP_SHOW_SCROLLBAR, + N_PROPERTIES, +}; + +struct OverviewScintilla_ +{ + ScintillaObject parent; + ScintillaObject *sci; // source scintilla + GtkWidget *canvas; // internal GtkDrawingArea of scintilla + GdkCursorType cursor; // the chosen mouse cursor to use over the scintilla + GdkCursorType active_cursor; // the cursor to draw + GdkRectangle visible_rect; // visible region rectangle + guint width; // width of the overview + gint zoom; // zoom level of scintilla + gboolean show_tooltip; // whether tooltip shown on hover + gboolean overlay_enabled; // whether the visible overlay is drawn + OverviewColor overlay_color; // the color of the visible overlay + OverviewColor overlay_outline_color; // the color of the outline of the overlay + gboolean overlay_inverted;// draw overlay over the visible area instead of around it + gboolean double_buffered; // whether to enable double-buffering on internal scintilla canvas + gint scroll_lines; // number of lines to scroll each scroll-event + gboolean show_scrollbar; // show the main scintilla's scrollbar + gboolean mouse_down; // whether the mouse is down + gulong update_rect; // signal id of idle rect handler + gulong conf_event; // signal id of the configure event on scintilla internal drawing area + GtkWidget *src_canvas; // internal drawing area of main scintilla +}; + +struct OverviewScintillaClass_ +{ + ScintillaClass parent_class; +}; + +static GParamSpec *pspecs[N_PROPERTIES] = { NULL }; + +static void overview_scintilla_finalize (GObject *object); +static void overview_scintilla_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void overview_scintilla_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void overview_scintilla_set_src_sci (OverviewScintilla *self, + ScintillaObject *sci); + +#if GTK_CHECK_VERSION (3, 0, 0) +static gboolean overview_scintilla_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data); +#else +static gboolean overview_scintilla_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data); +#endif + +G_DEFINE_TYPE (OverviewScintilla, overview_scintilla, scintilla_get_type()) + +static void +overview_scintilla_class_init (OverviewScintillaClass *klass) +{ + GObjectClass *g_object_class; + + g_object_class = G_OBJECT_CLASS (klass); + + g_object_class->finalize = overview_scintilla_finalize; + g_object_class->set_property = overview_scintilla_set_property; + g_object_class->get_property = overview_scintilla_get_property; + + pspecs[PROP_SCINTILLA] = + g_param_spec_object ("scintilla", + "Scintilla", + "The source ScintillaObject", + scintilla_get_type (), + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + + pspecs[PROP_CURSOR] = + g_param_spec_enum ("cursor", + "Cursor", + "The GdkCursorType to use for the mouse cursor", + GDK_TYPE_CURSOR_TYPE, + OVERVIEW_SCINTILLA_CURSOR, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_VISIBLE_RECT] = + g_param_spec_boxed ("visible-rect", + "VisibleRect", + "The visible area indication rectangle to draw", + GDK_TYPE_RECTANGLE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_WIDTH] = + g_param_spec_uint ("width", + "Width", + "Width of the overview", + OVERVIEW_SCINTILLA_WIDTH_MIN, + OVERVIEW_SCINTILLA_WIDTH_MAX, + OVERVIEW_SCINTILLA_WIDTH_DEF, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_ZOOM] = + g_param_spec_int ("zoom", + "Zoom", + "The zoom-level of the overview", + OVERVIEW_SCINTILLA_ZOOM_MIN, + OVERVIEW_SCINTILLA_ZOOM_MAX, + OVERVIEW_SCINTILLA_ZOOM_DEF, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_SHOW_TOOLTIP] = + g_param_spec_boolean ("show-tooltip", + "ShowTooltip", + "Whether to show a tooltip with addition info on mouse over", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_OVERLAY_ENABLED] = + g_param_spec_boolean ("overlay-enabled", + "OverlayEnabled", + "Whether an overlay is drawn ontop of the overview", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_OVERLAY_COLOR] = + g_param_spec_boxed ("overlay-color", + "OverlayColor", + "The color of the overlay, if enabled", + OVERVIEW_TYPE_COLOR, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_OVERLAY_OUTLINE_COLOR] = + g_param_spec_boxed ("overlay-outline-color", + "OverlayOutlineColor", + "The color of the overlay's outline, if enabled", + OVERVIEW_TYPE_COLOR, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_OVERLAY_INVERTED] = + g_param_spec_boolean ("overlay-inverted", + "OverlayInverted", + "Whether to draw the overlay over the visible area", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_DOUBLE_BUFFERED] = + g_param_spec_boolean ("double-buffered", + "DoubleBuffered", + "Whether the overview Scintilla's internal canvas is double-buffered", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_SCROLL_LINES] = + g_param_spec_int ("scroll-lines", + "ScrollLines", + "The number of lines to move each scroll, -1 for default, 0 to disable.", + -1, 100, OVERVIEW_SCINTILLA_SCROLL_LINES, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + pspecs[PROP_SHOW_SCROLLBAR] = + g_param_spec_boolean ("show-scrollbar", + "ShowScrollbar", + "Whether to show the scrollbar in the main Scintilla", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE); + + g_object_class_install_properties (g_object_class, N_PROPERTIES, pspecs); +} + +static void +overview_scintilla_finalize (GObject *object) +{ + OverviewScintilla *self; + + g_return_if_fail (OVERVIEW_IS_SCINTILLA (object)); + + self = OVERVIEW_SCINTILLA (object); + + if (GTK_IS_WIDGET (self->src_canvas) && self->conf_event != 0) + g_signal_handler_disconnect (self->src_canvas, self->conf_event); + + g_object_unref (self->sci); + + G_OBJECT_CLASS (overview_scintilla_parent_class)->finalize (object); +} + +static inline void +cairo_set_source_overlay_color_ (cairo_t *cr, + const OverviewColor *color) +{ + cairo_set_source_rgba (cr, color->red, color->green, color->blue, color->alpha); +} + +static inline void +overview_scintilla_draw_real (OverviewScintilla *self, + cairo_t *cr) +{ + if (! self->overlay_enabled) + return; + + GtkAllocation alloc; + + gtk_widget_get_allocation (GTK_WIDGET (self->canvas), &alloc); + + cairo_save (cr); + + cairo_set_line_width (cr, 1.0); + cairo_set_antialias (cr, CAIRO_ANTIALIAS_GOOD); + + if (self->overlay_inverted) + { + cairo_set_source_overlay_color_ (cr, &self->overlay_color); + cairo_rectangle (cr, + 0, + self->visible_rect.y, + alloc.width, + self->visible_rect.height); + cairo_fill (cr); + } + else + { + // draw a rectangle at the top and bottom to obscure the non-visible area + cairo_set_source_overlay_color_ (cr, &self->overlay_color); + cairo_rectangle (cr, 0, 0, alloc.width, self->visible_rect.y); + cairo_rectangle (cr, + 0, + self->visible_rect.y + self->visible_rect.height, + alloc.width, + alloc.height - (self->visible_rect.y + self->visible_rect.height)); + cairo_fill (cr); + } + + // draw a highlighting border at top and bottom of visible rect + cairo_set_source_overlay_color_ (cr, &self->overlay_outline_color); + cairo_move_to (cr, self->visible_rect.x + 0.5, self->visible_rect.y + 0.5); + cairo_line_to (cr, self->visible_rect.width, self->visible_rect.y + 0.5); + cairo_move_to (cr, self->visible_rect.x + 0.5, self->visible_rect.y + 0.5 + self->visible_rect.height); + cairo_line_to (cr, self->visible_rect.width, self->visible_rect.y + 0.5 + self->visible_rect.height); + cairo_stroke (cr); + + // draw a left border if there's no scrollbar + if (! overview_scintilla_get_show_scrollbar (self)) + { + cairo_move_to (cr, 0.5, 0.5); + cairo_line_to (cr, 0.5, alloc.height); + cairo_stroke (cr); + } + + cairo_restore (cr); +} + +#if GTK_CHECK_VERSION (3, 0, 0) +static gboolean +overview_scintilla_draw (GtkWidget *widget, + cairo_t *cr, + gpointer user_data) +{ + overview_scintilla_draw_real (OVERVIEW_SCINTILLA (user_data), cr); + return FALSE; +} +#else +static gboolean +overview_scintilla_expose_event (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + cairo_t *cr; + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + overview_scintilla_draw_real (OVERVIEW_SCINTILLA (user_data), cr); + cairo_destroy (cr); + return FALSE; +} +#endif + +static gboolean +on_focus_in_event (OverviewScintilla *self, + GdkEventFocus *event, + ScintillaObject *sci) +{ + sci_send (self, SETREADONLY, 1, 0); + return TRUE; +} + +static gboolean +on_focus_out_event (OverviewScintilla *self, + GdkEventFocus *event, + ScintillaObject *sci) +{ + GeanyDocument *doc = g_object_get_data (G_OBJECT (sci), "document"); + if (DOC_VALID (doc)) + sci_send (self, SETREADONLY, doc->readonly, 0); + else + sci_send (self, SETREADONLY, 0, 0); + return TRUE; +} + +static gboolean +on_enter_notify_event (OverviewScintilla *self, + GdkEventCrossing *event, + ScintillaObject *sci) +{ + return TRUE; +} + +static gboolean +on_leave_notify_event (OverviewScintilla *self, + GdkEventCrossing *event, + ScintillaObject *sci) +{ + return TRUE; +} + +static void +on_each_child (GtkWidget *child, + GList **list) +{ + *list = g_list_prepend (*list, child); +} + +static GList * +gtk_container_get_internal_children_ (GtkContainer *cont) +{ + GList *list = NULL; + gtk_container_forall (cont, (GtkCallback) on_each_child, &list); + return g_list_reverse (list); +} + +static GtkWidget * +overview_scintilla_find_drawing_area (GtkWidget *root) +{ + GtkWidget *da = NULL; + if (GTK_IS_DRAWING_AREA (root)) + da = root; + else if (GTK_IS_CONTAINER (root)) + { + GList *children = gtk_container_get_internal_children_ (GTK_CONTAINER (root)); + for (GList *iter = children; iter != NULL; iter = g_list_next (iter)) + { + GtkWidget *wid = overview_scintilla_find_drawing_area (iter->data); + if (GTK_IS_DRAWING_AREA (wid)) + { + da = wid; + break; + } + } + g_list_free (children); + } + return da; +} + +static gboolean +on_scroll_event (OverviewScintilla *self, + GdkEventScroll *event, + GtkWidget *widget) +{ + gint delta = 0; + + if (self->scroll_lines == 0) + return TRUE; + + if (event->direction == GDK_SCROLL_UP) + delta = -(self->scroll_lines); + else if (event->direction == GDK_SCROLL_DOWN) + delta = self->scroll_lines; + + if (delta != 0) + sci_send (self->sci, LINESCROLL, 0, delta); + + return TRUE; +} + +static void +overview_scintilla_goto_point (OverviewScintilla *self, + gint x, + gint y) +{ + gint pos; + pos = sci_send (self, POSITIONFROMPOINT, x, y); + if (pos >= 0) + sci_send (self->sci, GOTOPOS, pos, 0); +} + +static void +overview_scintilla_update_cursor (OverviewScintilla *self) +{ + if (GTK_IS_WIDGET (self->canvas) && gtk_widget_get_mapped (self->canvas)) + { + GdkCursor *cursor = gdk_cursor_new (self->active_cursor); + gdk_window_set_cursor (gtk_widget_get_window (self->canvas), cursor); + gdk_cursor_unref (cursor); + } +} + +static gboolean +on_button_press_event (OverviewScintilla *self, + GdkEventButton *event, + GtkWidget *widget) +{ + self->mouse_down = TRUE; + self->active_cursor = OVERVIEW_SCINTILLA_CURSOR_CLICK; + overview_scintilla_update_cursor (self); + return TRUE; +} + +static gboolean +on_button_release_event (OverviewScintilla *self, + GdkEventButton *event, + GtkWidget *widget) +{ + self->mouse_down = FALSE; + self->active_cursor = OVERVIEW_SCINTILLA_CURSOR; + overview_scintilla_update_cursor (self); + overview_scintilla_goto_point (self, event->x, event->y); + return TRUE; +} + +static gboolean +on_motion_notify_event (OverviewScintilla *self, + GdkEventMotion *event, + GtkWidget *widget) +{ + if (self->mouse_down) + { + if (self->active_cursor != OVERVIEW_SCINTILLA_CURSOR_SCROLL) + { + self->active_cursor = OVERVIEW_SCINTILLA_CURSOR_SCROLL; + overview_scintilla_update_cursor (self); + } + overview_scintilla_goto_point (self, event->x, event->y); + } + return TRUE; +} + +static gboolean +overview_scintilla_setup_tooltip (OverviewScintilla *self, + gint x, + gint y, + GtkTooltip *tooltip) +{ + gint pos; + + if (!self->show_tooltip) + return FALSE; + + pos = sci_send (self, POSITIONFROMPOINT, x, y); + if (pos >= 0) + { + gint line = sci_send (self, LINEFROMPOSITION, pos, 0); + gint column = sci_send (self, GETCOLUMN, pos, 0); + gchar *text = + g_strdup_printf (_("Line <b>%d</b>, Column <b>%d</b>, Position <b>%d</b>"), + line, column, pos); + gtk_tooltip_set_markup (tooltip, text); + g_free (text); + } + else + gtk_tooltip_set_text (tooltip, NULL); + + return TRUE; +} + +static gboolean +on_query_tooltip (OverviewScintilla *self, + gint x, + gint y, + gboolean kbd_mode, + GtkTooltip *tooltip, + GtkWidget *widget) +{ + if (!kbd_mode) + return overview_scintilla_setup_tooltip (self, x, y, tooltip); + return FALSE; +} + +static void +overview_scintilla_setup_canvas (OverviewScintilla *self) +{ + if (!GTK_IS_WIDGET (self->canvas)) + { + self->canvas = overview_scintilla_find_drawing_area (GTK_WIDGET (self)); + + gtk_widget_add_events (self->canvas, + GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_SCROLL_MASK); + + g_signal_connect_swapped (self->canvas, + "scroll-event", + G_CALLBACK (on_scroll_event), + self); + g_signal_connect_swapped (self->canvas, + "button-press-event", + G_CALLBACK (on_button_press_event), + self); + g_signal_connect_swapped (self->canvas, + "button-release-event", + G_CALLBACK (on_button_release_event), + self); + g_signal_connect_swapped (self->canvas, + "motion-notify-event", + G_CALLBACK (on_motion_notify_event), + self); + g_signal_connect_swapped (self->canvas, + "query-tooltip", + G_CALLBACK (on_query_tooltip), + self); + + gtk_widget_set_has_tooltip (self->canvas, self->show_tooltip); + +#if GTK_CHECK_VERSION (3, 0, 0) + g_signal_connect_after (self->canvas, + "draw", + G_CALLBACK (overview_scintilla_draw), + self); +#else + g_signal_connect_after (self->canvas, + "expose-event", + G_CALLBACK (overview_scintilla_expose_event), + self); +#endif + + } +} + +static void +overview_scintilla_update_rect (OverviewScintilla *self) +{ + GtkAllocation alloc; + GdkRectangle rect; + gint first_line, n_lines, last_line; + gint pos_start, pos_end; + gint ystart, yend; + + gtk_widget_get_allocation (GTK_WIDGET (self), &alloc); + + first_line = sci_send (self->sci, GETFIRSTVISIBLELINE, 0, 0); + n_lines = sci_send (self->sci, LINESONSCREEN, 0, 0); + last_line = first_line + n_lines; + + pos_start = sci_send (self, POSITIONFROMLINE, first_line, 0); + pos_end = sci_send (self, POSITIONFROMLINE, last_line, 0); + + ystart = sci_send (self, POINTYFROMPOSITION, 0, pos_start); + yend = sci_send (self, POINTYFROMPOSITION, 0, pos_end); + + if (yend >= alloc.height || yend == 0) + { + n_lines = sci_send (self, GETLINECOUNT, 0, 0); + last_line = n_lines - 1; + pos_end = sci_send (self, POSITIONFROMLINE, last_line, 0); + yend = sci_send (self, POINTYFROMPOSITION, 0, pos_end); + } + + rect.x = 0; + rect.width = alloc.width - 1; + rect.y = ystart; + rect.height = yend - ystart; + + overview_scintilla_set_visible_rect (self, &rect); +} + +static gint +sci_get_midline_ (gpointer sci) +{ + gint first, count; + first = sci_send (sci, GETFIRSTVISIBLELINE, 0, 0); + count = sci_send (sci, LINESONSCREEN, 0, 0); + return first + (count / 2); +} + +static void +overview_scintilla_sync_center (OverviewScintilla *self) +{ + gint mid_src = sci_get_midline_ (self->sci); + gint mid_dst = sci_get_midline_ (self); + gint delta = mid_src - mid_dst; + sci_send (self, LINESCROLL, 0, delta); + overview_scintilla_update_rect (self); +} + +static gboolean +on_map_event (OverviewScintilla *self, + GdkEventAny *event, + ScintillaObject *sci) +{ + overview_scintilla_setup_canvas (self); + + if (GTK_IS_WIDGET (self->canvas) && + gtk_widget_get_double_buffered (self->canvas) != self->double_buffered) + { + gtk_widget_set_double_buffered (self->canvas, self->double_buffered); + self->double_buffered = gtk_widget_get_double_buffered (self->canvas); + } + + overview_scintilla_update_cursor (self); + overview_scintilla_update_rect (self); + + return FALSE; +} + +#define self_connect(name, cb) \ + g_signal_connect_swapped (self, name, G_CALLBACK (cb), self) + +static void +overview_scintilla_init (OverviewScintilla *self) +{ + self->sci = NULL; + self->canvas = NULL; + self->cursor = OVERVIEW_SCINTILLA_CURSOR; + self->active_cursor = OVERVIEW_SCINTILLA_CURSOR; + self->update_rect = 0; + self->conf_event = 0; + self->src_canvas = NULL; + self->width = OVERVIEW_SCINTILLA_WIDTH_DEF; + self->zoom = OVERVIEW_SCINTILLA_ZOOM_DEF; + self->mouse_down = FALSE; + self->show_tooltip = TRUE; + self->double_buffered = TRUE; + self->scroll_lines = OVERVIEW_SCINTILLA_SCROLL_LINES; + self->show_scrollbar = TRUE; + self->overlay_inverted = TRUE; + + memset (&self->visible_rect, 0, sizeof (GdkRectangle)); + memcpy (&self->overlay_color, &def_overlay_color, sizeof (OverviewColor)); + memcpy (&self->overlay_outline_color, &def_overlay_outline_color, sizeof (OverviewColor)); + + gtk_widget_add_events (GTK_WIDGET (self), + GDK_EXPOSURE_MASK | + GDK_FOCUS_CHANGE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_STRUCTURE_MASK); + + self_connect ("focus-in-event", on_focus_in_event); + self_connect ("focus-out-event", on_focus_out_event); + self_connect ("enter-notify-event", on_enter_notify_event); + self_connect ("leave-notify-event", on_leave_notify_event); + self_connect ("map-event", on_map_event); +} + +static void +overview_scintilla_set_property (GObject *object, + guint prop_id, + const GValue *value, + @@ Diff output truncated at 100000 characters. @@
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).