[genius] Fri Sep 05 01:52:10 2014 Jiri (George) Lebl <jirka 5z com>



commit 1308ac19e1b4ddc8380c4901df132f923fc3ad9b
Author: Jiri (George) Lebl <jiri lebl gmail com>
Date:   Fri Sep 5 01:52:16 2014 -0500

    Fri Sep 05 01:52:10 2014  Jiri (George) Lebl <jirka 5z com>
    
        * tutors/*: add a simple strange-attractor tutorial
    
        * src/tutors.[ch], src/gnome-genius.c: add a tutorials menu
          to load same programs, Right now really simple, eventually should
          have submenus, and have to figure out translation

 ChangeLog                    |    8 ++
 Makefile.am                  |    2 +-
 configure.in                 |    1 +
 src/Makefile.am              |    2 +
 src/gnome-genius.c           |  121 ++++++++++++++++++++++------
 src/graphing.c               |    4 +
 src/tutors.c                 |  182 ++++++++++++++++++++++++++++++++++++++++++
 src/tutors.h                 |   34 ++++++++
 tutors/Makefile.am           |    6 ++
 tutors/strange-attractor.gel |   57 +++++++++++++
 10 files changed, 390 insertions(+), 27 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9b8073d..3aea396 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Fri Sep 05 01:52:10 2014  Jiri (George) Lebl <jirka 5z com>
+
+       * tutors/*: add a simple strange-attractor tutorial
+
+       * src/tutors.[ch], src/gnome-genius.c: add a tutorials menu
+         to load same programs, Right now really simple, eventually should
+         have submenus, and have to figure out translation
+
 Tue Sep 02 10:12:42 2014  Jiri (George) Lebl <jirka 5z com>
 
        * help/C/genius.xml: minor fixes
diff --git a/Makefile.am b/Makefile.am
index a5a8ee5..09b28e9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = ve gtkextra src pixmaps lib po help
+SUBDIRS = ve gtkextra src pixmaps tutors lib po help
 
 mimeinfodir = $(datadir)/mime-info
 mimeinfo_DATA = genius.keys genius.mime
diff --git a/configure.in b/configure.in
index 8370d0c..a63f53b 100644
--- a/configure.in
+++ b/configure.in
@@ -282,6 +282,7 @@ lib/symbolic/Makefile
 lib/commutative_algebra/Makefile
 ve/Makefile
 gtkextra/Makefile
+tutors/Makefile
 pixmaps/Makefile
 pixmaps/32x32/Makefile
 pixmaps/48x48/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 392546a..e33026b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -75,6 +75,8 @@ gnome_genius_SOURCES =        \
        parseutil.c     \
        inter.c         \
        inter.h         \
+       tutors.c        \
+       tutors.h        \
        plugin.c        \
        plugin.h        \
        plugread.c      \
diff --git a/src/gnome-genius.c b/src/gnome-genius.c
index b859164..882d4d0 100644
--- a/src/gnome-genius.c
+++ b/src/gnome-genius.c
@@ -47,6 +47,7 @@
 #include "graphing.h"
 
 #include "plugin.h"
+#include "tutors.h"
 #include "inter.h"
 
 #include "binreloc.h"
@@ -255,13 +256,15 @@ static void actually_open_help (const char *id);
 
 static void fork_helper_setup_comm (void);
 
-static void new_program (const char *filename);
+static void new_program (const char *filename,
+                        gboolean tutor);
 
 static GtkActionEntry entries[] = {
   { "FileMenu", NULL, N_("_File") },           /* name, stock id, label */
   { "EditMenu", NULL, N_("_Edit") },           /* name, stock id, label */
   { "CalculatorMenu", NULL, N_("_Calculator") },       /* name, stock id, label */
   { "PluginsMenu", NULL, N_("P_lugins") },     /* name, stock id, label */
+  { "TutorialsMenu", NULL, N_("_Tutorials") }, /* name, stock id, label */
   { "ProgramsMenu", NULL, N_("_Programs") },   /* name, stock id, label */
   { "SettingsMenu", NULL, N_("_Settings") },   /* name, stock id, label */
   { "HelpMenu", NULL, N_("_Help") },           /* name, stock id, label */
@@ -418,6 +421,12 @@ static GtkActionEntry entries[] = {
     "No Plugins", "",
     "No Plugins",
     NULL },
+  /* Kind of a placeholder for empty menu,
+   * FIXME: probably a bad hack */
+  { "NoTutorial", NULL,
+    "No Tutorials", "",
+    "No Tutorials",
+    NULL },
 };
 static guint n_entries = G_N_ELEMENTS (entries);
 
@@ -465,6 +474,9 @@ static const gchar *ui_info =
 "      <separator/>"
 "      <menuitem action='Plot'/>"
 "    </menu>"
+"    <menu action='TutorialsMenu'>"
+"      <menuitem action='NoTutorial'/>"
+"    </menu>"
 "    <menu action='PluginsMenu'>"
 "      <menuitem action='NoPlugin'/>"
 "    </menu>"
@@ -554,7 +566,6 @@ simple_menu_item_select_cb (GtkMenuItem *item, gpointer data)
        if (message) {
                gtk_statusbar_push (GTK_STATUSBAR (genius_window_statusbar), 0 /* context */,
                                    message);
-               g_free (message);
        }
 }
 
@@ -648,7 +659,7 @@ file_open_recent (GtkRecentChooser *chooser, gpointer data)
 
         uri = gtk_recent_info_get_uri (item);
 
-       new_program (uri);
+       new_program (uri, FALSE);
 
         gtk_recent_info_unref (item);
 }
@@ -3439,9 +3450,11 @@ file_is_writable (const char *fname)
 
 
 
+/* if tutor, filename is a filename and not a uri */
 static void
-new_program (const char *filename)
+new_program (const char *filename, gboolean tutor)
 {
+       char *contents;
        static int cnt = 1;
        GtkWidget *tv;
        GtkWidget *sw;
@@ -3542,7 +3555,7 @@ new_program (const char *filename)
                                G_CALLBACK (move_cursor),
                                p);
 
-       if (filename == NULL) {
+       if (filename == NULL || tutor) {
                GFile* file;
                char *d = g_get_current_dir ();
                char *n = g_strdup_printf (_("Program_%d.gel"), cnt);
@@ -3559,7 +3572,6 @@ new_program (const char *filename)
                p->vname = g_strdup_printf (_("Program %d"), cnt);
                cnt++;
        } else {
-               char *contents;
                recent_add (filename);
                p->name = g_strdup (filename);
                if (file_exists (filename)) { 
@@ -3569,31 +3581,40 @@ new_program (const char *filename)
                        p->readonly = FALSE;
                        contents = g_strdup ("");
                }
-               if (contents != NULL &&
-                   g_utf8_validate (contents, -1, NULL)) {
-                       GtkTextIter iter;
+               p->vname = g_path_get_basename (p->name);
+               p->real_file = TRUE;
+       }
+
+       if (tutor && filename != NULL) {
+               contents = NULL;
+               g_file_get_contents (filename, &contents, NULL, NULL);
+       }
+
+       if (contents != NULL &&
+           g_utf8_validate (contents, -1, NULL)) {
+               GtkTextIter iter;
 #ifdef HAVE_GTKSOURCEVIEW
-                       gtk_source_buffer_begin_not_undoable_action
-                               (GTK_SOURCE_BUFFER (buffer));
+               gtk_source_buffer_begin_not_undoable_action
+                       (GTK_SOURCE_BUFFER (buffer));
 #endif
-                       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
-                       gtk_text_buffer_insert_with_tags_by_name
-                               (buffer, &iter, contents, -1, "foo", NULL);
+               gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+               gtk_text_buffer_insert_with_tags_by_name
+                       (buffer, &iter, contents, -1, "foo", NULL);
 #ifdef HAVE_GTKSOURCEVIEW
-                       gtk_source_buffer_end_not_undoable_action
-                               (GTK_SOURCE_BUFFER (buffer));
+               gtk_source_buffer_end_not_undoable_action
+                       (GTK_SOURCE_BUFFER (buffer));
 #endif
-                       g_free (contents);
-               } else {
+               g_free (contents);
+       } else {
+               if (filename != NULL && ! tutor) {
                        char *s = g_strdup_printf (_("Cannot open %s"), filename);
                        genius_display_error (NULL, s);
                        g_free (s);
-                       if (contents != NULL)
-                               g_free (contents);
                }
-               p->vname = g_path_get_basename (p->name);
-               p->real_file = TRUE;
+               if (contents != NULL)
+                       g_free (contents);
        }
+
        /* the label will change after the set_current_page */
        p->label = gtk_label_new (p->vname);
        p->mlabel = gtk_label_new (p->vname);
@@ -3635,7 +3656,7 @@ new_program (const char *filename)
 static void
 new_callback (GtkWidget *menu_item, gpointer data)
 {
-       new_program (NULL);
+       new_program (NULL, FALSE);
 }
 
 static void
@@ -3658,7 +3679,7 @@ really_open_cb (GtkFileChooser *fs, int response, gpointer data)
        g_free (last_dir);
        last_dir = gtk_file_chooser_get_current_folder (fs);
 
-       new_program (s);
+       new_program (s, FALSE);
 
        gtk_widget_destroy (GTK_WIDGET (fs));
 }
@@ -4543,6 +4564,12 @@ catch_interrupts (GtkWidget *w, GdkEvent *e)
 }
 
 static void
+open_tutor_cb (GtkWidget *w, GelTutorial * tut)
+{
+       new_program (tut->file, TRUE);
+}
+
+static void
 open_plugin_cb (GtkWidget *w, GelPlugin * plug)
 {
        gel_open_plugin (plug);
@@ -4897,7 +4924,7 @@ loadup_files_from_cmdline (int argc, char *argv[])
 
                g_object_unref (file);
 
-               new_program (uri);
+               new_program (uri, FALSE);
                
                g_free (uri);
        }
@@ -4918,7 +4945,7 @@ drag_data_received (GtkWidget *widget, GdkDragContext *context,
        uris = gtk_selection_data_get_uris (selection_data);
 
        for (uri = uris[i]; uri != NULL; i++, uri = uris[i]) {
-               new_program (uri);
+               new_program (uri, FALSE);
        }
        g_strfreev (uris);
 }
@@ -4965,6 +4992,7 @@ main (int argc, char *argv[])
        GtkWidget *w;
        char *file;
        int plugin_count = 0;
+       int tutor_count = 0;
        gboolean give_no_lib_error_after_init = FALSE;
 
        arg0 = g_strdup (argv[0]); 
@@ -5138,12 +5166,53 @@ main (int argc, char *argv[])
                          G_CALLBACK (update_term_geometry), NULL);
 
        gtk_widget_hide (gtk_ui_manager_get_widget (genius_ui, "/MenuBar/PluginsMenu"));
+       gtk_widget_hide (gtk_ui_manager_get_widget (genius_ui, "/MenuBar/TutorialsMenu"));
 
        /* Show the window now before going on with the
         * setup */
        gtk_widget_show_now (genius_window);
        check_events ();
 
+       gel_read_tutor_list ();
+
+       if (gel_tutor_list != NULL) {
+               GSList *li;
+               int i;
+               GtkWidget *menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (gtk_ui_manager_get_widget 
(genius_ui, "/MenuBar/TutorialsMenu")));
+
+               for (i = 0, li = gel_tutor_list;
+                    li != NULL;
+                    li = li->next, i++) {
+                       GtkWidget *item;
+                       GelTutorial *tut = li->data;
+                       char *s;
+
+                       s = g_strconcat (tut->category, ": ", tut->name, NULL);
+                       item = gtk_menu_item_new_with_label (s);
+                       g_free (s);
+
+                       g_signal_connect (item, "select",
+                                         G_CALLBACK (simple_menu_item_select_cb), 
+                                         tut->name);
+                       g_signal_connect (item, "deselect",
+                                         G_CALLBACK (simple_menu_item_deselect_cb), 
+                                         tut->name);
+                       gtk_widget_show (item);
+                       g_signal_connect (G_OBJECT (item), "activate",
+                                         G_CALLBACK (open_tutor_cb), tut);
+                       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+                       tutor_count ++;
+               }
+       }
+
+       /* if no tutorials, hide the menu */
+       if (tutor_count == 0) {
+               gtk_widget_hide (gtk_ui_manager_get_widget (genius_ui, "/MenuBar/TutorialsMenu"));
+       } else {
+               gtk_widget_show (gtk_ui_manager_get_widget (genius_ui, "/MenuBar/TutorialsMenu"));
+               gtk_widget_hide (gtk_ui_manager_get_widget (genius_ui, "/MenuBar/TutorialsMenu/NoTutorial"));
+       }
+
        gel_read_plugin_list ();
 
        if (gel_plugin_list != NULL) {
diff --git a/src/graphing.c b/src/graphing.c
index c0beba3..4e18100 100644
--- a/src/graphing.c
+++ b/src/graphing.c
@@ -2291,6 +2291,10 @@ ensure_window (gboolean do_window_present)
        gtk_widget_show_all (menubar);
 
        plot_canvas = gtk_plot_canvas_new (WIDTH, HEIGHT, 1.0);
+       g_signal_connect (G_OBJECT (plot_canvas),
+                         "destroy",
+                         G_CALLBACK (gtk_widget_destroyed),
+                         &plot_canvas);
        GTK_PLOT_CANVAS_UNSET_FLAGS (GTK_PLOT_CANVAS (plot_canvas),
                                     GTK_PLOT_CANVAS_DND_FLAGS);
        g_signal_connect (G_OBJECT (plot_canvas), "select_region",
diff --git a/src/tutors.c b/src/tutors.c
new file mode 100644
index 0000000..4075723
--- /dev/null
+++ b/src/tutors.c
@@ -0,0 +1,182 @@
+/* GENIUS Calculator
+ * Copyright (C) 1997-2014 Jiri (George) Lebl
+ *
+ * Author: Jiri (George) Lebl
+ *
+ * This file is part of Genius.
+ *
+ * Genius 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <signal.h>
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <readline/tilde.h>
+
+#include <vicious.h>
+
+#include "calc.h"
+#include "eval.h"
+#include "util.h"
+#include "dict.h"
+#include "compil.h"
+
+#include "mpwrap.h"
+
+#include "parse.h"
+
+#include "tutors.h"
+
+#include "binreloc.h"
+
+GSList *gel_tutor_list = NULL;
+
+static GHashTable *opened = NULL;
+static GHashTable *info = NULL;
+
+static GelTutorial *
+gel_readtutor (const char *dir_name, const char *file_name)
+{
+       char *f = g_build_filename (ve_sure_string (dir_name),
+                                   ve_sure_string (file_name), NULL);
+       FILE *fp;
+       char buf[512];
+       char *name;
+       char *cat;
+       char *s;
+       GelTutorial *tut = NULL;
+
+       fp = fopen (f, "r");
+
+       if (fp == NULL) {
+               g_free (f);
+               return NULL;
+       }
+
+       if (fgets (buf, sizeof (buf), fp) == NULL) {
+               g_free (f);
+               fclose (fp);
+               return NULL;
+       }
+
+       s = strchr (buf, ':');
+       if (s != NULL) {
+               cat = g_strdup (g_strstrip(s+1));
+       } else {
+               g_free (f);
+               fclose (fp);
+               return NULL;
+       }
+
+       if (fgets (buf, sizeof (buf), fp) == NULL) {
+               g_free (f);
+               g_free (cat);
+               fclose (fp);
+               return NULL;
+       }
+
+       s = strchr (buf, ':');
+       if (s != NULL) {
+               name = g_strdup (g_strstrip (s+1));
+       } else {
+               g_free (f);
+               g_free (cat);
+               fclose (fp);
+               return NULL;
+       }
+
+       fclose (fp);
+
+       tut = g_new (GelTutorial, 1);
+       tut->category = cat;
+       tut->name = name;
+       tut->file = f;
+
+       return tut;
+}
+
+static void
+free_tutor(GelTutorial *tut)
+{
+       g_free (tut->category);
+       g_free (tut->name);
+       g_free (tut->file);
+       g_free (tut);
+}
+
+static void
+read_tutors_from_dir (const char *dir_name)
+{
+       DIR *dir;
+       struct dirent *dent;
+
+       dir = opendir (dir_name);
+       if (dir == NULL) {
+               return;
+       }
+       while((dent = readdir (dir)) != NULL) {
+               char *p;
+               GelTutorial *tut;
+               if(dent->d_name[0] == '.' &&
+                  (dent->d_name[1] == '\0' ||
+                   (dent->d_name[1] == '.' &&
+                    dent->d_name[2] == '\0')))
+                       continue;
+               p = strrchr(dent->d_name,'.');
+               if(!p || strcmp(p,".gel")!=0)
+                       continue;
+               tut = gel_readtutor (dir_name, dent->d_name);
+               if (tut != NULL) {
+                       gel_tutor_list = g_slist_prepend (gel_tutor_list, tut);
+               }
+       }
+       closedir (dir);
+}
+
+void
+gel_read_tutor_list (void)
+{
+       char *dir_name;
+       char *datadir;
+
+       /*free the previous list*/
+       g_slist_foreach (gel_tutor_list, (GFunc)free_tutor, NULL);
+       g_slist_free (gel_tutor_list);
+       gel_tutor_list = NULL;
+       
+       datadir = gbr_find_data_dir (DATADIR);
+       dir_name = g_build_filename (datadir, "genius", "tutors", NULL);
+       g_free (datadir);
+       read_tutors_from_dir (dir_name);
+       g_free (dir_name);
+
+       dir_name = g_build_filename (g_get_home_dir (),
+                                    ".genius", "tutors", NULL);
+       read_tutors_from_dir (dir_name);
+       g_free (dir_name);
+
+       /* FIXME: should do more */
+       gel_tutor_list = g_slist_reverse (gel_tutor_list);
+}
diff --git a/src/tutors.h b/src/tutors.h
new file mode 100644
index 0000000..f7b15ca
--- /dev/null
+++ b/src/tutors.h
@@ -0,0 +1,34 @@
+/* GENIUS Calculator
+ * Copyright (C) 1997-2014 Jiri (George) Lebl
+ *
+ * Author: Jiri (George) Lebl
+ *
+ * This file is part of Genius.
+ *
+ * Genius 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TUTOR_H__
+#define TUTOR_H__
+
+typedef struct _GelTutorial {
+       char *category;
+       char *name;
+       char *file;
+} GelTutorial;
+
+void gel_read_tutor_list(void);
+extern GSList *gel_tutor_list;
+
+#endif /* PLUGIN_H__ */
diff --git a/tutors/Makefile.am b/tutors/Makefile.am
new file mode 100644
index 0000000..4fbcf63
--- /dev/null
+++ b/tutors/Makefile.am
@@ -0,0 +1,6 @@
+tutordir = \
+       $(datadir)/genius/tutors/
+tutor_DATA = \
+       strange-attractor.gel
+EXTRA_DIST = \
+       $(tutor_DATA)
diff --git a/tutors/strange-attractor.gel b/tutors/strange-attractor.gel
new file mode 100644
index 0000000..248508d
--- /dev/null
+++ b/tutors/strange-attractor.gel
@@ -0,0 +1,57 @@
+# Category: Differential Equations
+# Name: Strange Attractor (Duffing's equation)
+#
+# Creates a strange attractor by strobing the forced Duffing
+# equation
+#
+
+# The Duffing equation (converted to an ODE system)
+# x_1' = x_2, x_2' = -0.05x_2 - x_1^3 + 7.5cos(t)
+#
+function duf(t,x) = [x@(2),-0.05*x@(2)-(x@(1))^3+7.5*cos(t)];
+
+# Strobe period
+strobe = 2*pi;
+
+# Initial time
+t = 0.0;
+
+# Steps to use in RungeKutta for each strobe
+steps = 25;
+
+# Number of points to compute
+ptnum = 5000;
+
+#initial position
+x = [0.0,0.0];
+
+LinePlotDrawLegends = false;
+
+points = null;
+
+k = 1;
+for j=1 to ptnum do (
+  x = RungeKutta(duf,t,x,t+strobe,steps);
+  t = t+strobe;
+
+  # only plot points from the 100th on
+  if (j > 100) then (
+    points@(k,) = x;
+    increment k;
+
+    # every 500 point display intermediate picture
+    if j % 500 == 0 then (
+      DisplayVariables(`j);
+      PlotCanvasFreeze ();
+      LinePlotClear ();
+      LinePlotDrawPoints (points, "color", "blue", "window", "fit");
+      PlotCanvasThaw ();
+    )
+  )
+);
+
+# Display final picture
+PlotCanvasFreeze ();
+LinePlotClear ();
+LinePlotDrawPoints (points, "color", "blue", "window", "fit");
+PlotCanvasThaw ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]