--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Thu Mar 19 02:14:19 2009 -->
+<glade-interface>
+ <widget class="GtkWindow" id="window1">
+ <property name="title" translatable="yes">Text Editor</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="default_width">300</property>
+ <property name="default_height">200</property>
+ <property name="icon_name">accessories-text-editor</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-new</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="new"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-open</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="open"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-save</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="save"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-save-as</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="save-as"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-quit</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="quit"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-cut</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="cut"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-copy</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="copy"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-paste</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="paste"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-delete</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="delete"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">gtk-about</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="about"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="toolbar1">
+ <property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <child>
+ <widget class="GtkToolButton" id="toolbutton1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">New</property>
+ <property name="stock_id">gtk-new</property>
+ <signal name="clicked" handler="new"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="toolbutton2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Open</property>
+ <property name="stock_id">gtk-open</property>
+ <signal name="clicked" handler="open"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="toolbutton3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save</property>
+ <property name="stock_id">gtk-save</property>
+ <signal name="clicked" handler="save"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="toolbutton4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save as</property>
+ <property name="stock_id">gtk-save-as</property>
+ <signal name="clicked" handler="save-as"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTextView" id="textview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkStatusbar" id="statusbar1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
--- /dev/null
+<?xml version="1.0"?>
+<!--Generated with glade3 3.4.5 on Thu Mar 19 02:14:19 2009 -->
+<interface>
+ <object class="GtkUIManager" id="uimanager1">
+ <child>
+ <object class="GtkActionGroup" id="actiongroup1">
+ <child>
+ <object class="GtkAction" id="menuitem1">
+ <property name="name">menuitem1</property>
+ <property name="label" translatable="yes">_File</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem1">
+ <property name="stock_id" translatable="yes">gtk-new</property>
+ <property name="name">imagemenuitem1</property>
+ <signal handler="new" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem2">
+ <property name="stock_id" translatable="yes">gtk-open</property>
+ <property name="name">imagemenuitem2</property>
+ <signal handler="open" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem3">
+ <property name="stock_id" translatable="yes">gtk-save</property>
+ <property name="name">imagemenuitem3</property>
+ <signal handler="save" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem4">
+ <property name="stock_id" translatable="yes">gtk-save-as</property>
+ <property name="name">imagemenuitem4</property>
+ <signal handler="save-as" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem5">
+ <property name="stock_id" translatable="yes">gtk-quit</property>
+ <property name="name">imagemenuitem5</property>
+ <signal handler="quit" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="menuitem2">
+ <property name="name">menuitem2</property>
+ <property name="label" translatable="yes">_Edit</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem6">
+ <property name="stock_id" translatable="yes">gtk-cut</property>
+ <property name="name">imagemenuitem6</property>
+ <signal handler="cut" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem7">
+ <property name="stock_id" translatable="yes">gtk-copy</property>
+ <property name="name">imagemenuitem7</property>
+ <signal handler="copy" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem8">
+ <property name="stock_id" translatable="yes">gtk-paste</property>
+ <property name="name">imagemenuitem8</property>
+ <signal handler="paste" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem9">
+ <property name="stock_id" translatable="yes">gtk-delete</property>
+ <property name="name">imagemenuitem9</property>
+ <signal handler="delete" name="activate"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="menuitem3">
+ <property name="name">menuitem3</property>
+ <property name="label" translatable="yes">_View</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="menuitem4">
+ <property name="name">menuitem4</property>
+ <property name="label" translatable="yes">_Help</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkAction" id="imagemenuitem10">
+ <property name="stock_id" translatable="yes">gtk-about</property>
+ <property name="name">imagemenuitem10</property>
+ <signal handler="about" name="activate"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <ui>
+ <menubar name="menubar1">
+ <menu action="menuitem1">
+ <menuitem action="imagemenuitem1"/>
+ <menuitem action="imagemenuitem2"/>
+ <menuitem action="imagemenuitem3"/>
+ <menuitem action="imagemenuitem4"/>
+ <separator/>
+ <menuitem action="imagemenuitem5"/>
+ </menu>
+ <menu action="menuitem2">
+ <menuitem action="imagemenuitem6"/>
+ <menuitem action="imagemenuitem7"/>
+ <menuitem action="imagemenuitem8"/>
+ <menuitem action="imagemenuitem9"/>
+ </menu>
+ <menuitem action="menuitem3"/>
+ <menu action="menuitem4">
+ <menuitem action="imagemenuitem10"/>
+ </menu>
+ </menubar>
+ </ui>
+ </object>
+ <object class="GtkWindow" id="window1">
+ <property name="title" translatable="yes">Text Editor</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="default_width">300</property>
+ <property name="default_height">200</property>
+ <property name="icon_name">accessories-text-editor</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkMenuBar" constructor="uimanager1" id="menubar1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="toolbar1">
+ <property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
+ <child>
+ <object class="GtkToolButton" id="toolbutton1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">New</property>
+ <property name="stock_id">gtk-new</property>
+ <signal handler="new" name="clicked"/>
+ </object>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Open</property>
+ <property name="stock_id">gtk-open</property>
+ <signal handler="open" name="clicked"/>
+ </object>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save</property>
+ <property name="stock_id">gtk-save</property>
+ <signal handler="save" name="clicked"/>
+ </object>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="toolbutton4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save as</property>
+ <property name="stock_id">gtk-save-as</property>
+ <signal handler="save-as" name="clicked"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <object class="GtkTextView" id="textview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkStatusbar" id="statusbar1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
#:test-notebook
#:test-calendar
#:test-box-child-property
- #:test-builder))
+ #:test-builder
+ #:demo-text-editor))
(in-package :gtk-demo)
(g-signal-connect (builder-get-object builder "window1") "destroy" (lambda (w) (declare (ignore w)) (gtk-main-quit)))
(status-bar-push (builder-get-object builder "statusbar1") "times" "0 times")
(widget-show (builder-get-object builder "window1"))
- (gtk-main)))
\ No newline at end of file
+ (gtk-main)))
+
+(defun read-text-file (file-name)
+ (with-output-to-string (str)
+ (with-open-file (file file-name)
+ (loop
+ for line = (read-line file nil nil)
+ while line
+ do (fresh-line str)
+ do (write-string line str)))))
+
+(defun demo-text-editor ()
+ (let* ((builder (aprog1 (make-instance 'builder)
+ (builder-add-from-file it (namestring (merge-pathnames "demo/text-editor.ui" *src-location*)))))
+ (window (builder-get-object builder "window1"))
+ (text-view (builder-get-object builder "textview1"))
+ (status-bar (builder-get-object builder "statusbar1"))
+ (file-name nil)
+ (modified-p t))
+ (status-bar-push status-bar "filename" "Untitled *")
+ (labels ((set-properties ()
+ (status-bar-pop status-bar "filename")
+ (status-bar-push status-bar "filename" (format nil "~A~:[~; *~]" (or file-name "Untitled") modified-p)))
+ (new (&rest args)
+ (setf file-name nil
+ modified-p t
+ (text-buffer-text (text-view-buffer text-view)) "")
+ (set-properties))
+ (cb-open (&rest args)
+ (let ((d (make-instance 'file-chooser-dialog :action :open :title "Open file")))
+ (when file-name (setf (file-chooser-filename d) file-name))
+ (dialog-add-button d "gtk-open" :accept)
+ (dialog-add-button d "gtk-cancel" :cancel)
+ (when (eq :accept (dialog-run d))
+ (setf file-name (file-chooser-filename d)
+ (text-buffer-text (text-view-buffer text-view)) (read-text-file file-name)
+ modified-p nil)
+ (set-properties))
+ (object-destroy d)))
+ (save (&rest args)
+ (if file-name
+ (progn
+ (with-open-file (file file-name :direction :output :if-exists :supersede)
+ (write-string (text-buffer-text (text-view-buffer text-view)) file))
+ (setf modified-p nil)
+ (set-properties))
+ (save-as)))
+ (save-as (&rest args)
+ (let ((d (make-instance 'file-chooser-dialog :action :save :title "Save file")))
+ (when file-name (setf (file-chooser-filename d) file-name))
+ (dialog-add-button d "gtk-save" :accept)
+ (dialog-add-button d "gtk-cancel" :cancel)
+ (if (eq :accept (dialog-run d))
+ (progn
+ (setf file-name (file-chooser-filename d))
+ (object-destroy d)
+ (save))
+ (object-destroy d))))
+ (cut (&rest args)
+ (text-buffer-cut-clipboard (text-view-buffer text-view) (get-clipboard "CLIPBOARD")))
+ (copy (&rest args)
+ (text-buffer-copy-clipboard (text-view-buffer text-view) (get-clipboard "CLIPBOARD")))
+ (paste (&rest args)
+ (text-buffer-paste-clipboard (text-view-buffer text-view) (get-clipboard "CLIPBOARD")))
+ (cb-delete (&rest args)
+ (let ((buffer (text-view-buffer text-view)))
+ (multiple-value-bind (i1 i2) (text-buffer-get-selection-bounds buffer)
+ (when (and i1 i2)
+ (text-buffer-delete buffer i1 i2)))))
+ (about (&rest args)
+ (let ((d (make-instance 'about-dialog
+ :program-name "Lisp Gtk+ Binding Demo Text Editor"
+ :version (format nil "0.0.0.1 ~A" #\GREEK_SMALL_LETTER_ALPHA)
+ :authors '("Kalyanov Dmitry")
+ :license "Public Domain"
+ :logo-icon-name "accessories-text-editor")))
+ (dialog-run d)
+ (object-destroy d)))
+ (quit (&rest args) (object-destroy window)))
+ (builder-connect-signals-simple builder `(("new" ,#'new)
+ ("open" ,#'cb-open)
+ ("save" ,#'save)
+ ("save-as" ,#'save-as)
+ ("cut" ,#'cut)
+ ("copy" ,#'copy)
+ ("paste" ,#'paste)
+ ("delete" ,#'cb-delete)
+ ("about" ,#'about)
+ ("quit" ,#'quit)))
+ (g-signal-connect window "destroy" (lambda (w) (declare (ignore w)) (gtk-main-quit)))
+ (g-signal-connect (text-view-buffer text-view) "changed" (lambda (b) (declare (ignore b)) (setf modified-p t) (set-properties)))
+ (widget-show window)
+ (gtk-main))))
\ No newline at end of file