Added tabs
Quite a bit has been reworked. The WebView is now part of a
WebThingView container which integrates the scrollbars. Tab
initialization has been split into two pieces, one for creating the
tab, and another for running plugins on it.
Also, for some reason I forgot to add WebThingPlugin.cs last time.
Whoops.
main.exe: main.cs WebThing.dll SoupSettings.so
gmcs $(CSFLAGS) -r:WebThing.dll main.cs
-WebThing.dll: WebThing.cs WebThingPlugin.cs
+WebThing.dll: WebThing.cs WebThingView.cs WebThingPlugin.cs
gmcs $(CSFLAGS) $(references) -target:library -out:$@ $^
SoupSettings.so: SoupSettings.c
}
public class WebThing {
+ private Gtk.Window _Window;
public Gtk.Window Window {
get { return _Window; }
}
-
public Gtk.Window w {
get { return _Window; }
}
- public Gtk.ScrolledWindow ScrolledWindow {
- get { return _ScrolledWindow; }
+ public ScrolledWindow ScrolledWindow {
+ get { return Tabs.CurrentPageWidget as ScrolledWindow; }
}
-
- public Gtk.ScrolledWindow sw {
- get { return _ScrolledWindow; }
+ public ScrolledWindow sw {
+ get { return ScrolledWindow; }
}
- public WebKit.WebView WebView {
- get { return _WebView; }
+ public WebView WebView {
+ get { return (Tabs.CurrentPageWidget as WebThingView).WebView; }
+ }
+ public WebView wv {
+ get { return WebView; }
}
- public WebKit.WebView wv {
- get { return _WebView; }
+ private Gtk.Notebook _Tabs;
+ public Gtk.Notebook Tabs {
+ get { return _Tabs; }
+ }
+ /*
+ private int _CurrentTab;
+ public int CurrentTab {
+ get { return _CurrentTab; }
+ set {
+ if (value >= _Tabs.Count)
+ _CurrentTab = _Tabs.Count - 1;
+ else if (value < 0)
+ _CurrentTab = 0;
+ else
+ _CurrentTab = value;
+
+ _WebView.Hide();
+ _ScrolledWindow.Remove(_WebView);
+ _WebView = _Tabs[_CurrentTab];
+ _ScrolledWindow.Add(_WebView);
+ foreach (WebView view in Tabs)
+ Console.WriteLine(view.MainFrame.Uri);
+ _WebView.Show();
+ _WebView.GrabFocus();
+ }
}
+ */
- private Gtk.Window _Window;
- private ScrolledWindow _ScrolledWindow;
- private WebKit.WebView _WebView;
private Gtk.Table WidgetGrid;
private Gtk.Alignment InteriorOverlay;
public void Run() {
Application.Init();
-
+ Plugins = new Dictionary<string,WebThingPlugin>();
ParseArgs();
+ soup_settings();
+
_Window = new Gtk.Window("WebThing");
_Window.SetWmclass("webthing", "WebThing");
_Window.Role = "browser";
WidgetGrid = new Gtk.Table(3, 3, false);
_Window.Add(WidgetGrid);
- _ScrolledWindow = new Gtk.ScrolledWindow();
- WidgetGrid.Attach(_ScrolledWindow, 1, 2, 1, 2);
+ _Tabs = new Gtk.Notebook();
+ _Tabs.SwitchPage += Tabs_SwitchPage;
+ WidgetGrid.Attach(_Tabs, 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";
- };
- soup_settings();
-
- _ScrolledWindow.Add(_WebView);
-
_Window.ShowAll();
- Plugins = new Dictionary<string,WebThingPlugin>();
+ WebThingView newview = NewWebThingView();
+
// TODO: Conf.Get("plugins") instead of hard-coded path?
using (TextReader f = new StreamReader("plugins.conf")) {
string line;
}
}
+ WebViewSetupPlugins(newview.WebView);
+ newview.WebView.GrabFocus();
+
Application.Run();
}
Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
Type[] types = a.GetTypes();
foreach (Type t in types) {
- if (t.GetInterface("WebThingPlugin") != null) {
+ 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;
AttachWidget(widget, direction, 0, 0);
}
- public void OpenUri(string Uri) {
+ public WebView NewTab() {
+ WebThingView newview = NewWebThingView();
+ WebViewSetupPlugins(newview.WebView);
+ return newview.WebView;
+ }
+
+ 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;
+ }
+
+ private void WebViewSetupPlugins(WebView view) {
+ foreach (string key in Plugins.Keys) {
+ Plugins[key].InitWebView(view);
+ }
+ }
+
+ 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) {
+ }
+ }
+ }
+
+ public string FixUri(string Uri) {
if (!Regex.IsMatch(Uri, @"://")) {
- Uri = String.Format("http://{0}", Uri);
+ return String.Format("http://{0}", Uri);
}
- wv.Open(Uri);
+ return Uri;
+ }
+
+ public void OpenUri(string Uri) {
+ wv.Open(FixUri(Uri));
+ }
+
+ public void OpenUriTab(string Uri) {
+ WebView view = NewTab();
+ view.Open(FixUri(Uri));
}
public void Quit() {
// TODO: Create a way of shutting down plugins
Application.Quit();
}
+
+ private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
+ Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
+ _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
+ }
}
}
+using WebKit;
+
+namespace bytex64.WebThing {
+ public abstract class WebThingPlugin {
+ public abstract void Init(WebThing wt);
+ public virtual void InitWebView(WebView wv) {}
+ }
+}
+using WebKit;
+using Gtk;
+
+namespace bytex64.WebThing {
+ public class WebThingView : ScrolledWindow {
+ private WebView _WebView;
+ public WebView WebView {
+ get { return _WebView; }
+ }
+
+ public WebThingView() {
+ _WebView = new WebView();
+ Add(_WebView);
+ _WebView.Show();
+ }
+ }
+}
using bytex64.WebThing;
public class DefaultPage : WebThingPlugin {
- public void Init(WebThing wt) {
+ public override void Init(WebThing wt) {
if (wt.Arguments.Length > 0) {
wt.OpenUri(wt.Arguments[0]);
} else {
using System;
using Gtk;
+using WebKit;
using bytex64.WebThing;
public class FFNav : WebThingPlugin {
WebThing wt;
- public void Init(WebThing wt) {
+ public override void Init(WebThing wt) {
this.wt = wt;
- wt.WebView.KeyPressEvent += WebView_KeyPress;
+ }
+
+ public override void InitWebView(WebView wv) {
+ wv.KeyPressEvent += WebView_KeyPress;
}
private void WebView_KeyPress(object o, KeyPressEventArgs e) {
+ WebView wv = (WebView) o;
if ((e.Event.State & Gdk.ModifierType.Mod1Mask) != 0) {
switch(e.Event.Key) {
case Gdk.Key.Left:
- wt.WebView.GoBack();
+ wv.GoBack();
break;
case Gdk.Key.Right:
- wt.WebView.GoForward();
+ wv.GoForward();
+ break;
+ }
+ } else if ((e.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+ switch(e.Event.Key) {
+ case Gdk.Key.t:
+ wt.NewTab();
+ wt.Tabs.CurrentPage = wt.Tabs.NPages - 1;
+ break;
+ case Gdk.Key.w:
+ wt.CloseTab();
+ break;
+ case Gdk.Key.ISO_Left_Tab:
+ if (wt.Tabs.CurrentPage == 0)
+ wt.Tabs.CurrentPage = wt.Tabs.NPages - 1;
+ else
+ wt.Tabs.PrevPage();
+ break;
+ case Gdk.Key.Tab:
+ if (wt.Tabs.CurrentPage == wt.Tabs.NPages - 1)
+ wt.Tabs.CurrentPage = 0;
+ else
+ wt.Tabs.NextPage();
break;
}
} else {
switch(e.Event.Key) {
case Gdk.Key.BackSpace:
- wt.WebView.GoBack();
+ wv.GoBack();
break;
}
}
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);
}
+ public void AttachSignals(WebView wv) {
+ wv.LoadStarted += WebView_LoadStarted;
+ wv.LoadCommitted += WebView_LoadCommitted;
+ wv.LoadProgressChanged += WebView_LoadProgressChanged;
+ wv.LoadFinished += WebView_LoadFinished;
+ }
+
protected override bool OnExposeEvent(Gdk.EventExpose e) {
Gdk.Window w = e.Window;
Gdk.GC gc = new Gdk.GC(w);
}
public class LoadThrobberPlugin : WebThingPlugin {
- public void Init(WebThing wt) {
- LoadThrobber lt = new LoadThrobber(wt);
+ LoadThrobber lt;
+
+ public override void Init(WebThing wt) {
+ lt = new LoadThrobber(wt);
wt.AttachWidget(lt, CompassDirection.Interior);
}
+
+ public override void InitWebView(WebView wv) {
+ lt.AttachSignals(wv);
+ }
}
using System;
using System.Text.RegularExpressions;
using Gtk;
+using WebKit;
using bytex64.WebThing;
public class Vimish : WebThingPlugin {
WebThing wt;
Gtk.Entry commandline;
- public void Init(WebThing wt) {
+ public override void Init(WebThing wt) {
this.wt = wt;
- wt.WebView.KeyPressEvent += WebView_KeyPress;
+
+ wt.Window.KeyPressEvent += Window_KeyPress;
commandline = new Gtk.Entry();
commandline.Activated += command_Activate;
commandline.Hide();
}
- private void WebView_KeyPress(object o, KeyPressEventArgs e) {
- Console.WriteLine(e.Event.Key);
+ public override void InitWebView(WebView wv) {
+ wv.KeyPressEvent += WebView_KeyPress;
+ }
+
+ private void Window_KeyPress(object o, KeyPressEventArgs e) {
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.r:
- wt.WebView.Reload();
- break;
case Gdk.Key.t:
CommandStart("tabopen ");
break;
case Gdk.Key.colon:
CommandlineShow();
break;
- case Gdk.Key.Escape:
- wt.WebView.ExecuteScript("document.activeElement.blur()");
- break;
+ }
+ }
+
+ private void WebView_KeyPress(object o, KeyPressEventArgs e) {
+ Console.WriteLine(e.Event.Key);
+ if ((Gdk.ModifierType.ControlMask & e.Event.State) != 0) {
+ switch(e.Event.Key) {
+ case Gdk.Key.n:
+ wt.Tabs.NextPage();
+ break;
+ case Gdk.Key.p:
+ wt.Tabs.PrevPage();
+ break;
+ }
+ } else {
+ 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.r:
+ wt.WebView.Reload();
+ break;
+ case Gdk.Key.Escape:
+ wt.WebView.ExecuteScript("document.activeElement.blur()");
+ break;
+ }
}
}
private void command_Activate(object o, EventArgs e) {
string[] args = Regex.Split(commandline.Text, @"\s+");
switch(args[0]) {
+ case "close":
+ wt.CloseTab();
+ break;
case "open":
if (args.Length < 2) return;
wt.OpenUri(args[1]);
break;
+ case "tabopen":
+ if (args.Length < 2) return;
+ wt.OpenUriTab(args[1]);
+ wt.Tabs.CurrentPage = wt.Tabs.NPages - 1;
+ break;
+ case "n":
+ wt.Tabs.NextPage();
+ break;
+ case "p":
+ wt.Tabs.PrevPage();
+ break;
case "q":
wt.Quit();
break;