Initial commit
This commit is contained in:
commit
1d2e4c0bf6
222
main.go
Normal file
222
main.go
Normal file
|
@ -0,0 +1,222 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gotk3/gotk3/glib"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
const appId = "com.github.gotk3.gotk3-examples.glade"
|
||||
|
||||
type App struct {
|
||||
app *gtk.Application
|
||||
|
||||
mw *gtk.ApplicationWindow
|
||||
|
||||
// The stack holds the views of the main window
|
||||
stack *gtk.Stack
|
||||
stackMain *gtk.Box
|
||||
stackAbout *gtk.Grid
|
||||
|
||||
// Detail stack variables
|
||||
stackDetail *gtk.Box
|
||||
detail struct {
|
||||
header *gtk.Label
|
||||
}
|
||||
|
||||
dynBtnBox *gtk.Box
|
||||
|
||||
dlgNew *gtk.FileChooserDialog
|
||||
listbox *gtk.ListBox
|
||||
}
|
||||
|
||||
func New() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := New()
|
||||
|
||||
// Create a new application.
|
||||
application, err := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)
|
||||
errorCheck(err)
|
||||
app.app = application
|
||||
|
||||
// Connect function to application startup event, this is not required.
|
||||
application.Connect("startup", func() {
|
||||
log.Println("application startup")
|
||||
})
|
||||
|
||||
// Connect function to application activate event
|
||||
application.Connect("activate", func() {
|
||||
log.Println("application activate")
|
||||
|
||||
// Get the GtkBuilder UI definition in the glade file.
|
||||
builder, err := gtk.BuilderNewFromFile("ui/app.glade")
|
||||
errorCheck(err)
|
||||
|
||||
// Map the handlers to callback functions, and connect the signals
|
||||
// to the Builder.
|
||||
signals := map[string]interface{}{
|
||||
"on_main_window_destroy": app.onMainWindowDestroy,
|
||||
"on_menu_home_activate": app.onBtnAboutBackClicked,
|
||||
"on_menu_new_activate": app.onMenuNewActivate,
|
||||
"on_menu_open_activate": app.onMenuOpenActivate,
|
||||
"on_menu_quit_activate": app.onMenuQuitActivate,
|
||||
"on_btn_about_clicked": app.onBtnAboutClicked,
|
||||
"on_btn_about_back_clicked": app.onBtnAboutBackClicked,
|
||||
"on_btn_detail_back_clicked": app.onBtnAboutBackClicked,
|
||||
}
|
||||
builder.ConnectSignals(signals)
|
||||
|
||||
// Get the object with the id of "main_window".
|
||||
obj, err := builder.GetObject("main_window")
|
||||
errorCheck(err)
|
||||
|
||||
// Verify that the object is a pointer to a gtk.ApplicationWindow.
|
||||
win, err := isWindow(obj)
|
||||
errorCheck(err)
|
||||
app.mw = win
|
||||
|
||||
stack, _ := builder.GetObject("mw_stack")
|
||||
app.stack = stack.(*gtk.Stack)
|
||||
|
||||
app.stackMain, _ = get(builder, "box_main").(*gtk.Box)
|
||||
app.stackAbout, _ = get(builder, "box_about").(*gtk.Grid)
|
||||
|
||||
app.stackDetail, _ = get(builder, "box_detail").(*gtk.Box)
|
||||
app.detail.header, _ = get(builder, "box_detail_header").(*gtk.Label)
|
||||
|
||||
app.dlgNew, _ = get(builder, "dlg_new_file").(*gtk.FileChooserDialog)
|
||||
app.listbox, _ = get(builder, "mw_list").(*gtk.ListBox)
|
||||
|
||||
app.dynBtnBox, _ = get(builder, "dyn_btn_box").(*gtk.Box)
|
||||
|
||||
for _, row := range []string{"First Button", "Second", "Third"} {
|
||||
app.AddButton(row)
|
||||
}
|
||||
|
||||
// for _, row := range []string{"First", "Second", "Third"} {
|
||||
// lbRow, err := gtk.ListBoxRowNew()
|
||||
// errorCheck(err)
|
||||
//
|
||||
// }
|
||||
|
||||
// Show the Window and all of its components.
|
||||
win.Show()
|
||||
application.AddWindow(win)
|
||||
})
|
||||
|
||||
// Connect function to application shutdown event, this is not required.
|
||||
application.Connect("shutdown", func() {
|
||||
log.Println("application shutdown")
|
||||
})
|
||||
|
||||
// Launch the application
|
||||
os.Exit(application.Run(os.Args))
|
||||
}
|
||||
|
||||
func isWindow(obj glib.IObject) (*gtk.ApplicationWindow, error) {
|
||||
// Make type assertion (as per gtk.go).
|
||||
if win, ok := obj.(*gtk.ApplicationWindow); ok {
|
||||
return win, nil
|
||||
}
|
||||
return nil, errors.New("not a *gtk.Window")
|
||||
}
|
||||
|
||||
func get(builder *gtk.Builder, name string) glib.IObject {
|
||||
v, err := builder.GetObject(name)
|
||||
errorCheck(err)
|
||||
return v
|
||||
}
|
||||
|
||||
func errorCheck(e error) {
|
||||
if e != nil {
|
||||
// panic for any errors.
|
||||
log.Panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
// adds a button to the dynBtnBox
|
||||
func (a *App) AddButton(label string) {
|
||||
btn, err := gtk.ButtonNewWithLabel(label)
|
||||
errorCheck(err)
|
||||
|
||||
btn.Connect("clicked", func() {
|
||||
a.gotoDetailScreen(label)
|
||||
})
|
||||
|
||||
// PackEnd(widget, expand, fill, padding)
|
||||
a.dynBtnBox.PackStart(btn, false, true, 0)
|
||||
btn.Show()
|
||||
}
|
||||
|
||||
// onMainWindowDestory is the callback that is linked to the
|
||||
// on_main_window_destroy handler. It is not required to map this,
|
||||
// and is here to simply demo how to hook-up custom callbacks.
|
||||
func (a *App) onMainWindowDestroy() {
|
||||
log.Println("onMainWindowDestroy")
|
||||
}
|
||||
|
||||
func (a *App) onMenuNewActivate() {
|
||||
log.Println("new clicked")
|
||||
a.dlgNew.Show()
|
||||
}
|
||||
|
||||
func (a *App) onMenuOpenActivate() {
|
||||
log.Println("open clicked")
|
||||
|
||||
dialog, err := gtk.FileChooserDialogNewWith2Buttons(
|
||||
"Open File...",
|
||||
a.mw,
|
||||
gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
"Cancel",
|
||||
gtk.RESPONSE_DELETE_EVENT,
|
||||
"Open",
|
||||
gtk.RESPONSE_ACCEPT)
|
||||
errorCheck(err)
|
||||
|
||||
filter, _ := gtk.FileFilterNew()
|
||||
filter.AddPattern("*.jpg")
|
||||
filter.SetName("JPEG images")
|
||||
dialog.AddFilter(filter)
|
||||
|
||||
switcher := dialog.Run()
|
||||
log.Printf("switcher: %d\n", switcher)
|
||||
filename := dialog.GetFilename()
|
||||
dialog.Destroy()
|
||||
|
||||
if switcher != -3 {
|
||||
fmt.Printf("user canceled\n")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("chosen: %s\n", filename)
|
||||
|
||||
}
|
||||
|
||||
func (a *App) onMenuQuitActivate() {
|
||||
a.mw.Destroy()
|
||||
// os.Exit(0) // TODO: more graceful
|
||||
}
|
||||
|
||||
func (a *App) onBtnAboutClicked() {
|
||||
fmt.Println("about clicked")
|
||||
a.stack.SetTransitionType(gtk.STACK_TRANSITION_TYPE_SLIDE_LEFT)
|
||||
a.stack.SetVisibleChild(a.stackAbout)
|
||||
}
|
||||
|
||||
func (a *App) onBtnAboutBackClicked() {
|
||||
a.stack.SetTransitionType(gtk.STACK_TRANSITION_TYPE_SLIDE_RIGHT)
|
||||
a.stack.SetVisibleChild(a.stackMain)
|
||||
}
|
||||
|
||||
func (a *App) gotoDetailScreen(label string) {
|
||||
a.detail.header.SetText("Detail: " + label)
|
||||
a.stack.SetTransitionType(gtk.STACK_TRANSITION_TYPE_SLIDE_LEFT)
|
||||
a.stack.SetVisibleChild(a.stackDetail)
|
||||
}
|
331
ui/app.glade
Normal file
331
ui/app.glade
Normal file
|
@ -0,0 +1,331 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.36.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<object class="GtkFileChooserDialog" id="dlg_new_file">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Choose your file</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="file-activated" handler="on_new_file_selected" swapped="no"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Accept</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu_home">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Home</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_home_activate" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu_new">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_new_activate" swapped="no"/>
|
||||
<accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu_open">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Open</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_open_activate" swapped="no"/>
|
||||
<accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu_save">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_save_activate" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu_quit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Quit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_quit_activate" swapped="no"/>
|
||||
<accelerator key="F4" signal="activate" modifiers="GDK_MOD1_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="main_window">
|
||||
<property name="width_request">360</property>
|
||||
<property name="height_request">720</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_menubar">False</property>
|
||||
<signal name="destroy" handler="on_main_window_destroy" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkStack" id="mw_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_main">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="mw_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dyn_btn_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Glade button</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btn_about">
|
||||
<property name="label" translatable="yes">About</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_btn_about_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page0</property>
|
||||
<property name="title" translatable="yes">page0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="box_about">
|
||||
<property name="name">stack_about</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">The About Screen!</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btn_about_back">
|
||||
<property name="label" translatable="yes">Back</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_btn_about_back_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="yes">page1</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_detail">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="box_detail_header">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<attributes>
|
||||
<attribute name="font-desc" value="Sans Bold 18"/>
|
||||
<attribute name="foreground" value="#cccc00000000"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btn_detail_back">
|
||||
<property name="label" translatable="yes">Back to Menu</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_btn_detail_back_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page2</property>
|
||||
<property name="title" translatable="yes">page2</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Hello world</property>
|
||||
<property name="subtitle" translatable="yes">Test</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="main_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="popup">menu1</property>
|
||||
<property name="use_popover">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
Loading…
Reference in New Issue
Block a user