/WebThing.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Gtk;
using GtkSharp;
using WebKit;
namespace bytex64.WebThing {
public enum AttachPoint {
N, E, S, W, Interior
}
public class WebThing {
private Gtk.Window _Window;
public Gtk.Window Window {
get { return _Window; }
}
public Gtk.Window w {
get { return _Window; }
}
public ScrolledWindow ScrolledWindow {
get { return Tabs.CurrentPageWidget as ScrolledWindow; }
}
public ScrolledWindow sw {
get { return ScrolledWindow; }
}
public WebView WebView {
get { return (Tabs.CurrentPageWidget as WebThingView).WebView; }
}
public WebView wv {
get { return WebView; }
}
private Gtk.Notebook _Tabs;
public Gtk.Notebook Tabs {
get { return _Tabs; }
}
private Gtk.Table WidgetGrid;
private Gtk.Alignment InteriorOverlay;
public PluginManager Plugins;
public SearchHandler Search;
[DllImport ("SoupSettings.dll")]
private static extern void soup_settings();
// Main setup
public void Run() {
Application.Init();
soup_settings();
Config.ParseCommandLine();
Config.Load();
//Config.DumpOptions();
// Initialize Window
_Window = new Gtk.Window("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();
// Load Plugins
Plugins = new PluginManager(this);
Plugins.Load();
// Load Search Handlers
Search = new SearchHandler(this);
// 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 Quit() {
Plugins.Deinit();
Application.Quit();
}
// Widget attachment
public void AttachWidget(Gtk.Widget widget, AttachPoint direction, AttachOptions xoptions, AttachOptions yoptions) {
switch(direction) {
case AttachPoint.N:
WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
break;
case AttachPoint.E:
WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
break;
case AttachPoint.S:
WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
break;
case AttachPoint.W:
WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
break;
case AttachPoint.Interior:
InteriorOverlay.Add(widget);
break;
}
}
public void AttachWidget(Gtk.Widget widget, AttachPoint direction) {
AttachWidget(widget, direction, 0, 0);
}
// Tab management
public WebThingView NewTab() {
WebThingView newview = NewWebThingView();
Plugins.WebViewSetup(newview.WebView);
return newview;
}
private WebThingView NewWebThingView() {
WebThingView newview = new WebThingView();
Tabs.AppendPage(newview, new Label("Blank"));
newview.WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
Tabs.SetTabLabelText((Gtk.Widget) newview, e.Title);
if (newview == Tabs.CurrentPageWidget)
_Window.Title = e.Title + " - WebThing";
};
newview.Show();
return newview;
}
public void CloseTab() {
CloseTab(_Tabs.Page);
}
public void CloseTab(int tab) {
if (_Tabs.NPages > 1) {
try {
WebThingView view = _Tabs.GetNthPage(tab) as WebThingView;
_Tabs.RemovePage(tab);
view.Dispose();
} catch (ArgumentOutOfRangeException) {
Console.WriteLine("Attempted to close tab out of range: {0}", tab);
}
}
}
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);
}
}
}
public bool Open(string query) {
string uri = GetUri(query);
if (uri == null) return false;
wv.Open(uri);
return true;
}
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 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;
}
public void Bump(int x, int y) {
Scroll(x * ScrolledWindow.Hadjustment.StepIncrement, y * ScrolledWindow.Vadjustment.StepIncrement);
}
}
}