Fix scrolling functionality
[WebThing.git] / WebThing.cs
index 5aa52cf..ff51354 100644 (file)
@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Reflection;
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Runtime.InteropServices;
@@ -9,7 +8,7 @@ using GtkSharp;
 using WebKit;
 
 namespace bytex64.WebThing {
-    public enum CompassDirection {
+    public enum AttachPoint {
         N, E, S, W, Interior
     }
 
@@ -44,98 +43,121 @@ namespace bytex64.WebThing {
         private Gtk.Table WidgetGrid;
         private Gtk.Alignment InteriorOverlay;
 
-        public Dictionary<string,WebThingPlugin> Plugins;
+        public PluginManager Plugins;
+        public SearchHandler Search;
 
         [DllImport ("SoupSettings.dll")]
         private static extern void soup_settings();
 
+        // Main setup
         public void Run() {
             Application.Init();
-            Plugins = new Dictionary<string,WebThingPlugin>();
+
+            soup_settings();
 
             Config.ParseCommandLine();
             Config.Load();
             //Config.DumpOptions();
 
-            soup_settings();
-
+            // Initialize Window
             _Window = new Gtk.Window("WebThing");
-            _Window.SetWmclass("webthing", "WebThing");
+            // The GTK+ docs say not to use this, but the defaults are
+            // based on the executable name, which I don't like.
+            _Window.SetWmclass("webthing", "WebThing");  
             _Window.Role = "browser";
+            {
+                int w, h;
+
+                if (Config.Options.ContainsKey("Width"))
+                    w = Convert.ToInt32(Config.Options["Width"]);
+                else
+                    w = 640;
+
+                if (Config.Options.ContainsKey("Height"))
+                    h = Convert.ToInt32(Config.Options["Height"]);
+                else
+                    h = 480;
+
+                _Window.DefaultSize = new Gdk.Size(w, h);
+            }
             _Window.Destroyed += delegate { Quit(); };
 
+            // Initialize WidgetGrid
+            // The WidgetGrid holds the Tabs (and thus WebKit) and
+            // AttachPoint.Interior in the center, and allows widgets to
+            // be added on the sides of the browser
             WidgetGrid = new Gtk.Table(3, 3, false);
             _Window.Add(WidgetGrid);
 
+            // Initialize Tabs
+            // Tabs are a core feature of WebThing, not a plugin.  By
+            // default, they do nothing -- Tab manipulation is left to
+            // plugins to define.
             _Tabs = new Gtk.Notebook();
             _Tabs.ShowBorder = false;
             _Tabs.Scrollable = true;
             _Tabs.SwitchPage += Tabs_SwitchPage;
             WidgetGrid.Attach(_Tabs, 1, 2, 1, 2);
 
+            // InteriorOverlay goes over top of the Tabs to contain
+            // widgets that hover over the content, like progress, or
+            // inline search.  This is not a very solid idea ATM.
             InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
             WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
 
             _Window.ShowAll();
 
-            WebThingView newview = NewWebThingView();
+            // Load Plugins
+            Plugins = new PluginManager(this);
+            Plugins.Load();
 
-            // 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);
-                }
-            }
+            // Load Search Handlers
+            Search = new SearchHandler(this);
 
-            WebViewSetupPlugins(newview.WebView);
-            newview.WebView.GrabFocus();
+            // Create a new, default WebThingView if one has not already
+            // been created.
+            if (Tabs.NPages == 0)
+                OpenTab("http://dominionofawesome.com/");
+            WebView.GrabFocus();
 
             Application.Run();
         }
 
-        public void LoadPlugin(string assemblyname) {
-            Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
-            Type[] types = a.GetTypes();
-            foreach (Type t in types) {
-                if (t.IsSubclassOf(typeof(WebThingPlugin))) {
-                    WebThingPlugin p = (WebThingPlugin) a.CreateInstance(t.FullName, false, BindingFlags.ExactBinding, null, null, null, null);
-                    p.Init(this);
-                    Plugins[t.FullName] = p;
-                    Console.WriteLine("Successfully loaded {0}", t.FullName);
-                }
-            }
+        public void Quit() {
+            Plugins.Deinit();
+            Application.Quit();
         }
 
-        public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
+        // Widget attachment
+        public void AttachWidget(Gtk.Widget widget, AttachPoint direction, AttachOptions xoptions, AttachOptions yoptions) {
             switch(direction) {
-            case CompassDirection.N:
+            case AttachPoint.N:
                 WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.E:
+            case AttachPoint.E:
                 WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.S:
+            case AttachPoint.S:
                 WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.W:
+            case AttachPoint.W:
                 WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.Interior:
+            case AttachPoint.Interior:
                 InteriorOverlay.Add(widget);
                 break;
             }
         }
 
-        public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
+        public void AttachWidget(Gtk.Widget widget, AttachPoint direction) {
             AttachWidget(widget, direction, 0, 0);
         }
 
-        public WebView NewTab() {
+        // Tab management
+        public WebThingView NewTab() {
             WebThingView newview = NewWebThingView();
-            WebViewSetupPlugins(newview.WebView);
-            return newview.WebView;
+            Plugins.WebViewSetup(newview.WebView);
+            return newview;
         }
 
         private WebThingView NewWebThingView() {
@@ -150,12 +172,6 @@ namespace bytex64.WebThing {
             return newview;
         }
 
-        private void WebViewSetupPlugins(WebView view) {
-            foreach (string key in Plugins.Keys) {
-                Plugins[key].InitWebView(view);
-            }
-        }
-
         public void CloseTab() {
             CloseTab(_Tabs.Page);
         }
@@ -167,34 +183,60 @@ namespace bytex64.WebThing {
                     _Tabs.RemovePage(tab);
                     view.Dispose();
                 } catch (ArgumentOutOfRangeException) {
+                    Console.WriteLine("Attempted to close tab out of range: {0}", tab);
                 }
             }
         }
 
-        public string FixUri(string Uri) {
-            if (!Regex.IsMatch(Uri, @"://")) {
-                return String.Format("http://{0}", Uri);
+        private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
+            Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
+            _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
+        }
+
+        // Uri loading
+        private string GetUri(string query) {
+            Uri u;
+            try {
+                u = new Uri(query);
+                return u.ToString();
+            } catch(UriFormatException) {
+                try {
+                    u = new Uri(String.Format("http://{0}", query));
+                    return u.ToString();
+                } catch (UriFormatException) {
+                    return Search.Transform(query);
+                }
             }
-            return Uri;
         }
 
-        public void OpenUri(string Uri) {
-            wv.Open(FixUri(Uri));
+        public bool Open(string query) {
+            string uri = GetUri(query);
+            if (uri == null) return false;
+            
+            wv.Open(uri);
+            return true;
         }
 
-        public void OpenUriTab(string Uri) {
-            WebView view = NewTab();
-            view.Open(FixUri(Uri));
+        public bool OpenTab(string query) {
+            WebThingView wtv = NewTab();
+            string uri = GetUri(query);
+            if (uri == null) return false;
+
+            wtv.WebView.Open(uri);
+            return true;
         }
 
-        public void Quit() {
-            // TODO: Create a way of shutting down plugins
-            Application.Quit();
+        public void Scroll(double x, double y) {
+            ScrolledWindow.Hadjustment.Value += x;
+            if (ScrolledWindow.Hadjustment.Value > ScrolledWindow.Hadjustment.Upper - ScrolledWindow.Hadjustment.PageSize)
+                ScrolledWindow.Hadjustment.Value = ScrolledWindow.Hadjustment.Upper - ScrolledWindow.Hadjustment.PageSize;
+            ScrolledWindow.Vadjustment.Value += y;
+            if (ScrolledWindow.Vadjustment.Value > ScrolledWindow.Vadjustment.Upper - ScrolledWindow.Vadjustment.PageSize)
+                ScrolledWindow.Vadjustment.Value = ScrolledWindow.Vadjustment.Upper - ScrolledWindow.Vadjustment.PageSize;
         }
 
-        private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
-            Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
-            _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
+        public void Bump(int x, int y) {
+            Scroll(x * ScrolledWindow.Hadjustment.StepIncrement, y * ScrolledWindow.Vadjustment.StepIncrement);
         }
     }
 }