Merge pull request #6 from CalebQ42/gtkUI

Gtk ui
This commit is contained in:
Belac Darkstorm
2017-04-04 18:36:18 -05:00
committed by GitHub
9 changed files with 783 additions and 304 deletions
+225 -189
View File
@@ -5,8 +5,8 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"github.com/nelsam/gxui" "github.com/gotk3/gotk3/gdk"
"github.com/nelsam/gxui/math" "github.com/gotk3/gotk3/gtk"
) )
type app struct { type app struct {
@@ -15,94 +15,35 @@ type app struct {
appimg []string appimg []string
lin []string lin []string
ex []string ex []string
icon gxui.Texture icon *gdk.Pixbuf
dir string dir string
ini *os.File ini *os.File
} }
type appExNode struct { func (a *app) getTreeIter(store *gtk.TreeStore) *gtk.TreeIter {
ap app it := store.Append(nil)
exInd int store.SetValue(it, 0, a.icon)
store.SetValue(it, 1, a.name)
if len(a.ex) > 1 {
for _, v := range a.ex {
i := store.Append(it)
store.SetValue(i, 1, v)
}
}
return it
} }
func (a *appExNode) launch() { func (a *app) launch() {
if len(a.ex) == 1 {
if wine { if wine {
var cmd *exec.Cmd var cmd *exec.Cmd
if !contains(a.ap.lin, a.ap.ex[a.exInd]) { if !contains(a.lin, a.ex[0]) {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; wine \""+a.ap.ex[a.exInd]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; wine \""+a.ex[0]+"\"")
} else { } else {
if comEnbld { if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"") cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"")
} else { } else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"")
}
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
}
var cmd *exec.Cmd
if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
} else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
}
func (a *appExNode) Count() int {
return 0
}
func (a *appExNode) NodeAt(int) gxui.TreeNode {
return nil
}
func (a *appExNode) ItemIndex(gxui.AdapterItem) int {
return -1
}
func (a *appExNode) Item() gxui.AdapterItem {
if wine {
return a.ap.ex[a.exInd]
}
return a.ap.lin[a.exInd]
}
func (a *appExNode) Create(the gxui.Theme) gxui.Control {
box := the.CreateLinearLayout()
box.SetDirection(gxui.LeftToRight)
box.SetVerticalAlignment(gxui.AlignMiddle)
img := the.CreateImage()
img.SetTexture(a.ap.icon)
img.SetExplicitSize(math.Size{H: 32, W: 32})
lbl := the.CreateLabel()
lbl.SetText(a.ap.ex[a.exInd])
box.AddChild(img)
box.AddChild(lbl)
box.OnDoubleClick(func(gxui.MouseEvent) {
a.launch()
})
return box
}
type appNode struct {
ap app
}
func (a *appNode) launch() {
if len(a.ap.ex) == 1 {
if wine {
var cmd *exec.Cmd
if !contains(a.ap.lin, a.ap.ex[0]) {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; wine \""+a.ap.ex[0]+"\"")
} else {
if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[0]+"\"")
} else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[0]+"\"")
} }
} }
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
@@ -111,9 +52,9 @@ func (a *appNode) launch() {
} else { } else {
var cmd *exec.Cmd var cmd *exec.Cmd
if comEnbld { if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[0]+"\"") cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"")
} else { } else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[0]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[0]+"\"")
} }
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@@ -122,29 +63,29 @@ func (a *appNode) launch() {
} else { } else {
if wine { if wine {
var cmd *exec.Cmd var cmd *exec.Cmd
if len(a.ap.lin) == 0 { if len(a.lin) == 0 {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; wine \""+a.ap.ex[0]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; wine \""+a.ex[0]+"\"")
} else { } else {
var ind int var ind int
for i, v := range a.ap.lin { for i, v := range a.lin {
if strings.HasSuffix(v, ".sh") { if strings.HasSuffix(v, ".sh") {
ind = i ind = i
break break
} }
} }
if comEnbld { if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.lin[ind]+"\"") cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"")
} else { } else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.lin[ind]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"")
} }
} }
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Start() cmd.Start()
} else { } else {
if len(a.ap.lin) != 0 { if len(a.lin) != 0 {
var ind int var ind int
for i, v := range a.ap.lin { for i, v := range a.lin {
if strings.HasSuffix(v, ".sh") { if strings.HasSuffix(v, ".sh") {
ind = i ind = i
break break
@@ -152,9 +93,9 @@ func (a *appNode) launch() {
} }
var cmd *exec.Cmd var cmd *exec.Cmd
if comEnbld { if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.lin[ind]+"\"") cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"")
} else { } else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.lin[ind]+"\"") cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.lin[ind]+"\"")
} }
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@@ -164,109 +105,204 @@ func (a *appNode) launch() {
} }
} }
func (a *appNode) Count() int { func (a *app) launchSub(sub int) {
if wine { if wine {
if len(a.ap.ex) > 1 { var cmd *exec.Cmd
return len(a.ap.ex) if !contains(a.lin, a.ex[sub]) {
} cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; wine \""+a.ex[sub]+"\"")
return 0
}
if len(a.ap.lin) > 1 {
return len(a.ap.lin)
}
return 0
}
func (a *appNode) NodeAt(i int) gxui.TreeNode {
return &appExNode{ap: a.ap, exInd: i}
}
func (a *appNode) ItemIndex(item gxui.AdapterItem) int {
if wine {
for i, v := range a.ap.ex {
if v == item {
return i
}
}
} else { } else {
for i, v := range a.ap.lin { if comEnbld {
if v == item { cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"")
return i
}
}
}
return -1
}
func (a *appNode) Item() gxui.AdapterItem {
return a.ap.name
}
func (a *appNode) Create(the gxui.Theme) gxui.Control {
box := the.CreateLinearLayout()
box.SetDirection(gxui.LeftToRight)
box.SetPadding(math.CreateSpacing(2))
box.SetVerticalAlignment(gxui.AlignMiddle)
img := the.CreateImage()
if a.ap.icon != nil {
img.SetTexture(a.ap.icon)
}
img.SetExplicitSize(math.Size{H: 32, W: 32})
lbl := the.CreateLabel()
lbl.SetText(a.ap.name)
box.AddChild(img)
box.AddChild(lbl)
box.OnDoubleClick(func(gxui.MouseEvent) {
a.launch()
})
return box
}
type catAdap struct {
gxui.AdapterBase
cat string
}
func (a *catAdap) setCat(cat string) {
a.cat = cat
a.DataChanged(false)
}
func (a *catAdap) refresh() {
a.DataChanged(false)
}
func (a *catAdap) Count() int {
if wine {
return len(master[a.cat])
}
return len(linmaster[a.cat])
}
func (a *catAdap) NodeAt(i int) gxui.TreeNode {
if wine {
return &appNode{ap: master[a.cat][i]}
}
return &appNode{ap: linmaster[a.cat][i]}
}
func (a *catAdap) Size(gxui.Theme) math.Size {
return math.Size{H: 34, W: math.MaxSize.W}
}
func (a *catAdap) ItemIndex(item gxui.AdapterItem) int {
if wine {
for i, v := range master[a.cat] {
if v.name == item {
return i
}
}
} else { } else {
for i, v := range linmaster[a.cat] { cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"")
if v.name == item {
return i
} }
} }
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
} }
return -1 var cmd *exec.Cmd
if comEnbld {
cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"")
} else {
cmd = exec.Command("/bin/sh", "-c", "cd \""+a.dir+"\"; \"./"+a.ex[sub]+"\"")
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
} }
// type appExNode struct {
// ap app
// exInd int
// }
//
// func (a *appExNode) launch() {
// if wine {
// var cmd *exec.Cmd
// if !contains(a.ap.lin, a.ap.ex[a.exInd]) {
// cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; wine \""+a.ap.ex[a.exInd]+"\"")
// } else {
// if comEnbld {
// cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
// } else {
// cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
// }
// }
// cmd.Stdout = os.Stdout
// cmd.Stderr = os.Stderr
// cmd.Start()
// }
// var cmd *exec.Cmd
// if comEnbld {
// cmd = exec.Command("/bin/sh", "-c", ". PortableApps/LinuxPACom/common.sh || exit 1;cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
// } else {
// cmd = exec.Command("/bin/sh", "-c", "cd \""+a.ap.dir+"\"; \"./"+a.ap.ex[a.exInd]+"\"")
// }
// cmd.Stdout = os.Stdout
// cmd.Stderr = os.Stderr
// cmd.Start()
// }
// func (a *appExNode) Count() int {
// return 0
// }
//
// func (a *appExNode) NodeAt(int) gxui.TreeNode {
// return nil
// }
//
// func (a *appExNode) ItemIndex(gxui.AdapterItem) int {
// return -1
// }
//
// func (a *appExNode) Item() gxui.AdapterItem {
// if wine {
// return a.ap.ex[a.exInd]
// }
// return a.ap.lin[a.exInd]
// }
//
// func (a *appExNode) Create(the gxui.Theme) gxui.Control {
// box := the.CreateLinearLayout()
// box.SetDirection(gxui.LeftToRight)
// box.SetVerticalAlignment(gxui.AlignMiddle)
// img := the.CreateImage()
// img.SetTexture(a.ap.icon)
// img.SetExplicitSize(math.Size{H: 32, W: 32})
// lbl := the.CreateLabel()
// lbl.SetText(a.ap.ex[a.exInd])
// box.AddChild(img)
// box.AddChild(lbl)
// box.OnDoubleClick(func(gxui.MouseEvent) {
// a.launch()
// })
// return box
// }
// func (a *appNode) Count() int {
// if wine {
// if len(a.ex) > 1 {
// return len(a.ap.ex)
// }
// return 0
// }
// if len(a.ap.lin) > 1 {
// return len(a.ap.lin)
// }
// return 0
// }
//
// func (a *appNode) NodeAt(i int) gxui.TreeNode {
// return &appExNode{ap: a.ap, exInd: i}
// }
//
// func (a *appNode) ItemIndex(item gxui.AdapterItem) int {
// if wine {
// for i, v := range a.ap.ex {
// if v == item {
// return i
// }
// }
// } else {
// for i, v := range a.ap.lin {
// if v == item {
// return i
// }
// }
// }
// return -1
// }
//
// func (a *appNode) Item() gxui.AdapterItem {
// return a.ap.name
// }
//
// func (a *appNode) Create(the gxui.Theme) gxui.Control {
// box := the.CreateLinearLayout()
// box.SetDirection(gxui.LeftToRight)
// box.SetPadding(math.CreateSpacing(2))
// box.SetVerticalAlignment(gxui.AlignMiddle)
// img := the.CreateImage()
// if a.ap.icon != nil {
// img.SetTexture(a.ap.icon)
// }
// img.SetExplicitSize(math.Size{H: 32, W: 32})
// lbl := the.CreateLabel()
// lbl.SetText(a.ap.name)
// box.AddChild(img)
// box.AddChild(lbl)
// box.OnDoubleClick(func(gxui.MouseEvent) {
// a.launch()
// })
// return box
// }
// type catAdap struct {
// gxui.AdapterBase
// cat string
// }
//
// func (a *catAdap) setCat(cat string) {
// a.cat = cat
// a.DataChanged(false)
// }
//
// func (a *catAdap) refresh() {
// a.DataChanged(false)
// }
//
// func (a *catAdap) Count() int {
// if wine {
// return len(master[a.cat])
// }
// return len(linmaster[a.cat])
// }
//
// func (a *catAdap) NodeAt(i int) gxui.TreeNode {
// if wine {
// return &appNode{ap: master[a.cat][i]}
// }
// return &appNode{ap: linmaster[a.cat][i]}
// }
//
// func (a *catAdap) Size(gxui.Theme) math.Size {
// return math.Size{H: 34, W: math.MaxSize.W}
// }
//
// func (a *catAdap) ItemIndex(item gxui.AdapterItem) int {
// if wine {
// for i, v := range master[a.cat] {
// if v.name == item {
// return i
// }
// }
// } else {
// for i, v := range linmaster[a.cat] {
// if v.name == item {
// return i
// }
// }
// }
// return -1
// }
+82
View File
@@ -0,0 +1,82 @@
package main
import (
"fmt"
"os"
"os/exec"
"github.com/nelsam/gxui"
"github.com/nelsam/gxui/drivers/gl"
"github.com/nelsam/gxui/themes/dark"
"github.com/nelsam/gxui/themes/light"
)
const (
version = "1.1.0.0"
defIni = "[basic]\ntheme=dk"
)
var (
dr gxui.Driver
th gxui.Theme
master map[string][]app
linmaster map[string][]app
cats []string
lin []string
wine bool
comEnbld bool
darkTheme = true
)
func main() {
updated := false
os.MkdirAll("PortableApps/LinuxPACom", 0777)
stat, err := versionDL()
if stat {
res := getVersionFileInfo()
if res != "Error!" {
stat, err = checkForUpdate(res)
if stat {
downloadUpdate(res)
updated = true
} else {
fmt.Println(err)
}
} else {
fmt.Println("Failed Version File Info")
}
} else {
fmt.Println(err)
}
if updated {
cmd := exec.Command("./LinuxPA")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Start()
} else {
master = make(map[string][]app)
linmaster = make(map[string][]app)
gl.StartDriver(appMain)
}
}
func appMain(dri gxui.Driver) {
dr = dri
setup()
if darkTheme {
th = dark.CreateTheme(dr)
} else {
th = light.CreateTheme(dr)
}
th = dark.CreateTheme(dr)
ui()
}
func contains(arr []string, str string) bool {
for _, v := range arr {
if v == str {
return true
}
}
return false
}
+208
View File
@@ -0,0 +1,208 @@
package main
import (
"bufio"
"fmt"
"image"
"image/draw"
_ "image/png"
"os"
"reflect"
"sort"
"strings"
"github.com/nelsam/gxui"
)
func setup() {
PortableAppsFold, err := os.Open("PortableApps")
if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() {
os.Mkdir("PortableApps", 0777)
PortableAppsFold, err = os.Open("PortableApps")
if err != nil {
panic("Can't find PortableApps folder and can't create one!")
}
}
if _, err = os.Open("PortableApps/LinuxPACom"); err != nil {
os.Mkdir("PortableApps/LinuxPACom", 0777)
}
fmt.Println(err)
_, err = os.Open("PortableApps/LinuxPACom/common.sh")
if err == nil {
comEnbld = true
}
fi, err := os.Open("PortableApps/LinuxPACom/Info.ini")
if err != nil {
fi, err = os.Create("PortableApps/LinuxPACom/Info.ini")
if err == nil {
wrt := bufio.NewWriter(fi)
wrt.WriteString(defIni)
wrt.Flush()
}
}
if err == nil {
rdr := bufio.NewReader(fi)
for err != nil {
ln, _, error := rdr.ReadLine()
err = error
str := string(ln)
if strings.HasPrefix(str, "theme=") {
str = strings.TrimPrefix(str, "theme=")
if str == "lt" {
darkTheme = false
}
}
}
}
PAFolds, _ := PortableAppsFold.Readdirnames(-1)
sort.Strings(PAFolds)
for _, v := range PAFolds {
fold, _ := os.Open("PortableApps/" + v)
if stat, _ := fold.Stat(); stat.IsDir() && stat.Name() != "PortableApps.com" && stat.Name() != "LinuxPACom" {
ap := processApp("PortableApps/" + v)
if !reflect.DeepEqual(ap, app{}) {
if _, ok := master[ap.cat]; !ok {
cats = append(cats, ap.cat)
sort.Strings(cats)
}
if len(ap.lin) != 0 {
if _, ok := linmaster[ap.cat]; !ok {
lin = append(lin, ap.cat)
sort.Strings(lin)
}
}
master[ap.cat] = append(master[ap.cat], ap)
if len(ap.lin) != 0 {
linmaster[ap.cat] = append(linmaster[ap.cat], ap)
}
}
}
}
}
func processApp(fold string) (out app) {
wd, _ := os.Getwd()
out.dir = wd + "/" + fold
out.ini = findInfo(fold)
if out.ini != nil {
out.name = getName(out.ini)
out.ini = findInfo(fold)
out.cat = getCat(out.ini)
out.ini = findInfo(fold)
}
if out.name == "" {
out.name = strings.TrimPrefix(fold, "PortableApps/")
}
if out.cat == "" {
out.cat = "Other"
}
out.icon = getIcon(fold)
folder, _ := os.Open(fold)
fis, _ := folder.Readdirnames(-1)
for _, v := range fis {
tmp, _ := os.Open(fold + "/" + v)
if stat, _ := tmp.Stat(); stat.IsDir() {
continue
}
if strings.HasSuffix(strings.ToLower(v), ".appimage") {
out.appimg = append(out.appimg, v)
out.ex = append(out.ex, v)
out.lin = append(out.lin, v)
} else if strings.HasSuffix(strings.ToLower(v), ".exe") {
out.ex = append(out.ex, v)
} else {
btys := make([]byte, 4)
rdr := bufio.NewReader(tmp)
rdr.Read(btys)
if (strings.Contains(strings.ToLower(string(btys)), "elf") && !strings.HasSuffix(strings.ToLower(v), ".so") && !strings.Contains(v, ".so.")) || strings.HasPrefix(strings.ToLower(string(btys)), "#!") {
out.ex = append(out.ex, v)
out.lin = append(out.lin, v)
}
}
}
if len(out.ex) == 0 {
return app{}
}
if len(out.lin) == 0 {
out.name += " (Wine)"
}
return
}
func getCat(ini *os.File) string {
rdr := bufio.NewReader(ini)
var ret string
for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() {
if strings.HasPrefix(string(line), "Category=") {
ret = strings.TrimPrefix(string(line), "Category=")
break
}
}
rdr.Reset(ini)
return ret
}
func getName(ini *os.File) string {
rdr := bufio.NewReader(ini)
var ret string
for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() {
if strings.HasPrefix(string(line), "Name=") {
ret = strings.TrimPrefix(string(line), "Name=")
break
}
}
rdr.Reset(ini)
return ret
}
func getIcon(fold string) gxui.Texture {
var pic *os.File
if folder, err := os.Open(fold + "/App/AppInfo"); err == nil {
fis, _ := folder.Readdir(-1)
var pics []string
for _, v := range fis {
if !v.IsDir() && strings.HasSuffix(strings.ToLower(v.Name()), ".png") && strings.HasPrefix(strings.ToLower(v.Name()), "appicon_") {
pics = append(pics, v.Name())
}
}
sort.Strings(pics)
if len(pics) > 1 {
var ind int
if !contains(pics, "appicon_32.png") {
ind = len(pics) - 1
} else {
ind = sort.SearchStrings(pics, "appicon_32.png")
}
pic, _ = os.Open(fold + "/App/AppInfo/" + pics[ind])
}
} else if fi, err := os.Open(fold + "/appicon.png"); err == nil {
pic = fi
} else {
return nil
}
img, _, err := image.Decode(pic)
if err != nil {
return nil
}
rgba := image.NewRGBA(img.Bounds())
draw.Draw(rgba, img.Bounds(), img, image.ZP, draw.Src)
ret := dr.CreateTexture(rgba, 1)
return ret
}
func findInfo(fold string) *os.File {
tmp, err := os.Open(fold + "/App/AppInfo")
if err == nil {
fis, _ := tmp.Readdirnames(-1)
for _, v := range fis {
if strings.ToLower(v) == "appinfo.ini" {
tmp, _ := os.Open(fold + "/App/AppInfo/" + v)
return tmp
}
}
}
if fi, err := os.Open(fold + "/appinfo.ini"); err == nil {
return fi
}
return nil
}
View File
+66
View File
@@ -0,0 +1,66 @@
package main
import (
"os"
"os/exec"
"github.com/nelsam/gxui"
)
func ui() {
catListAdap := &StrList{}
appListAdap := &catAdap{}
catListAdap.SetStrings(lin)
win := th.CreateWindow(500, 500, "LinuxPA")
top := th.CreateLinearLayout()
top.SetDirection(gxui.BottomToTop)
splBox := th.CreateLinearLayout()
spl := th.CreateSplitterLayout()
spl.SetOrientation(gxui.Horizontal)
catList := th.CreateList()
catList.SetAdapter(catListAdap)
catList.OnSelectionChanged(func(it gxui.AdapterItem) {
appListAdap.setCat(it.(string))
})
appList := th.CreateTree()
appList.SetAdapter(appListAdap)
spl.AddChild(catList)
spl.AddChild(appList)
splBox.AddChild(spl)
butBox := th.CreateLinearLayout()
butBox.SetDirection(gxui.LeftToRight)
if _, err := exec.LookPath("wine"); err == nil {
wineBut := th.CreateButton()
wineBut.SetType(gxui.ToggleButton)
wineBut.SetChecked(wine)
wineBut.SetText("Show Windows Apps")
wineBut.OnClick(func(gxui.MouseEvent) {
wine = wineBut.IsChecked()
appListAdap.refresh()
if wineBut.IsChecked() {
catListAdap.SetStrings(cats)
wineBut.SetText("Hide Windows Apps")
} else {
catListAdap.SetStrings(lin)
wineBut.SetText("Show Windows Apps")
}
})
_, err := os.Open("Start.exe")
if err == nil {
pa := th.CreateButton()
pa.SetText("Open PortableApps Launcher")
pa.OnClick(func(gxui.MouseEvent) {
cmd := exec.Command("wine", "Start.exe")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
})
butBox.AddChild(pa)
}
butBox.AddChild(wineBut)
}
top.AddChild(butBox)
top.AddChild(splBox)
win.AddChild(top)
win.OnClose(dr.Terminate)
}
+20 -43
View File
@@ -3,22 +3,16 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"os/exec"
"github.com/nelsam/gxui" "github.com/gotk3/gotk3/gtk"
"github.com/nelsam/gxui/drivers/gl"
"github.com/nelsam/gxui/themes/dark"
"github.com/nelsam/gxui/themes/light"
) )
const ( const (
version = "1.1.0.0" version = "2.0.0.1"
defIni = "[basic]\ntheme=dk" defIni = ""
) )
var ( var (
dr gxui.Driver
th gxui.Theme
master map[string][]app master map[string][]app
linmaster map[string][]app linmaster map[string][]app
cats []string cats []string
@@ -29,47 +23,30 @@ var (
) )
func main() { func main() {
updated := false
os.MkdirAll("PortableApps/LinuxPACom", 0777) os.MkdirAll("PortableApps/LinuxPACom", 0777)
stat, err := versionDL()
if stat {
res := getVersionFileInfo()
if res != "Error!" {
stat, err = checkForUpdate(res)
if stat {
downloadUpdate(res)
updated = true
} else {
fmt.Println(err)
}
} else {
fmt.Println("Failed Version File Info")
}
} else {
fmt.Println(err)
}
if updated {
cmd := exec.Command("./LinuxPA")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Start()
} else {
master = make(map[string][]app) master = make(map[string][]app)
linmaster = make(map[string][]app) linmaster = make(map[string][]app)
gl.StartDriver(appMain) uiStart()
}
} }
func appMain(dri gxui.Driver) { func uiStart() {
dr = dri gtk.Init(nil)
setup() setup()
if darkTheme { win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
th = dark.CreateTheme(dr) if err != nil {
} else { fmt.Println("Window not created", err)
th = light.CreateTheme(dr)
} }
th = dark.CreateTheme(dr) win.SetTitle("LinuxPA")
ui() win.Connect("destroy", func() {
gtk.MainQuit()
})
win.SetDefaultSize(500, 500)
win.SetPosition(gtk.WIN_POS_CENTER)
ui(win)
win.ShowAll()
win.Show()
update(win)
gtk.Main()
} }
func contains(arr []string, str string) bool { func contains(arr []string, str string) bool {
+13 -19
View File
@@ -3,19 +3,16 @@ package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"image"
"image/draw"
_ "image/png" _ "image/png"
"os" "os"
"reflect" "reflect"
"sort" "sort"
"strings" "strings"
"github.com/nelsam/gxui" "github.com/gotk3/gotk3/gdk"
"github.com/gotk3/gotk3/gtk"
) )
const ()
func setup() { func setup() {
PortableAppsFold, err := os.Open("PortableApps") PortableAppsFold, err := os.Open("PortableApps")
if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() { if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() {
@@ -157,8 +154,8 @@ func getName(ini *os.File) string {
return ret return ret
} }
func getIcon(fold string) gxui.Texture { func getIcon(fold string) *gdk.Pixbuf {
var pic *os.File var pic string
if folder, err := os.Open(fold + "/App/AppInfo"); err == nil { if folder, err := os.Open(fold + "/App/AppInfo"); err == nil {
fis, _ := folder.Readdir(-1) fis, _ := folder.Readdir(-1)
var pics []string var pics []string
@@ -175,21 +172,18 @@ func getIcon(fold string) gxui.Texture {
} else { } else {
ind = sort.SearchStrings(pics, "appicon_32.png") ind = sort.SearchStrings(pics, "appicon_32.png")
} }
pic, _ = os.Open(fold + "/App/AppInfo/" + pics[ind]) pic = fold + "/App/AppInfo/" + pics[ind]
} }
} else if fi, err := os.Open(fold + "/appicon.png"); err == nil { } else if _, err := os.Open(fold + "/appicon.png"); err == nil {
pic = fi pic = fold + "/appicon.png"
} else { } else {
return nil img, _ := gtk.ImageNewFromIconName("application-x-executable", gtk.ICON_SIZE_BUTTON)
buf, _ := img.GetPixbuf().ScaleSimple(32, 32, gdk.INTERP_BILINEAR)
return buf
} }
img, _, err := image.Decode(pic) img, _ := gtk.ImageNewFromFile(pic)
if err != nil { buf, _ := img.GetPixbuf().ScaleSimple(32, 32, gdk.INTERP_BILINEAR)
return nil return buf
}
rgba := image.NewRGBA(img.Bounds())
draw.Draw(rgba, img.Bounds(), img, image.ZP, draw.Src)
ret := dr.CreateTexture(rgba, 1)
return ret
} }
func findInfo(fold string) *os.File { func findInfo(fold string) *os.File {
+115 -52
View File
@@ -1,66 +1,129 @@
package main package main
import ( import (
"os" "fmt"
"os/exec"
"github.com/nelsam/gxui" "github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
) )
func ui() { func ui(win *gtk.Window) {
catListAdap := &StrList{} ls := getCatRows()
appListAdap := &catAdap{} var treeApps []*gtk.TreeIter
catListAdap.SetStrings(lin) header, _ := gtk.HeaderBarNew()
win := th.CreateWindow(500, 500, "LinuxPA") header.SetShowCloseButton(true)
top := th.CreateLinearLayout() header.SetTitle("LinuxPA")
top.SetDirection(gxui.BottomToTop) header.SetSubtitle("PortableApps.com type launcher")
splBox := th.CreateLinearLayout() settings, _ := gtk.ButtonNewFromIconName("applications-system", gtk.ICON_SIZE_SMALL_TOOLBAR)
spl := th.CreateSplitterLayout() settings.Connect("clicked", func() {
spl.SetOrientation(gxui.Horizontal) //Open Settings window!
catList := th.CreateList()
catList.SetAdapter(catListAdap)
catList.OnSelectionChanged(func(it gxui.AdapterItem) {
appListAdap.setCat(it.(string))
}) })
appList := th.CreateTree() settings.SetTooltipText("Settings (Coming Soon!)")
appList.SetAdapter(appListAdap) header.PackStart(settings)
spl.AddChild(catList) win.SetTitlebar(header)
spl.AddChild(appList) topLvl, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
splBox.AddChild(spl) lrBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5)
butBox := th.CreateLinearLayout() catList, _ := gtk.ListBoxNew()
butBox.SetDirection(gxui.LeftToRight) catList.SetActivateOnSingleClick(true)
if _, err := exec.LookPath("wine"); err == nil { store, _ := gtk.TreeStoreNew(glib.TYPE_OBJECT, glib.TYPE_STRING)
wineBut := th.CreateButton() appsList, _ := gtk.TreeViewNewWithModel(store)
wineBut.SetType(gxui.ToggleButton) render, _ := gtk.CellRendererPixbufNew()
wineBut.SetChecked(wine) pixColumn, _ := gtk.TreeViewColumnNewWithAttribute("", render, "pixbuf", 0)
wineBut.SetText("Show Windows Apps") txtRender, _ := gtk.CellRendererTextNew()
wineBut.OnClick(func(gxui.MouseEvent) { txtColumn, _ := gtk.TreeViewColumnNewWithAttribute("", txtRender, "text", 1)
wine = wineBut.IsChecked() appsList.AppendColumn(pixColumn)
appListAdap.refresh() appsList.AppendColumn(txtColumn)
if wineBut.IsChecked() { catList.SetHExpand(true)
catListAdap.SetStrings(cats) catList.SetVExpand(true)
wineBut.SetText("Hide Windows Apps") appsList.SetHExpand(true)
appsList.SetVExpand(true)
vScrollCat, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
hScrollCat, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
vScrollApp, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
hScrollApp, _ := gtk.AdjustmentNew(0, 0, 0, 0, 0, 0)
catScrl, _ := gtk.ScrolledWindowNew(hScrollCat, vScrollCat)
catScrl.Add(catList)
appScrl, _ := gtk.ScrolledWindowNew(hScrollApp, vScrollApp)
appScrl.Add(appsList)
lrBox.Add(catScrl)
lrBox.Add(appScrl)
botBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2)
wineCheck, _ := gtk.CheckButtonNewWithLabel("Show Windows apps (Wine)")
wineCheck.Connect("toggled", func() {
wine = wineCheck.GetActive()
for i := range ls {
catList.Remove(catList.GetRowAtIndex(i))
}
ls = getCatRows()
for _, v := range ls {
catList.Add(v)
}
catList.ShowAll()
})
botBox.Add(wineCheck)
topLvl.Add(lrBox)
topLvl.PackEnd(botBox, false, true, 0)
win.Add(topLvl)
for _, v := range ls {
catList.Prepend(v)
}
catList.Connect("row-selected", func() {
store.Clear()
if catList.GetSelectedRow().GetIndex() >= 0 {
treeApps = make([]*gtk.TreeIter, 0)
if wine {
apps := master[cats[catList.GetSelectedRow().GetIndex()]]
for _, v := range apps {
treeApps = append(treeApps, v.getTreeIter(store))
}
} else { } else {
catListAdap.SetStrings(lin) apps := linmaster[lin[catList.GetSelectedRow().GetIndex()]]
wineBut.SetText("Show Windows Apps") for _, v := range apps {
treeApps = append(treeApps, v.getTreeIter(store))
}
}
} }
}) })
_, err := os.Open("Start.exe") appsList.Connect("row-activated", func() {
if err == nil { selec, _ := appsList.GetSelection()
pa := th.CreateButton() _, it, ok := selec.GetSelected()
pa.SetText("Open PortableApps Launcher") if ok {
pa.OnClick(func(gxui.MouseEvent) { pth, _ := store.GetPath(it)
cmd := exec.Command("wine", "Start.exe") ind := pth.GetIndices()
cmd.Stdout = os.Stdout if len(ind) == 1 {
cmd.Stderr = os.Stderr if wine {
cmd.Start() app := master[cats[catList.GetSelectedRow().GetIndex()]][ind[0]]
app.launch()
} else {
app := linmaster[lin[catList.GetSelectedRow().GetIndex()]][ind[0]]
app.launch()
}
} else if len(ind) == 2 {
if wine {
app := master[cats[catList.GetSelectedRow().GetIndex()]][ind[0]]
app.launchSub(ind[1])
} else {
app := linmaster[lin[catList.GetSelectedRow().GetIndex()]][ind[0]]
app.launchSub(ind[1])
}
}
}
}) })
butBox.AddChild(pa) }
func getCatRows() (out []*gtk.Label) {
if wine {
for _, v := range cats {
txt, _ := gtk.LabelNew(v)
out = append(out, txt)
fmt.Println(v)
} }
butBox.AddChild(wineBut) } else {
for _, v := range lin {
txt, _ := gtk.LabelNew(v)
out = append(out, txt)
fmt.Println(v)
} }
top.AddChild(butBox) }
top.AddChild(splBox) return
win.AddChild(top)
win.OnClose(dr.Terminate)
} }
+53
View File
@@ -2,11 +2,15 @@ package main
import ( import (
"bufio" "bufio"
"fmt"
"io" "io"
"net/http" "net/http"
"os" "os"
"os/exec"
"strconv" "strconv"
"strings" "strings"
"github.com/gotk3/gotk3/gtk"
) )
const ( const (
@@ -69,6 +73,8 @@ func checkForUpdate(new string) (bool, error) {
} }
if newNums[i] > curNums[i] { if newNums[i] > curNums[i] {
return true, nil return true, nil
} else if curNums[i] > newNums[i] {
return false, nil
} }
} }
return false, nil return false, nil
@@ -104,3 +110,50 @@ func downloadUpdate(newVersion string) (bool, error) {
} }
return true, nil return true, nil
} }
func update(win *gtk.Window) {
updateWin, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
updateWin.SetTransientFor(win)
topLvl, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 5)
spin, _ := gtk.SpinnerNew()
spin.Start()
lbl, _ := gtk.LabelNew("Checking for updates")
topLvl.Add(spin)
topLvl.Add(lbl)
topLvl.SetMarginBottom(10)
topLvl.SetMarginEnd(10)
topLvl.SetMarginStart(10)
topLvl.SetMarginTop(10)
updateWin.SetPosition(gtk.WIN_POS_CENTER_ON_PARENT)
updateWin.Add(topLvl)
updateWin.ShowAll()
updateWin.Show()
go func(win, updateWin *gtk.Window) {
stat, err := versionDL()
if stat {
res := getVersionFileInfo()
if res != "Error!" {
stat, err = checkForUpdate(res)
if stat {
lbl.SetText("Updating!")
downloadUpdate(res)
updateWin.Close()
win.Close()
cmd := exec.Command("./LinuxPA")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Start()
} else {
fmt.Println(err)
updateWin.Close()
}
} else {
fmt.Println("Failed Version File Info")
updateWin.Close()
}
} else {
fmt.Println(err)
updateWin.Close()
}
}(win, updateWin)
}