commit:126f2111e41f6b2595ffde1de6828ef12246e545
author:Chip Black
committer:Chip Black
date:Sat May 30 04:34:21 2009 -0500
parents:
Finally, a version I'm proud of. :)
diff --git a/Makefile b/Makefile
line changes: +15/-0
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
line changes: +7/-0
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
line changes: +125/-0
index 0000000..04ede67
--- /dev/null
+++ b/WebThing.cs
@@ -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
line changes: +12/-0
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
line changes: +4/-0
index 0000000..72eb6e4
--- /dev/null
+++ b/plugins.conf
@@ -0,0 +1,4 @@
+SoupSettings
+LoadProgress
+Vimish
+DefaultPage

diff --git a/plugins/DefaultPage.cs b/plugins/DefaultPage.cs
line changes: +8/-0
index 0000000..e1a0010
--- /dev/null
+++ b/plugins/DefaultPage.cs
@@ -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
line changes: +87/-0
index 0000000..3d5e59d
--- /dev/null
+++ b/plugins/LoadProgress.cs
@@ -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
line changes: +15/-0
index 0000000..d742115
--- /dev/null
+++ b/plugins/Makefile
@@ -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
line changes: +16/-0
index 0000000..6defa6a
--- /dev/null
+++ b/plugins/SoupSettings/Makefile
@@ -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
line changes: +12/-0
index 0000000..66778bf
--- /dev/null
+++ b/plugins/SoupSettings/SoupSettings.c
@@ -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
line changes: +12/-0
index 0000000..1637c97
--- /dev/null
+++ b/plugins/SoupSettings/SoupSettings.cs
@@ -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
line changes: +85/-0
index 0000000..bb56ed0
--- /dev/null
+++ b/plugins/Vimish.cs
@@ -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();
+	}
+}