-
Notifications
You must be signed in to change notification settings - Fork 148
Gecko and Glade mini browser
Added by Eli Yukelzon
In this example we'll use Glade# to construct the GUI of the application, and then use Gecko# to add the actual browser component.
Notice
- To make Gecko# application run and detect Mozilla's libraries, you have to make sure that MOZILLA_FIVE_HOME directory is in the LD_LIBARY_PATH
The design of the GUI is entirely up to you, all you need is a few buttons for basic actions, like Back,Forward,Refresh and etc, and a placeholder for Mozilla's Webcontrol. For each button prepare a Clicked signals, and write down their names. We'll write handlers for them later on.
You can find my Glade generated at the end of the article.
Basic idea of constructing Glade application is as follows:
- create a class
- on it's constructor:
-
- call Application.Init()
-
- loads the GUI xml, and connects it's signals to handlers in the code
-
- add any additional controls if needed
-
- call Application.Run()
So, here's the code:
# Simple Mozilla base Browser - booRowser
# by Eli Yukelzon <[email protected]>
# Based on examples from MonoDoc
# Note: before running, make sure that MOZILLA_FIVE_HOME directory
# is in the LD_LIBARY_PATH
import System
# when importing , specify a 'from' to help boo find the references
import Gtk from "gtk-sharp"
import Glade from "glade-sharp"
import Gecko from "gecko-sharp"
import Gnome from "gnome-sharp"
public class GladeApp:
[Widget] frame1 as Frame
[Widget] entry1 as Gtk.Entry
[Widget] window1 as Gtk.Window
[Widget] progressbar1 as Gtk.ProgressBar
[Widget] statusbar1 as Gtk.Statusbar
web as WebControl
public def constructor (args):
Application.Init()
gxml = Glade.XML ("gui.glade", "window1", null)
try:
# load the xml file, and setup a controls with event handlers
gxml.Autoconnect (self)
# create Mozilla control
web = WebControl()
web.Show()
frame1.Add(web)
# setup event handlers
entry1.Activated += load_url
web.TitleChange += web_title_change
web.LinkMsg += on_linkmessage
web.Progress += on_progress
# setup default site
entry1.Text = "www.google.com"
entry1.Show()
entry1.Activate()
statusbar1.Push(1,"Welcome to booBrowser!")
# start Gtk message loop
Application.Run()
except e as Glade.HandlerNotFoundException:
print "Exception caught while constructing from Glade XML:\n" + e
except e as Exception:
print "Exception caught:\n" + e
public def on_progress ( source as object , args as ProgressArgs):
# this will work only if target page size is known
progressbar1.Adjustment.Upper = args.Maxprogress
progressbar1.Adjustment.Value = args.Curprogress
public def web_title_change( source as object, args as EventArgs):
window1.Title = "booRowser: [ "+web.Title+" ]"
public def OnWindowDeleteEvent (source as object, args as DeleteEventArgs):
Application.Quit ()
args.RetVal = true
public def load_url(source as object , args as EventArgs):
if (entry1.Text!=null):
web.LoadUrl(entry1.Text)
public def on_linkmessage (source as object, args as EventArgs):
statusbar1.Pop (1)
statusbar1.Push (1, web.LinkMessage)
public def on_StopButton_clicked(source as object , args as EventArgs):
web.StopLoad()
public def on_GoButton_clicked(source as object , args as EventArgs):
load_url(source, args)
public def on_FwdButton_clicked(source as object , args as EventArgs):
web.GoForward()
public def on_BackButton_clicked(source as object , args as EventArgs):
web.GoBack()
public def on_ReloadButton_clicked(source as object , args as EventArgs ):
web.Reload(3)
statusbar1.Pop(1)
statusbar1.Push(1,"Refreshing Page")
# construct a glade class
GladeApp ([])
And here's the Glade-generated GUI file:
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<requires lib="gnome"/>
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="title" translatable="yes">BooRowser</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
<property name="default_width">230</property>
<property name="default_height">350</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<signal name="delete_event" handler="OnWindowDeleteEvent"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="BackButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-go-back</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_BackButton_clicked"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="FwdButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-go-forward</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_FwdButton_clicked" />
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="StopButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-stop</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_StopButton_clicked" />
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="ReloadButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-refresh</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_ReloadButton_clicked" />
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="GoButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_GoButton_clicked" />
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
<property name="fraction">0</property>
<property name="pulse_step">0.10000000149</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusbar1">
<property name="visible">True</property>
<property name="has_resize_grip">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
Since, we've specified the list of assemblies that need to be referenced in the import section, all the is left now is to run the application:
mono booi.exe browser.boo
Or even compile it into executable, and then run it:
mono booc.exe browser.boo
mono browser.exe
That's it! Have fun boo-ing!
Eli Yukelzon