[gnome-calculator] GCi: new library for Controllers for Widgets using GCalc
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator] GCi: new library for Controllers for Widgets using GCalc
- Date: Fri, 18 Oct 2019 00:09:29 +0000 (UTC)
commit 08f2c7c44a70572e46ba2827bcc65b1516cdb8db
Author: Daniel Espinosa <esodan gmail com>
Date: Thu Oct 17 18:35:29 2019 -0500
GCi: new library for Controllers for Widgets using GCalc
Setups a new library GCi, it will provide
a set of widgets using GCalc.
Initial new Gci.EntryController, as a controller
for Gtk.Entry widgets intenting to response
when an user input a math expression text and
it is substituded by its evaluation
doc/meson.build | 27 +++++++
gcalc/meson.build | 2 +-
gci/gci-entry-controller.vala | 84 ++++++++++++++++++++++
gci/gci.deps.in | 2 +
gci/gci.pc.in | 13 ++++
gci/meson.build | 116 ++++++++++++++++++++++++++++++
gci/namespace-info.vala.in | 24 +++++++
meson.build | 1 +
tests/gci-test-entry-controller.ui | 59 +++++++++++++++
tests/meson.build | 23 ++++++
tests/test-entry-controller.gresource.xml | 6 ++
tests/test-gci-entry-controller.vala | 74 +++++++++++++++++++
12 files changed, 430 insertions(+), 1 deletion(-)
---
diff --git a/doc/meson.build b/doc/meson.build
index 8cfb4dae..d1f98d4b 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -28,4 +28,31 @@ if valadoc.found()
install_dir : docsdir,
depends: libgcalc
)
+ gtkdoc_outdir = GCI_CAMEL_CASE_NAME+'-'+GCI_API_VERSION
+ docsdir = join_paths (get_option ('datadir'), 'devhelp','books')
+
+ custom_target ('libgci_valadocs',
+ input : gci_sources,
+ output : GCI_CAMEL_CASE_NAME+'-'+GCI_API_VERSION,
+ command : [valadoc,
+ '--doclet=devhelp',
+ '--force',
+ '--fatal-warnings',
+ '--package-name='+GCI_CAMEL_CASE_NAME+'-'+GCI_API_VERSION,
+ '--package-version='+meson.project_version(),
+ '--vapidir='+gcalc_build_dir,
+ '--vapidir='+gci_build_dir,
+ '--pkg=glib-2.0',
+ '--pkg=gio-2.0',
+ '--pkg=gee-0.8',
+ '--vapidir='+vapis_dir,
+ '--pkg=gcalc-'+API_VERSION,
+ '--pkg=gtk+-3.0',
+ '--directory=@OUTDIR@',
+ '@INPUT@'
+ ],
+ install : true,
+ install_dir : docsdir,
+ depends: libgcalc
+ )
endif
diff --git a/gcalc/meson.build b/gcalc/meson.build
index e0694127..1bb573c9 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -178,7 +178,7 @@ libgcalc = library(VERSIONED_PROJECT_NAME,
if not get_option('disable-introspection')
g_ir_compiler = find_program('g-ir-compiler', required: false)
if g_ir_compiler.found()
-custom_target('typelib',
+custom_target('gcalc-typelib',
command: [
g_ir_compiler,
'--shared-library', 'lib'+PROJECT_NAME+'-@0@.so'.format (API_VERSION),
diff --git a/gci/gci-entry-controller.vala b/gci/gci-entry-controller.vala
new file mode 100644
index 00000000..3824def2
--- /dev/null
+++ b/gci/gci-entry-controller.vala
@@ -0,0 +1,84 @@
+/* gcalc-entry-controler.vala
+ *
+ * Copyright (C) 2019 Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Daniel Espinosa <esodan gmail com>
+ */
+/**
+ * A {@link Gtk.Entry} controler to provide calculator services
+ *
+ * Setup a {@link Gtk.Entry} to response when the user hits the
+ * enter key or click the secondary icon, to evaluate the math
+ * expression and substitude the result as the new content text
+ * of the {@link Gtk.Entry}.
+ *
+ * The math expression should start with the equal sign "=", in
+ * order to execute the math expression evaluation.
+ *
+ * If the expression is not a valid one, like using undefined
+ * variables, the new text is empty.
+ */
+public class GCi.EntryController : Object {
+ Gtk.Entry _entry;
+ public Gtk.Entry entry {
+ get {
+ return _entry;
+ }
+ set {
+ _entry = value;
+ setup ();
+ }
+ }
+ public EntryController.for_entry (Gtk.Entry entry) {
+ this.entry = entry;
+ setup ();
+ }
+ internal void setup () {
+ if (entry == null) {
+ warning (_("No entry was set"));
+ }
+ entry.secondary_icon_name = "accessories-calculator";
+ entry.secondary_icon_activatable = true;
+ entry.secondary_icon_sensitive = true;
+ entry.activate.connect (()=>{
+ if (!entry.text.has_prefix ("=")) {
+ return;
+ }
+ calculate ();
+ });
+ entry.icon_press.connect ((pos, ev)=>{
+ if (!entry.text.has_prefix ("=")) {
+ return;
+ }
+ calculate ();
+ });
+ }
+
+ internal void calculate () {
+ var s = new GCalc.Solver ();
+ string str = entry.text.replace ("=", "");
+ try {
+ var r = s.solve (str);
+ if (r is GCalc.MathResult) {
+ entry.text = r.expression.to_string ();
+ }
+ } catch (GLib.Error e) {
+ warning (_("Math Expression evaluation error: %s"), e.message);
+ }
+ }
+}
+
diff --git a/gci/gci.deps.in b/gci/gci.deps.in
new file mode 100644
index 00000000..5adb695e
--- /dev/null
+++ b/gci/gci.deps.in
@@ -0,0 +1,2 @@
+gcalc-2
+gtk+-3.0
diff --git a/gci/gci.pc.in b/gci/gci.pc.in
new file mode 100644
index 00000000..15e94644
--- /dev/null
+++ b/gci/gci.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=@libdir@
+datadir=@prefix@/share
+includedir=@prefix@/include
+
+Name: libgcalc
+Description: GNOME Calculator Libray GTK Interface
+URL: http://live.gnome.org/
+Version: @PROJECT_VERSION@
+Requires: gcalc-2 >= 3.34 gtk+-3.0 > 3.19.3
+Libs: -L${libdir} -lgci-@API_VERSION@
+Cflags: -I${includedir}/gci-@API_VERSION@
diff --git a/gci/meson.build b/gci/meson.build
new file mode 100644
index 00000000..f20b431e
--- /dev/null
+++ b/gci/meson.build
@@ -0,0 +1,116 @@
+GCI_PROJECT_NAME='gci'
+GCI_API_VERSION='1'
+GCI_VERSIONED_PROJECT_NAME=GCI_PROJECT_NAME+'-'+GCI_API_VERSION
+GCI_CAMEL_CASE_NAME='GCi'
+GCI_VERSIONED_CAMEL_CASE_NAME=GCI_CAMEL_CASE_NAME+'-'+GCI_API_VERSION
+GCI_GIR_NAME= GCI_VERSIONED_CAMEL_CASE_NAME+'.gir'
+GCI_TYPELIB_NAME= GCI_VERSIONED_CAMEL_CASE_NAME+'.typelib'
+GCI_VAPI_NAME = GCI_VERSIONED_PROJECT_NAME+'.vapi'
+
+conf = configuration_data()
+conf.set('prefix', get_option('prefix'))
+conf.set('libdir', '${exec_prefix}/'+get_option ('libdir'))
+conf.set('PROJECT_NAME', GCI_PROJECT_NAME)
+conf.set('PROJECT_VERSION', meson.project_version ())
+conf.set('API_VERSION', GCI_API_VERSION)
+
+configure_file(input : 'gci.pc.in',
+ output : 'gci-@0@.pc'.format(GCI_API_VERSION),
+ configuration : conf,
+ install : true,
+ install_dir : join_paths(get_option('libdir'), 'pkgconfig'))
+
+configure_file(input : 'gci.deps.in',
+ output : 'gci-@0@.deps'.format(GCI_API_VERSION),
+ configuration : conf,
+ install : true,
+ install_dir : vapidir)
+
+gci_nsinfo = configure_file(input : 'namespace-info.vala.in',
+ output : 'namespace-info.vala',
+ configuration : conf)
+gci_namespaceinfo_dep = declare_dependency (sources : gci_nsinfo)
+
+gci_confh = configuration_data ()
+gci_confh.set_quoted('PACKAGE_LOCALE_DIR', join_paths(get_option('prefix'), get_option('datadir'), 'locale'))
+gci_confh.set_quoted('GETTEXT_PACKAGE', 'GCalc')
+configure_file(output : 'config.h',
+ configuration : gci_confh)
+
+
+gci_sources = files([
+ 'gci-entry-controller.vala'
+])
+
+
+gci_inc_libh = include_directories ('.')
+gci_inc_libh_dep = declare_dependency (include_directories : gci_inc_libh)
+gci_build_dir = meson.current_build_dir ()
+gci_sources_dir = meson.current_source_dir ()
+
+gci_deps = [
+ gio,
+ gci_namespaceinfo_dep,
+ inc_libh_dep,
+ inc_rooth_dep,
+ gci_inc_libh_dep,
+ gee,
+ gtk
+]
+
+# LT_VERSION for ABI related changes
+# From: https://autotools.io/libtool/version.html
+# This rules applies to Meson 0.43
+# Increase the current value whenever an interface has been added, removed or changed.
+# Always increase revision value whenever an interface has been added, removed or changed.
+# Increase the age value only if the changes made to the ABI are backward compatible.
+# Set version to the value of subtract age from current
+# Reset current and version to 1 and, age and version to 0 if library's name is changed
+GCI_LT_CURRENT='0'
+GCI_LT_REVISION='0'
+GCI_LT_AGE='0'
+GCI_LT_VERSION='0'
+libgci = library(GCI_VERSIONED_PROJECT_NAME,
+ gci_sources,
+ version : GCI_LT_VERSION,
+ soversion : GCI_LT_VERSION+'.'+GCI_LT_AGE+'.'+GCI_LT_REVISION,
+ vala_header : GCI_PROJECT_NAME+'.h',
+ vala_vapi : GCI_VAPI_NAME,
+ vala_gir : GCI_GIR_NAME,
+ dependencies : gci_deps,
+ vala_args: [
+ '--use-header',
+ ],
+ c_args : [
+ '-include',
+ meson.current_build_dir() + '/config.h',
+ ],
+ link_with: [ libgcalc ],
+ install : true,
+ install_dir : [
+ true,
+ join_paths (get_option('includedir'), 'gci-@0@'.format (API_VERSION), 'gci'),
+ vapidir,
+ true
+ ])
+
+if not get_option('disable-introspection')
+if g_ir_compiler.found()
+custom_target('gci-typelib',
+ command: [
+ g_ir_compiler,
+ '--shared-library', 'lib'+GCI_PROJECT_NAME+'-@0@.so'.format (GCI_API_VERSION),
+ '--output', '@OUTPUT@',
+ join_paths(meson.current_build_dir(), GCI_GIR_NAME)
+ ],
+ output: GCI_TYPELIB_NAME,
+ depends: libgci,
+ install: true,
+ install_dir: join_paths(get_option('libdir'), 'girepository-1.0'))
+endif
+endif
+
+libgci_dep = declare_dependency(include_directories : gci_inc_libh,
+ link_with : libgci,
+ dependencies: gci_deps,
+ )
diff --git a/gci/namespace-info.vala.in b/gci/namespace-info.vala.in
new file mode 100644
index 00000000..e539779f
--- /dev/null
+++ b/gci/namespace-info.vala.in
@@ -0,0 +1,24 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/* Attr.vala
+ *
+ * Copyright (C) 2019 Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Daniel Espinosa <esodan gmail com>
+ */
+[CCode (gir_namespace = "GCi", gir_version = "@API_VERSION@", cheader_filename = "gci/@PROJECT_NAME@.h")]
+namespace GCi {}
diff --git a/meson.build b/meson.build
index 16d11c4a..7173794e 100644
--- a/meson.build
+++ b/meson.build
@@ -64,6 +64,7 @@ subdir('vapi')
subdir('gcalc')
if not get_option ('disable-ui')
gtk = dependency('gtk+-3.0', version: '>= 3.19.3')
+subdir('gci')
gtksourceview = dependency('gtksourceview-4', version: '>= 4.0.2')
subdir('data')
subdir('lib')
diff --git a/tests/gci-test-entry-controller.ui b/tests/gci-test-entry-controller.ui
new file mode 100644
index 00000000..4747c6aa
--- /dev/null
+++ b/tests/gci-test-entry-controller.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <template class="TestsWindow" parent="GtkApplicationWindow">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Testing GCi.EntryController</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">GCi Test</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">12</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button">
+ <property name="label" translatable="yes">Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="destructive-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/tests/meson.build b/tests/meson.build
index 24d1d3a3..b65bd9f4 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -49,6 +49,29 @@ test_serializer = executable('test-serializer', test_serializer_sources,
include_directories: gnome_calculator_tests_includes,
)
test('Serializer test', test_serializer)
+
+
+gci_test_deps = [
+ gee,
+ gtk,
+ inc_rooth_dep,
+ inc_libh_dep,
+ gci_inc_libh_dep
+]
+
+test_entry_controler_resource_files = files('test-entry-controller.gresource.xml')
+test_entry_controler_resources = gnome.compile_resources('test-entry-controller-resources',
test_entry_controler_resource_files)
+
+test_entry_controler_sources = [
+ 'test-gci-entry-controller.vala',
+]
+test_entry_controler_sources += test_entry_controler_resources
+
+test_entry_controler = executable('test-entry-controller', test_entry_controler_sources,
+ dependencies: gci_test_deps,
+ link_with: [libgci, libgcalc],
+)
+test('gci-entry-controller', test_entry_controler)
endif
tests_deps = [
diff --git a/tests/test-entry-controller.gresource.xml b/tests/test-entry-controller.gresource.xml
new file mode 100644
index 00000000..e8ca34da
--- /dev/null
+++ b/tests/test-entry-controller.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/Calculator">
+ <file preprocess="xml-stripblanks">gci-test-entry-controller.ui</file>
+ </gresource>
+</gresources>
diff --git a/tests/test-gci-entry-controller.vala b/tests/test-gci-entry-controller.vala
new file mode 100644
index 00000000..d42f605e
--- /dev/null
+++ b/tests/test-gci-entry-controller.vala
@@ -0,0 +1,74 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * GCalc Unit Tests
+ * Copyright (C) Daniel Espinosa Ortiz 2019 <esodan gmail com>
+ *
+ * libgda is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libgda 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+using GCalc;
+using GCi;
+
+class Tests {
+ [GtkTemplate (ui = "/org/gnome/Calculator/gci-test-entry-controller.ui")]
+ class Window : Gtk.ApplicationWindow {
+ [GtkChild]
+ Gtk.Entry entry;
+ [GtkChild]
+ Gtk.Button button;
+
+ GCi.EntryController controller;
+
+ construct {
+ controller = new GCi.EntryController ();
+ controller.entry = entry;
+ this.destroy.connect (()=>{
+ application.quit ();
+ });
+ GLib.Timeout.add (10000, ()=>{
+ application.quit ();
+ });
+ button.clicked.connect (()=>{
+ message ("Closing...");
+ application.quit ();
+ });
+ }
+
+ public Window (Gtk.Application app) {
+ Object(application: app);
+ }
+ }
+ class Application : Gtk.Application {
+ public Application () {
+ Object(application_id: "test.gci.entry.controler",
+ flags: ApplicationFlags.FLAGS_NONE);
+ }
+
+ protected override void activate () {
+ // Create the window of this application and show it
+ Gtk.ApplicationWindow w = new Window (this);
+ w.show_all ();
+ }
+ }
+ static int main (string[] args)
+ {
+ GLib.Intl.setlocale (GLib.LocaleCategory.ALL, "");
+ Test.init (ref args);
+ Test.add_func ("/gci/entry/controler",
+ ()=>{
+ var app = new Application ();
+ app.run ();
+ });
+ return Test.run ();
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]