Finally, a version I'm proud of. :)
authorChip Black <bytex64@bytex64.net>
Sat, 30 May 2009 09:34:21 +0000 (04:34 -0500)
committerChip Black <bytex64@bytex64.net>
Sat, 30 May 2009 09:34:21 +0000 (04:34 -0500)
12 files changed:
Makefile [new file with mode: 0644]
WebThing [new file with mode: 0755]
WebThing.cs [new file with mode: 0644]
main.cs [new file with mode: 0644]
plugins.conf [new file with mode: 0644]
plugins/DefaultPage.cs [new file with mode: 0644]
plugins/LoadProgress.cs [new file with mode: 0644]
plugins/Makefile [new file with mode: 0644]
plugins/SoupSettings/Makefile [new file with mode: 0644]
plugins/SoupSettings/SoupSettings.c [new file with mode: 0644]
plugins/SoupSettings/SoupSettings.cs [new file with mode: 0644]
plugins/Vimish.cs [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..1ac11b5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+CSFLAGS = -debug
+references = -r:webkit-sharp.dll -pkg:gtk-sharp-2.0
+
+all: main.exe plugins
+
+main.exe: main.cs WebThing.dll
+       gmcs $(CSFLAGS) -r:WebThing.dll main.cs
+
+WebThing.dll: WebThing.cs
+       gmcs $(CSFLAGS) $(references) -target:library -out:$@ $<
+
+plugins:
+       make -C plugins
+
+.PHONY: plugins
diff --git a/WebThing b/WebThing
new file mode 100755 (executable)
index 0000000..7d14c4b
--- /dev/null
+++ b/WebThing
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+export LD_LIBRARY_PATH=plugins:$LD_LIBRARY_PATH
+
+echo $LD_LIBRARY_PATH
+
+exec mono main.exe
diff --git a/WebThing.cs b/WebThing.cs
new file mode 100644 (file)
index 0000000..04ede67
--- /dev/null
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.IO;
+using Gtk;
+using GtkSharp;
+using WebKit;
+
+namespace bytex64.WebThing {
+       public enum CompassDirection {
+               N, NE, E, SE, S, SW, W, NW,
+               Interior
+       }
+
+       public class WebThing {
+               public Gtk.Window Window {
+                       get { return _Window; }
+               }
+
+               public Gtk.Window w {
+                       get { return _Window; }
+               }
+
+               public Gtk.ScrolledWindow ScrolledWindow {
+                       get { return _ScrolledWindow; }
+               }
+
+               public Gtk.ScrolledWindow sw {
+                       get { return _ScrolledWindow; }
+               }
+
+               public WebKit.WebView WebView {
+                       get { return _WebView; }
+               }
+
+               public WebKit.WebView wv {
+                       get { return _WebView; }
+               }
+
+               private Gtk.Window _Window;
+               private ScrolledWindow _ScrolledWindow;
+               private WebKit.WebView _WebView;
+               private Gtk.Table WidgetGrid;
+               private Gtk.Alignment InteriorOverlay;
+
+               public Dictionary<string,object> Plugins;
+
+               public void Run() {
+                       Application.Init();
+                       _Window = new Gtk.Window("WebThing");
+                       _Window.Destroyed += delegate { Application.Quit(); };
+
+                       WidgetGrid = new Gtk.Table(3, 3, false);
+                       _Window.Add(WidgetGrid);
+
+                       _ScrolledWindow = new Gtk.ScrolledWindow();
+                       WidgetGrid.Attach(_ScrolledWindow, 1, 2, 1, 2);
+
+                       InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
+                       WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
+
+                       _WebView = new WebKit.WebView();
+                       _WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
+                               _Window.Title = e.Title + " - WebThing";
+                       };
+                       _ScrolledWindow.Add(_WebView);
+
+                       _Window.ShowAll();
+
+                       Plugins = new Dictionary<string, object>();
+                       // TODO: Conf.Get("plugins") instead of hard-coded path?
+                       using (TextReader f = new StreamReader("plugins.conf")) {
+                               string line;
+                               while ((line = f.ReadLine()) != null) {
+                                       line = line.Trim();
+                                       LoadPlugin(line);
+                               }
+                       }
+
+                       Application.Run();
+               }
+
+               public void LoadPlugin(string assemblyname) {
+                       Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
+                       object obj = a.CreateInstance("Plugin", false, BindingFlags.ExactBinding, null, new object[] { this }, null, null);
+                       Plugins[assemblyname] = obj;
+               }
+
+               public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
+                       switch(direction) {
+                       case CompassDirection.N:
+                               WidgetGrid.Attach(widget, 1, 2, 0, 1, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.NE:
+                               WidgetGrid.Attach(widget, 2, 3, 0, 1, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.E:
+                               WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.SE:
+                               WidgetGrid.Attach(widget, 2, 3, 2, 3, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.S:
+                               WidgetGrid.Attach(widget, 1, 2, 2, 3, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.SW:
+                               WidgetGrid.Attach(widget, 0, 1, 2, 3, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.W:
+                               WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.NW:
+                               WidgetGrid.Attach(widget, 0, 1, 0, 1, xoptions, yoptions, 0, 0);
+                               break;
+                       case CompassDirection.Interior:
+                               InteriorOverlay.Add(widget);
+                               break;
+                       }
+               }
+
+               public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
+                       AttachWidget(widget, direction, 0, 0);
+               }
+       }
+}
diff --git a/main.cs b/main.cs
new file mode 100644 (file)
index 0000000..4633d6f
--- /dev/null
+++ b/main.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace bytex64.WebThing {
+       public class WebThingMain {
+               static WebThing wt;
+
+               public static void Main(string[] args) {
+                       wt = new WebThing();
+                       wt.Run();
+               }
+       }
+}
diff --git a/plugins.conf b/plugins.conf
new file mode 100644 (file)
index 0000000..72eb6e4
--- /dev/null
@@ -0,0 +1,4 @@
+SoupSettings
+LoadProgress
+Vimish
+DefaultPage
diff --git a/plugins/DefaultPage.cs b/plugins/DefaultPage.cs
new file mode 100644 (file)
index 0000000..e1a0010
--- /dev/null
@@ -0,0 +1,8 @@
+using System;
+using bytex64.WebThing;
+
+public class Plugin {
+       public Plugin(WebThing wt) {
+               wt.WebView.Open("http://dominionofawesome.com/");
+       }
+}
diff --git a/plugins/LoadProgress.cs b/plugins/LoadProgress.cs
new file mode 100644 (file)
index 0000000..3d5e59d
--- /dev/null
@@ -0,0 +1,87 @@
+using System;
+using Gtk;
+using WebKit;
+using bytex64.WebThing;
+
+public class LoadThrobber : Gtk.DrawingArea {
+       public enum Mode {
+               LoadStarted,
+               LoadInProgress,
+               LoadFinished
+       };
+       public Mode LoadState;
+       int r;
+       uint idletimer;
+
+       public LoadThrobber(WebThing wt) {
+               LoadState = Mode.LoadStarted;
+
+               wt.WebView.LoadStarted += WebView_LoadStarted;
+               wt.WebView.LoadCommitted += WebView_LoadCommitted;
+               wt.WebView.LoadProgressChanged += WebView_LoadProgressChanged;
+               wt.WebView.LoadFinished += WebView_LoadFinished;
+
+               SetSizeRequest(64, 64);
+       }
+
+       protected override bool OnExposeEvent(Gdk.EventExpose e) {
+               Gdk.Window w = e.Window;
+               Gdk.GC gc = new Gdk.GC(w);
+               int width, height;
+               w.GetSize(out width, out height);
+
+               gc.Foreground = new Gdk.Color(0, 0, 0);
+               gc.SetLineAttributes(3, Gdk.LineStyle.Solid, Gdk.CapStyle.Butt, Gdk.JoinStyle.Round);
+               w.Clear();
+
+               switch(LoadState) {
+               case Mode.LoadStarted:
+                       w.DrawArc(gc, false, 4, 4, width-8, width-8, -r*64, 90*64);
+                       w.DrawArc(gc, false, 4, 4, width-8, width-8, -r*64 + 180*64, 90*64);
+                       r += 5;
+                       break;
+               case Mode.LoadInProgress:
+               case Mode.LoadFinished:
+                       w.DrawArc(gc, false, 4, 4, width-8, width-8, 90*64, -r*64);
+                       break;
+               }
+               return true;
+       }
+
+       void WebView_LoadStarted(object o, LoadStartedArgs e) {
+               this.Show();
+               Console.WriteLine("Loading Started");
+               LoadState = Mode.LoadStarted;
+               idletimer = GLib.Timeout.Add(100, delegate {
+                       QueueDraw();
+                       return true;
+               });
+       }
+
+       void WebView_LoadCommitted(object o, LoadCommittedArgs e) {
+               Console.WriteLine("Loading Committed");
+               LoadState = Mode.LoadInProgress;
+               GLib.Source.Remove(idletimer);
+               r = 0;
+               QueueDraw();
+       }
+
+       void WebView_LoadProgressChanged(object o, LoadProgressChangedArgs e) {
+               Console.WriteLine("Loading Progress: {0}", e.Progress);
+               r = (int) ((e.Progress / 100.0) * 360);
+               QueueDraw();
+       }
+
+       void WebView_LoadFinished(object o, LoadFinishedArgs e) {
+               Console.WriteLine("Loading Finished");
+               LoadState = Mode.LoadFinished;
+               this.Hide();
+       }
+}
+
+public class Plugin {
+       public Plugin(WebThing wt) {
+               LoadThrobber lt = new LoadThrobber(wt);
+               wt.AttachWidget(lt, CompassDirection.Interior);
+       }
+}
diff --git a/plugins/Makefile b/plugins/Makefile
new file mode 100644 (file)
index 0000000..d742115
--- /dev/null
@@ -0,0 +1,15 @@
+CSFLAGS = -debug
+references = -r:../webkit-sharp.dll -pkg:gtk-sharp-2.0
+
+all: Vimish.dll DefaultPage.dll SoupSettings.dll LoadProgress.dll
+
+clean:
+       rm -f *.dll *.mdb *.so
+       make -C SoupSettings clean
+
+.PHONY: SoupSettings.dll
+SoupSettings.dll: 
+       make -C SoupSettings
+
+%.dll: %.cs ../WebThing.dll
+       gmcs $(CSFLAGS) $(references) -r:../WebThing.dll -target:library -out:$@ $<
diff --git a/plugins/SoupSettings/Makefile b/plugins/SoupSettings/Makefile
new file mode 100644 (file)
index 0000000..6defa6a
--- /dev/null
@@ -0,0 +1,16 @@
+CFLAGS = `pkg-config glib-2.0 libsoup-2.4 webkit-1.0 --cflags`
+LDFLAGS = `pkg-config glib-2.0 libsoup-2.4 webkit-1.0 --libs`
+CSFLAGS = -debug
+references = -r:../../webkit-sharp.dll -pkg:gtk-sharp-2.0
+
+all: ../SoupSettings.dll
+
+clean:
+       rm -f *.dll *.mdb ../SoupSettings.dll ../SoupSettings.so
+
+../%.dll: %.cs %.so ../../WebThing.dll
+       gmcs $(CSFLAGS) $(references) -r:../../WebThing.dll -target:library -out:$@ $<
+
+%.so: %.c
+       $(CC) $(CFLAGS) -shared $(LDFLAGS) $< -o $@
+       cp $@ ../
diff --git a/plugins/SoupSettings/SoupSettings.c b/plugins/SoupSettings/SoupSettings.c
new file mode 100644 (file)
index 0000000..66778bf
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <glib.h>
+#include <webkit/webkit.h>
+#include <libsoup/soup.h>
+
+void soup_settings() {
+       SoupSession *soup_session = webkit_get_default_session();
+
+       /* Set up persistent cookies */
+       SoupCookieJar *jar = (SoupCookieJar *) soup_cookie_jar_text_new("cookies.txt", FALSE);
+       soup_session_add_feature(soup_session, SOUP_SESSION_FEATURE(jar));
+}
diff --git a/plugins/SoupSettings/SoupSettings.cs b/plugins/SoupSettings/SoupSettings.cs
new file mode 100644 (file)
index 0000000..1637c97
--- /dev/null
@@ -0,0 +1,12 @@
+using System;
+using System.Runtime.InteropServices;
+using bytex64.WebThing;
+
+public class Plugin {
+       [DllImport ("SoupSettings.so")]
+       private static extern void soup_settings();
+
+       public Plugin(WebThing wt) {
+               soup_settings();
+       }
+}
diff --git a/plugins/Vimish.cs b/plugins/Vimish.cs
new file mode 100644 (file)
index 0000000..bb56ed0
--- /dev/null
@@ -0,0 +1,85 @@
+using System;
+using System.Text.RegularExpressions;
+using Gtk;
+using bytex64.WebThing;
+
+public class Plugin {
+       WebThing wt;
+       Gtk.Entry commandline;
+
+       public Plugin(WebThing wt) {
+               this.wt = wt;
+               wt.WebView.KeyPressEvent += WebView_KeyPress;
+
+               commandline = new Gtk.Entry();
+               commandline.Activated += command_Activate;
+               commandline.KeyPressEvent += command_KeyPress;
+               wt.AttachWidget(commandline, CompassDirection.S, AttachOptions.Fill, AttachOptions.Shrink);
+
+               commandline.Hide();
+       }
+
+       private void WebView_KeyPress(object o, KeyPressEventArgs e) {
+               Console.WriteLine(e.Event.Key);
+               switch(e.Event.Key) {
+               case Gdk.Key.j:
+                       wt.ScrolledWindow.Vadjustment.Value += wt.ScrolledWindow.Vadjustment.StepIncrement;
+                       break;
+               case Gdk.Key.k:
+                       wt.ScrolledWindow.Vadjustment.Value -= wt.ScrolledWindow.Vadjustment.StepIncrement;
+                       break;
+               case Gdk.Key.l:
+                       wt.ScrolledWindow.Hadjustment.Value += wt.ScrolledWindow.Hadjustment.StepIncrement;
+                       break;
+               case Gdk.Key.h:
+                       wt.ScrolledWindow.Hadjustment.Value -= wt.ScrolledWindow.Hadjustment.StepIncrement;
+                       break;
+               case Gdk.Key.o:
+                       CommandStart("open ");
+                       break;
+               case Gdk.Key.t:
+                       CommandStart("tabopen ");
+                       break;
+               case Gdk.Key.BackSpace:
+                       wt.WebView.GoBack();
+                       break;
+               case Gdk.Key.colon:
+                       CommandlineShow();
+                       break;
+               }
+       }
+
+       public void CommandStart(string text) {
+               commandline.Text = text;
+               commandline.GrabFocus();
+               commandline.Position = text.Length;
+               commandline.Show();
+       }
+
+       public void CommandlineShow() {
+               commandline.Show();
+               commandline.GrabFocus();
+       }
+
+       public void CommandlineHide() {
+               commandline.Hide();
+               wt.WebView.GrabFocus();
+       }
+
+       private void command_Activate(object o, EventArgs e) {
+               string[] args = Regex.Split(commandline.Text, @"\s+");
+               switch(args[0]) {
+               case "open":
+                       if (args.Length < 2) return;
+                       wt.WebView.Open(args[1]);
+                       break;
+               }
+               commandline.Text = "";
+               CommandlineHide();
+       }
+
+       private void command_KeyPress(object o, KeyPressEventArgs e) {
+               if (e.Event.Key == Gdk.Key.Escape)
+                       CommandlineHide();
+       }
+}