You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

238 lines
6.8 KiB

package ui
import (
"reflect"
"os"
"log"
"errors"
"strconv"
"github.com/gotk3/gotk3/gtk"
"github.com/gotk3/gotk3/gdk"
)
const appId = "com.snaums.gotoot"
var Version string
var BuildDate string
var BuildWith string
var GladeString string
func PlaceHolder ( page *gtk.Box ) ( *gtk.Box ) {
page.GetChildren().FreeFull ( func ( w interface{} ) {
x, ok := w.(*gtk.Widget)
if ok == true {
x.Destroy()
}
})
spinner, err := gtk.SpinnerNew ()
if err != nil {
return nil
}
spinner.Start()
box, _ := gtk.BoxNew ( gtk.ORIENTATION_HORIZONTAL, 0 )
box.Add ( spinner )
page.Add ( box )
page.ShowAll()
return box
}
func NoEntries ( page *gtk.Box, txt string ) {
lbl, err := gtk.LabelNew ( txt )
if err != nil {
return
}
lbl.SetSingleLineMode ( false )
page.Add ( lbl )
page.ShowAll()
return
}
func pixVariantGetPixbuf ( url string, variant int ) ( *gdk.Pixbuf, error ) {
var varname string = strconv.Itoa(variant) + "px"
var px *gdk.Pixbuf = nil
x, err := cache.GetVariant ( url, varname )
if err != nil {
x, lp, err := cache.PutVariantUser ( url, varname )
if ( err == nil || err.Error() == "Variant already exists" ) && lp != "" {
px, err = SimpleScale ( lp, -1, variant )
if err == nil {
err = px.SaveJPEG ( x, 95 )
if err == nil {
return px, nil
} else {
return px, nil
}
}
}
return nil,err
} else {
px, err = gdk.PixbufNewFromFile ( x )
if err != nil {
return nil, err
}
return px, err
}
}
func pixVariantGet ( url string, variant int ) ( string, error ) {
var varname string = strconv.Itoa(variant) + "px"
x, err := cache.GetVariant ( url, varname )
if err != nil {
x, lp, err := cache.PutVariantUser ( url, varname )
if ( err == nil || err.Error() == "Variant already exists" ) && lp != "" {
px, err := SimpleScale ( lp, -1, variant )
if err == nil {
err = px.SaveJPEG ( x, 95 )
if err == nil {
return x, nil
}
}
}
return "",err
} else {
return x, nil
}
}
func HandleError ( err error ) error {
if err == nil {
return nil
}
e, ok := err.(*tootError)
if ok == true {
log.Println (" error: ", e )
if e.FollowUp == ShowModal {
modal ( e.Msg )
return nil
} else if e.FollowUp == ShowSetup {
SetupWin.Window.Show()
return errors.New("")
} else if e.FollowUp == Ignore {
return nil
} else {
log.Println ("Unrecognized Error type", e.FollowUp)
}
} else {
modal ( err.Error() )
}
return nil
}
func SimpleScale ( filename string, targetWidth int, targetHeight int ) ( *gdk.Pixbuf, error ) {
px, err := gdk.PixbufNewFromFile ( filename )
if err != nil {
return nil, err
}
iw := px.GetWidth()
ih := px.GetHeight()
var aspect float64 = (float64(iw) / float64(ih))
var tw int = targetWidth
var th int = targetHeight
if targetWidth <= 0 && targetHeight <= 0 {
log.Println ("Both width and height are lower than 0")
return nil, errors.New("Width and height are lower than 0")
} else if targetWidth <= 0 {
tw = int(float64(th)*aspect)
} else if targetHeight <= 0 {
th = int(float64(tw)/aspect)
} // else both are valid is already the default values of th and tw
//log.Println ( iw, ih, aspect, tw, th )
px, err = px.ScaleSimple ( tw, th, gdk.INTERP_BILINEAR )
if err != nil {
return nil, err
}
return px, nil
}
func discoverWidgetsInner ( GtkBuilder *gtk.Builder, current reflect.Value, prefix string ) error {
var err error
tp := current.Type()
if tp.Kind() != reflect.Struct {
return errors.New ("Interface is not a struct")
}
//log.Println ("Input Kind: ", tp.Kind().String())
for i := 0; i < tp.NumField(); i++ {
f := current.Field ( i )
t := tp.Field(i)
switch t.Type.Kind() {
case reflect.Ptr:
switch f.Type().Elem().Name() {
case "Window","Label", "Entry", "Button", "CheckButton", "TextView", "RadioButton", "ToggleButton", "Box", "Image", "FlowBoxChild", "FlowBox", "ListBox", "Notebook", "HeaderBar", "Popover", "PopoverMenu", "Calendar", "SpinButton", "Grid", "Viewport":
//log.Println( "(", i , ") Trying to resolve: ", prefix + t.Name )
obj, err := GtkBuilder.GetObject ( prefix + t.Name )
if err != nil {
log.Println ("ERROR! Cannot find object: ", prefix+t.Name)
} else {
//log.Println ("f.Kind: ", f.Type().Kind().String())
//c := reflect.ValueOf(obj)
//log.Println ("obj.Kind: ", c.Type().Kind().String())
f.Set(reflect.ValueOf(obj))
}
case "Application":
f.Set(reflect.ValueOf(application))
default:
log.Println ("Unknown type or value ", f.Type().Elem().Name(), f.Type().PkgPath())
}
case reflect.Struct:
err = discoverWidgetsInner ( GtkBuilder, f, prefix+t.Name )
if err != nil {
log.Println ("An Error occurred while recursing into Discover Widgets: ", err)
}
}
}
return nil
}
func Reset ( pl interface{} ) error {
// ToDo
return nil
}
func DiscoverWidgets ( GtkBuilder *gtk.Builder, pl interface{}, prefix string ) error {
current := reflect.Indirect ( reflect.ValueOf( pl ) )
return discoverWidgetsInner ( GtkBuilder, current, prefix )
}
func createGtkBuilder () (*gtk.Builder, error ) {
GtkBuilder, err := gtk.BuilderNew()
if err != nil {
return nil, err
}
info, err := os.Stat ("ui/views.glade");
if os.IsNotExist ( err ) || info.Mode().IsRegular() == false {
err = GtkBuilder.AddFromString ( GladeString );
} else {
err = GtkBuilder.AddFromFile ("ui/views.glade");
}
if err != nil {
return nil, err;
}
return GtkBuilder, err
}
func modal ( text string ) {
obj := gtk.MessageDialogNew (
nil,
gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_WARNING,
gtk.BUTTONS_OK,
text );
obj.SetDefaultResponse ( gtk.RESPONSE_OK );
obj.Connect ( "response", func () {
obj.Destroy();
});
obj.Run();
}