Migrating to new Gio version (non-working version).

This commit is contained in:
Greg 2020-08-29 19:52:51 -04:00
parent 3163a75b93
commit ec0b64f5f5
13 changed files with 249 additions and 179 deletions

Binary file not shown.

View File

@ -29,6 +29,8 @@ import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.Manifest;
import android.content.pm.PackageManager;
import android.content.Context;
import android.view.View;
public class PgpConnect extends Fragment {
Context ctx;
@ -37,8 +39,19 @@ public class PgpConnect extends Fragment {
OpenPgpServiceConnection mServiceConnection;
final int PERMISSIONS_REQUEST = 1;
public PgpConnect() {
public PgpConnect(View view) {
Log.d("gio", "PgpConnect()");
this.ctx = view.getContext();
this.handler = new Handler(this.ctx.getMainLooper());
PgpConnect inst = this;
handler.post(new Runnable() {
public void run() {
Activity act = (Activity)ctx;
FragmentTransaction ft = act.getFragmentManager().beginTransaction();
ft.add(inst, "PgpConnect");
ft.commitNow();
}
});
}
@Override public void onAttach(Context ctx) {
@ -47,14 +60,13 @@ public class PgpConnect extends Fragment {
if (ctx instanceof Activity) {
Log.d("gio", "It's an Activity!");
}
this.ctx = ctx;
this.handler = new Handler(ctx.getMainLooper());
mServiceConnection = new OpenPgpServiceConnection(ctx, "org.sufficientlysecure.keychain");
mServiceConnection.bindToService();
cb = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ctx.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST);
}
System.loadLibrary("gio");
installComplete(this);
}

View File

@ -1,4 +1,4 @@
//+build !darwin
//+build android
package main
@ -7,7 +7,7 @@ import (
"git.wow.st/gmp/passgo"
"gioui.org/app"
"gioui.org/font/gofont"
"gioui.org/io/event"
)
var (
@ -18,11 +18,17 @@ func init() {
log(Info, "Android start")
// Use a larger font on Android
fontSize = 24
gofont.Register()
}
func initPgp(w *app.Window) {
passgo.InitPgp(w)
func handleEvent(e event.Event) {
switch e := e.(type) {
case app.ViewEvent:
initPgp(e.View)
}
}
func initPgp(view uintptr) {
passgo.InitPgp(view)
}
func getConfDir() (string, error) {

View File

@ -7,9 +7,6 @@ import (
"os/user"
"path"
"gioui.org/app"
"gioui.org/font"
"gioui.org/font/gofont"
"gioui.org/font/opentype"
"gioui.org/text"
)
@ -30,24 +27,23 @@ func setFont() error {
log(Info, "Cannot parse font collection")
return err
}
face, err := fnts.Font(0)
fnt, err := fnts.Font(0)
if err != nil {
log(Info, "Cannot get font from collection")
return err
}
collection = append(collection, text.FontFace{Font: text.Font{}, Face: fnt})
if err != nil {
log(Info, "Cannot access font from font collection")
return err
}
font.Register(text.Font{}, face)
//font.Register(text.Font{}, face)
return nil
}
func init() {
fontSize = 16
err := setFont()
if err != nil {
gofont.Register()
}
}
func initPgp(w *app.Window) {
setFont()
}
func getConfDir() (string, error) {

View File

@ -0,0 +1,10 @@
//+build !android
package main
import (
"gioui.org/io/event"
)
func handleEvent(e event.Event) {
}

View File

@ -15,16 +15,16 @@ import (
"time"
"gioui.org/app"
"gioui.org/font/gofont"
"gioui.org/io/key"
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/text"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
//"gioui.org/font/gofont"
"github.com/fsnotify/fsnotify"
"gopkg.in/yaml.v2"
@ -32,6 +32,11 @@ import (
"git.wow.st/gmp/rand"
)
type (
D = layout.Dimensions
C = layout.Context
)
type conf struct {
StoreDir string
ClearDelay int
@ -113,6 +118,7 @@ func main() {
var (
fontSize float32
collection []text.FontFace
confDir string
Config conf
l []passgo.Pass
@ -190,15 +196,16 @@ func saveConf(fds ...*os.File) {
}
func eventLoop() {
//gofont.Register()
th = material.NewTheme()
if collection == nil {
collection = gofont.Collection()
}
var ops op.Ops
th = material.NewTheme(collection)
th.TextSize = unit.Sp(fontSize)
w := app.NewWindow(
app.Size(unit.Dp(250), unit.Dp(500)),
app.Title("passgo"))
initPgp(w)
gtx := layout.NewContext(w.Queue())
//time.Sleep(time.Second/5)
var margincs layout.Constraints
@ -207,7 +214,7 @@ func eventLoop() {
sysinset := &layout.Inset{}
margin := layout.UniformInset(unit.Dp(10))
title := th.Body1("passgo")
title := material.Body1(th, "passgo")
dotsBtn := &Button{
Size: unit.Sp(fontSize),
Label: "\xe2\x8b\xae",
@ -289,7 +296,7 @@ func eventLoop() {
Background: gray,
}
storeDirLabel := th.Label(unit.Sp(fontSize), "Store directory")
storeDirLabel := material.Label(th, unit.Sp(fontSize), "Store directory")
storeDirEd := &widget.Editor{ SingleLine: true}
storeDirEd.SetText(store.Dir)
saveBtn := &Button{
@ -306,7 +313,7 @@ func eventLoop() {
Color: black,
Background: gray,
}
confirmLabel := th.Label(unit.Sp(fontSize), "Password exists. Overwrite?")
confirmLabel := material.Label(th, unit.Sp(fontSize), "Password exists. Overwrite?")
yesBtn := &Button{
Size: unit.Sp(fontSize),
Label: "yes",
@ -315,7 +322,7 @@ func eventLoop() {
Background: gray,
}
promptLabel := th.Label(unit.Sp(fontSize), "passphrase")
promptLabel := material.Label(th, unit.Sp(fontSize), "passphrase")
promptEd := &widget.Editor{ SingleLine: true, Submit: true }
okBtn := &Button{
Size: unit.Sp(fontSize),
@ -332,20 +339,20 @@ func eventLoop() {
Background: gray,
}
insertLabel := th.Label(unit.Sp(fontSize), "Insert")
passnameLabel := th.Label(unit.Sp(fontSize), "password name:")
insertLabel := material.Label(th, unit.Sp(fontSize), "Insert")
passnameLabel := material.Label(th, unit.Sp(fontSize), "password name:")
passnameEd := &widget.Editor{ SingleLine: true }
passvalLabel := th.Label(unit.Sp(fontSize), "password value:")
passvalLabel := material.Label(th, unit.Sp(fontSize), "password value:")
passvalEd := &widget.Editor{ SingleLine: true, Submit: true }
noidLabel := th.Label(unit.Sp(fontSize), noidLabelText)
idLabel := th.Label(unit.Sp(fontSize), "Select ID")
noidLabel := material.Label(th, unit.Sp(fontSize), noidLabelText)
idLabel := material.Label(th, unit.Sp(fontSize), "Select ID")
anim := &time.Ticker{}
animating := false
animOn := func() {
log(Info, "animOn()")
anim = time.NewTicker(time.Second / 30)
anim = time.NewTicker(time.Second / 90)
animating = true
w.Invalidate()
}
@ -355,7 +362,7 @@ func eventLoop() {
animating = false
}
var listPage, idPage, insertPage, confirmPage, confPage, promptPage, page func()
var listPage, idPage, insertPage, confirmPage, confPage, promptPage, page func(C) D
_ = idPage
prompt := func() []byte {
@ -365,13 +372,14 @@ func eventLoop() {
return <-passch
}
listPage = func() {
listPage = func(gtx C) D {
// timing variables used for animation
fade1a, fade1b := 1.5, 2.0
start2 := float64(Config.ClearDelay)
fade2a, end := start2+1.5, start2+2.0
c2 := layout.Flexed(1.0, func() {
c2 := layout.Flexed(1.0, func(gtx C) D {
var ret D
mux.Lock()
if lst.Dragging() {
key.HideInputOp{}.Add(gtx.Ops)
@ -389,10 +397,10 @@ func eventLoop() {
w.Invalidate()
page = idPage
default:
lst.Layout(gtx, len(passBtns), func(i int) {
ret = lst.Layout(gtx, len(passBtns), func(gtx C, i int) D {
btn := passBtns[i]
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
btn.Layout(gtx)
gtx.Constraints.Min.X = gtx.Constraints.Max.X
ret := btn.Layout(gtx)
if btn.Clicked() {
log(Info, "Clicked ", btn.Label)
// don't block UI thread on decryption attempt
@ -421,11 +429,13 @@ func eventLoop() {
}
}(pathnames[i])
}
return ret
})
}
mux.Unlock()
return ret
})
flex.Layout(gtx, c1, c2)
ret := flex.Layout(gtx, c1, c2)
x := time.Since(overlayStart).Seconds()
if x >= fade1b && x < start2 && animating {
animOff()
@ -463,10 +473,9 @@ func eventLoop() {
overlay.Background = darkgray
}
gtx.Constraints = margincs
al := layout.Align(layout.SE)
al.Layout(gtx, func() {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
overlay.Layout(gtx)
layout.SE.Layout(gtx, func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return overlay.Layout(gtx)
})
}
if x > start2 && x < fade2a {
@ -475,6 +484,7 @@ func eventLoop() {
if animating && x > end {
animOff()
}
return ret
}
updateBtn := &Button{
@ -493,12 +503,12 @@ func eventLoop() {
Background: gray,
}
idPage = func() {
idPage = func(gtx C) D {
if !animating {
animOn()
}
c2 := layout.Rigid(func() {
idLabel.Layout(gtx)
c2 := layout.Rigid(func(gtx C) D {
return idLabel.Layout(gtx)
})
var c3 layout.FlexChild
var c4 layout.FlexChild
@ -506,17 +516,17 @@ func eventLoop() {
var c6 layout.FlexChild
var c7 layout.FlexChild
if len(idBtns) == 0 {
c3 = layout.Rigid(func() {
updateBtn.Layout(gtx)
c3 = layout.Rigid(func(gtx C) D {
return updateBtn.Layout(gtx)
})
if updateBtn.Clicked() {
updateIdBtns()
w.Invalidate()
}
c4 = layout.Rigid(func() {
th.Editor("id").Layout(gtx, idEd)
c4 = layout.Rigid(func(gtx C) D {
return material.Editor(th, idEd, "id").Layout(gtx)
})
for _, e := range idEd.Events(gtx) {
for _, e := range idEd.Events() {
switch e.(type) {
case widget.SubmitEvent:
log(Info, "Submit")
@ -524,27 +534,28 @@ func eventLoop() {
page = listPage
}
}
c5 = layout.Rigid(func() {
idSubmitBtn.Layout(gtx)
c5 = layout.Rigid(func(gtx C) D {
return idSubmitBtn.Layout(gtx)
})
if idSubmitBtn.Clicked() {
store.Id = idEd.Text()
page = listPage
}
c6 = layout.Rigid(func() {
noidLabel.Layout(gtx)
c6 = layout.Rigid(func(gtx C) D {
return noidLabel.Layout(gtx)
})
} else {
c3 = layout.Rigid(func() { })
c4 = layout.Rigid(func() { })
c5 = layout.Rigid(func() { })
c6 = layout.Rigid(func() { })
c3 = layout.Rigid(func(gtx C) D { return D{} })
c4 = layout.Rigid(func(gtx C) D { return D{} })
c5 = layout.Rigid(func(gtx C) D { return D{} })
c6 = layout.Rigid(func(gtx C) D { return D{} })
}
c7 = layout.Rigid(func() {
c7 = layout.Rigid(func(gtx C) D {
var ret D
if len(idBtns) > 0 { // still zero after update
for i := 0; i < len(idBtns); i++ {
lst.Layout(gtx, len(idBtns), func(i int) {
idBtns[i].Layout(gtx)
ret = lst.Layout(gtx, len(idBtns), func(gtx C, i int) D {
return idBtns[i].Layout(gtx)
})
}
for _, btn := range idBtns {
@ -557,8 +568,9 @@ func eventLoop() {
}
}
}
return ret
})
flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7)
return flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7)
}
var insName, insValue string
@ -596,41 +608,40 @@ func eventLoop() {
passvalEd.SetText(string(pw))
}
insertPage = func() {
c2 := layout.Rigid(func() { insertLabel.Layout(gtx) })
c3 := layout.Rigid(func() { passnameLabel.Layout(gtx) })
c4 := layout.Rigid(func() { th.Editor("name").Layout(gtx, passnameEd) })
c5 := layout.Rigid(func() { passvalLabel.Layout(gtx) })
c6 := layout.Rigid(func() { th.Editor("password").Layout(gtx, passvalEd) })
insertPage = func(gtx C) D {
c2 := layout.Rigid(func(gtx C) D { return insertLabel.Layout(gtx) })
c3 := layout.Rigid(func(gtx C) D { return passnameLabel.Layout(gtx) })
c4 := layout.Rigid(func(gtx C) D { return material.Editor(th, passnameEd, "name").Layout(gtx) })
c5 := layout.Rigid(func(gtx C) D { return passvalLabel.Layout(gtx) })
c6 := layout.Rigid(func(gtx C) D { return material.Editor(th, passvalEd, "password").Layout(gtx) })
btnflx := &layout.Flex{Axis: layout.Horizontal}
al := layout.Align(layout.E)
c7 := layout.Rigid(func() {
bc1 := layout.Rigid(func() { lBtn.Layout(gtx) })
bc2 := layout.Rigid(func() {
gtx.Constraints.Width.Min = 60
th.Editor("len").Layout(gtx, lenEd)
c7 := layout.Rigid(func(gtx C) D {
bc1 := layout.Rigid(func(gtx C) D { return lBtn.Layout(gtx) })
bc2 := layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = 60
return material.Editor(th, lenEd, "len").Layout(gtx)
})
bc3 := layout.Rigid(func() { rBtn.Layout(gtx) })
bc4 := layout.Rigid(func() { symBtn.Layout(gtx) })
bc5 := layout.Rigid(func() { numBtn.Layout(gtx) })
bc6 := layout.Rigid(func() { genBtn.Layout(gtx) })
bc3 := layout.Rigid(func(gtx C) D { return rBtn.Layout(gtx) })
bc4 := layout.Rigid(func(gtx C) D { return symBtn.Layout(gtx) })
bc5 := layout.Rigid(func(gtx C) D { return numBtn.Layout(gtx) })
bc6 := layout.Rigid(func(gtx C) D { return genBtn.Layout(gtx) })
al.Layout(gtx, func() {
btnflx.Layout(gtx, bc1, bc2, bc3, bc4, bc5, bc6)
return layout.E.Layout(gtx, func(gtx C) D {
return btnflx.Layout(gtx, bc1, bc2, bc3, bc4, bc5, bc6)
})
})
c8 := layout.Rigid(func() {
bc1 := layout.Rigid(func() { backBtn.Layout(gtx) })
bc2 := layout.Rigid(func() { saveBtn.Layout(gtx) })
al.Layout(gtx, func() {
btnflx.Layout(gtx, bc1, bc2)
c8 := layout.Rigid(func(gtx C) D {
bc1 := layout.Rigid(func(gtx C) D { return backBtn.Layout(gtx) })
bc2 := layout.Rigid(func(gtx C) D { return saveBtn.Layout(gtx) })
return layout.E.Layout(gtx, func(gtx C) D {
return btnflx.Layout(gtx, bc1, bc2)
})
})
flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7, c8)
ret := flex.Layout(gtx, c1, c2, c3, c4, c5, c6, c7, c8)
if lBtn.Clicked() {
l, _ := strconv.Atoi(lenEd.Text())
@ -673,7 +684,7 @@ func eventLoop() {
log(Info, "Password exists")
page = confirmPage
w.Invalidate()
return
return ret
}
}
//Do not block the UI thread.
@ -684,23 +695,23 @@ func eventLoop() {
}
}()
}
return ret
}
confirmPage = func() {
c2 := layout.Rigid(func() {
confirmLabel.Layout(gtx)
confirmPage = func(gtx C) D {
c2 := layout.Rigid(func(gtx C) D {
return confirmLabel.Layout(gtx)
})
al := layout.Align(layout.E)
btnflx := &layout.Flex{Axis: layout.Horizontal}
c3 := layout.Rigid(func() {
bc1 := layout.Rigid(func() { backBtn.Layout(gtx) })
bc2 := layout.Rigid(func() { yesBtn.Layout(gtx) })
c3 := layout.Rigid(func(gtx C) D {
bc1 := layout.Rigid(func(gtx C) D { return backBtn.Layout(gtx) })
bc2 := layout.Rigid(func(gtx C) D { return yesBtn.Layout(gtx) })
al.Layout(gtx, func() {
btnflx.Layout(gtx, bc1, bc2)
return layout.E.Layout(gtx, func(gtx C) D {
return btnflx.Layout(gtx, bc1, bc2)
})
})
flex.Layout(gtx, c1, c2, c3)
ret := flex.Layout(gtx, c1, c2, c3)
if backBtn.Clicked() {
w.Invalidate()
@ -716,26 +727,26 @@ func eventLoop() {
}
}()
}
return ret
}
confPage = func() {
c2 := layout.Rigid(func() { storeDirLabel.Layout(gtx) })
c3 := layout.Rigid(func() { th.Editor("directory").Layout(gtx, storeDirEd) })
confPage = func(gtx C) D {
c2 := layout.Rigid(func(gtx C) D { return storeDirLabel.Layout(gtx) })
c3 := layout.Rigid(func(gtx C) D { return material.Editor(th, storeDirEd, "directory").Layout(gtx) })
al := layout.Align(layout.E)
c4 := layout.Rigid(func() {
c4 := layout.Rigid(func(gtx C) D {
btnflx := &layout.Flex{Axis: layout.Horizontal}
bc1 := layout.Rigid(func() {
backBtn.Layout(gtx)
bc1 := layout.Rigid(func(gtx C) D {
return backBtn.Layout(gtx)
})
bc2 := layout.Rigid(func() {
saveBtn.Layout(gtx)
bc2 := layout.Rigid(func(gtx C) D {
return saveBtn.Layout(gtx)
})
al.Layout(gtx, func() {
btnflx.Layout(gtx, bc1, bc2)
return layout.E.Layout(gtx, func(gtx C) D {
return btnflx.Layout(gtx, bc1, bc2)
})
})
flex.Layout(gtx, c1, c2, c3, c4)
ret := flex.Layout(gtx, c1, c2, c3, c4)
if backBtn.Clicked() {
log(Info, "Back")
@ -757,33 +768,33 @@ func eventLoop() {
w.Invalidate()
page = listPage
}
return ret
}
promptPage = func() {
promptPage = func(gtx C) D {
submit := false
for _, e := range promptEd.Events(gtx) {
for _, e := range promptEd.Events() {
switch e.(type) {
case widget.SubmitEvent:
log(Info, "Submit")
submit = true
}
}
c2 := layout.Rigid(func() { promptLabel.Layout(gtx) })
c3 := layout.Rigid(func() { th.Editor("password").Layout(gtx, promptEd) })
c4 := layout.Rigid(func() {
al := layout.Align(layout.E)
c2 := layout.Rigid(func(gtx C) D { return promptLabel.Layout(gtx) })
c3 := layout.Rigid(func(gtx C) D { return material.Editor(th, promptEd, "password").Layout(gtx) })
c4 := layout.Rigid(func(gtx C) D {
btnflx := &layout.Flex{Axis: layout.Horizontal}
bc1 := layout.Rigid(func() {
backBtn.Layout(gtx)
bc1 := layout.Rigid(func(gtx C) D {
return backBtn.Layout(gtx)
})
bc2 := layout.Rigid(func() {
okBtn.Layout(gtx)
bc2 := layout.Rigid(func(gtx C) D {
return okBtn.Layout(gtx)
})
al.Layout(gtx, func() {
btnflx.Layout(gtx, bc1, bc2)
return layout.E.Layout(gtx, func(gtx C) D {
return btnflx.Layout(gtx, bc1, bc2)
})
})
flex.Layout(gtx, c1, c2, c3, c4)
ret := flex.Layout(gtx, c1, c2, c3, c4)
if submit || okBtn.Clicked() {
log(Info, "Ok")
@ -801,6 +812,7 @@ func eventLoop() {
w.Invalidate()
page = listPage
}
return ret
}
page = listPage
@ -832,31 +844,31 @@ func eventLoop() {
}()
}
case system.FrameEvent:
gtx.Reset(e.Config, e.Size)
gtx := layout.NewContext(&ops, e)
sysinset.Top = e.Insets.Top
sysinset.Bottom = e.Insets.Bottom
sysinset.Left = e.Insets.Left
sysinset.Right = e.Insets.Right
sysinset.Layout(gtx, func() {
margin.Layout(gtx, func() {
sysinset.Layout(gtx, func(gtx C) D {
return margin.Layout(gtx, func(gtx C) D {
margincs = gtx.Constraints
c1 = layout.Rigid(func() {
ct2 := layout.Rigid(func() {
plusBtn.Layout(gtx)
c1 = layout.Rigid(func(gtx C) D {
ct2 := layout.Rigid(func(gtx C) D {
return plusBtn.Layout(gtx)
})
ct3 := layout.Rigid(func() {
dotsBtn.Layout(gtx)
ct3 := layout.Rigid(func(gtx C) D {
return dotsBtn.Layout(gtx)
})
ct1 := layout.Flexed(1.0, func() {
gtx.Constraints.Width.Min = gtx.Constraints.Width.Max
title.Layout(gtx)
ct1 := layout.Flexed(1.0, func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return title.Layout(gtx)
})
titleflex.Layout(gtx, ct1, ct2, ct3)
return titleflex.Layout(gtx, ct1, ct2, ct3)
})
page()
return page(gtx)
})
})
@ -872,6 +884,8 @@ func eventLoop() {
page = insertPage
}
e.Frame(gtx.Ops)
default:
handleEvent(e)
}
if x == 100 {
x = 0

View File

@ -12,6 +12,7 @@ import (
"gioui.org/op/paint"
"gioui.org/text"
"gioui.org/unit"
"gioui.org/widget/material"
)
var (
@ -30,23 +31,24 @@ type Overlay struct {
Alignment text.Alignment
}
func (b *Overlay) Layout(gtx *layout.Context) {
func (b *Overlay) Layout(gtx C) D {
ins := layout.UniformInset(unit.Dp(1))
ins.Layout(gtx, func() {
return ins.Layout(gtx, func(gtx C) D {
st := layout.Stack{}
c2 := layout.Stacked(func() {
l := th.Label(b.Size, b.Text)
c2 := layout.Stacked(func(gtx C) D {
l := material.Label(th, b.Size, b.Text)
ins := layout.UniformInset(unit.Dp(4))
l.Color = b.Color
ins.Layout(gtx, func() {
l.Layout(gtx)
ret := ins.Layout(gtx, func(gtx C) D {
return l.Layout(gtx)
})
pointer.Rect(image.Rect(0, 0, gtx.Dimensions.Size.X, gtx.Dimensions.Size.Y)).Add(gtx.Ops)
pointer.Rect(image.Rect(0, 0, ret.Size.X, ret.Size.Y)).Add(gtx.Ops)
return ret
})
c1 := layout.Expanded(func() {
layoutRRect(b.Background, gtx)
c1 := layout.Expanded(func(gtx C) D {
return layoutRRect(b.Background, gtx)
})
st.Layout(gtx, c1, c2)
return st.Layout(gtx, c1, c2)
})
}
@ -66,23 +68,23 @@ type Button struct {
clicked bool
}
func layoutRRect(col color.RGBA, gtx *layout.Context) {
func layoutRRect(col color.RGBA, gtx C) D {
r := float32(gtx.Px(unit.Dp(4)))
sz := image.Point{X: gtx.Constraints.Width.Min, Y: gtx.Constraints.Height.Min}
sz := image.Point{X: gtx.Constraints.Min.X, Y: gtx.Constraints.Min.Y}
w, h := float32(sz.X), float32(sz.Y)
rect := f32.Rectangle{
f32.Point{0, 0},
f32.Point{w, h},
}
//clip.RoundRect(gtx.Ops, rect, r, r, r, r)
clip.Rect{Rect: rect, NE: r, NW: r, SE: r, SW: r}.Op(gtx.Ops).Add(gtx.Ops)
clip.RRect{Rect: rect, NE: r, NW: r, SE: r, SW: r}.Add(gtx.Ops)
paint.ColorOp{Color: col}.Add(gtx.Ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: w, Y: h}}}.Add(gtx.Ops)
gtx.Dimensions = layout.Dimensions{Size: sz}
return layout.Dimensions{Size: sz}
}
func (b *Button) Layout(gtx *layout.Context) {
mwidth := gtx.Constraints.Width.Min
func (b *Button) Layout(gtx C) D {
mwidth := gtx.Constraints.Min.X
b.clicked = false
for _, ev := range b.Click.Events(gtx) {
if ev.Type == gesture.TypeClick {
@ -90,23 +92,24 @@ func (b *Button) Layout(gtx *layout.Context) {
}
}
ins := layout.UniformInset(unit.Dp(1))
ins.Layout(gtx, func() {
return ins.Layout(gtx, func(gtx C) D {
st := layout.Stack{}
c2 := layout.Stacked(func() {
l := th.Label(b.Size, b.Label)
c2 := layout.Stacked(func(gtx C) D {
l := material.Label(th, b.Size, b.Label)
ins := layout.UniformInset(unit.Dp(4))
//paint.ColorOp{Color: b.Color}.Add(ops)
ins.Layout(gtx, func() {
l.Layout(gtx)
ret := ins.Layout(gtx, func(gtx C) D {
return l.Layout(gtx)
})
pointer.Rect(image.Rect(0, 0, gtx.Dimensions.Size.X, gtx.Dimensions.Size.Y)).Add(gtx.Ops)
pointer.Rect(image.Rect(0, 0, ret.Size.X, ret.Size.Y)).Add(gtx.Ops)
b.Click.Add(gtx.Ops)
return ret
})
c1 := layout.Expanded(func() {
gtx.Constraints.Width.Min = mwidth
layoutRRect(b.Background, gtx)
c1 := layout.Expanded(func(gtx C) D {
gtx.Constraints.Min.X = mwidth
return layoutRRect(b.Background, gtx)
})
st.Layout(gtx, c1, c2)
return st.Layout(gtx, c1, c2)
})
}

5
go.mod
View File

@ -3,12 +3,13 @@ module git.wow.st/gmp/passgo
go 1.13
require (
gioui.org v0.0.0-20191218180754-3dd7c8121c67
gioui.org v0.0.0-20200827132523-d57edbb49d3c
git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5
git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0
git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0
github.com/fsnotify/fsnotify v1.4.7
github.com/jcmdev0/gpgagent v0.0.0-20180509014935-5601b32d936c
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
golang.org/x/image v0.0.0-20190802002840-cff245a6509b
golang.org/x/image v0.0.0-20200618115811-c13761719519
gopkg.in/yaml.v2 v2.2.7
)

9
go.sum
View File

@ -3,8 +3,13 @@ gioui.org v0.0.0-20191126175243-2ca2e5462f16 h1:p31rtmKm51xpj2QtqGNlljAyHEP1oStU
gioui.org v0.0.0-20191126175243-2ca2e5462f16/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY=
gioui.org v0.0.0-20191218180754-3dd7c8121c67 h1:y9md+l1thtMqJu/ulhF1Upv3pnOpGotpJDssO8X3LbY=
gioui.org v0.0.0-20191218180754-3dd7c8121c67/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY=
gioui.org v0.0.0-20200827132523-d57edbb49d3c h1:TY1A2dzvxASVC+crmYfkDF8JNkd4rKaXZG2A4WboyU4=
gioui.org v0.0.0-20200827132523-d57edbb49d3c/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw=
gioui.org v0.0.0-20200829162755-829ee4559c5a h1:mciXRGzQwU0TbgCILZzl6L1nYIWU31lDGIb+8RYige8=
git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5 h1:OKeTjZST+/TKvtdA258NXJH+/gIx/xwyZxKrAezNFvk=
git.wow.st/gmp/clip v0.0.0-20191001134149-1458ba6a7cf5/go.mod h1:NLdpaBoMQNFqncwP8OVRNWUDw1Kt9XWm3snfT7cXu24=
git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0 h1:Ynp3h+TC8k1clvf45D28VFQlmy0bPx8M/MG5bB24Vj8=
git.wow.st/gmp/jni v0.0.0-20200827154156-014cd5c7c4c0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo=
git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0 h1:08wP00wvbDINsct1fzKV1xGGLvvtNsSb2X4CtIdpBzM=
git.wow.st/gmp/rand v0.0.0-20191001220155-a81bebfaf8b0/go.mod h1:8+2Gwnrpc5yuk8Wp6cBhxvGcNLumYiPbQ7n0SQ8h29A=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -23,6 +28,8 @@ golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgn
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -33,6 +40,8 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=

View File

@ -1,6 +1,6 @@
//+build android
//go:generate mkdir -p classes
//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath openpgp-api.jar -d classes PgpConnect.java
//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath openpgp-api.jar -d classes PgpConnect.java Foo.java
//go:generate jar cf PgpConnect.jar -C classes .
//go:generate rm -rf classes
@ -19,13 +19,15 @@ import (
"log"
"strings"
"sync"
"unsafe"
"gioui.org/app"
_ "gioui.org/app/permission/storage"
//"git.wow.st/gmp/jni"
)
var (
h *app.Handle
jvm uintptr
waitch chan struct{}
//w *app.Window
pgp PGP
@ -40,16 +42,18 @@ func init() {
func Java_st_wow_git_passgo_PgpConnect_installComplete(env *C.JNIEnv, class C.jclass, p C.jobject) {
log.Printf("InstallComplete()")
pgp = PGP(C.NewGlobalRef(env, p))
h = app.PlatformHandle()
SetJVM(h.JVM)
installCompleteOnce.Do(func() {
close(waitch)
})
}
func InitPgp(w *app.Window) {
func InitPgp(view uintptr) {
log.Printf("InitPgp()")
w.RegisterFragment("st/wow/git/passgo/PgpConnect")
jvm = app.JavaVM()
SetJVM(jvm) // why?
RunInJVM(func(env *JNIEnv) {
C.registerFragment(env, (C.jobject)(unsafe.Pointer(view)))
})
}
func stopPgp() {

View File

@ -1,16 +1,30 @@
#include <stdlib.h>
//#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include "jni_android.h"
#include "_cgo_export.h"
void
registerFragment(JNIEnv *env, jobject view) {
jclass cls = (*env)->GetObjectClass(env, view);
jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;");
jobject ctx = (*env)->CallObjectMethod(env, view, mid);
cls = (*env)->GetObjectClass(env, ctx);
mid = (*env)->GetMethodID(env, cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject loader = (*env)->CallObjectMethod(env, ctx, mid);
cls = (*env)->GetObjectClass(env, loader);
mid = (*env)->GetMethodID(env, cls, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring str = (*env)->NewStringUTF(env, "st/wow/git/passgo/PgpConnect");
cls = (*env)->CallObjectMethod(env, loader, mid, str);
mid = (*env)->GetMethodID(env, cls, "<init>", "(Landroid/view/View;)V");
jobject inst = (*env)->NewObject(env, cls, mid, view);
}
void
GetId(JNIEnv* env, jobject p, int chint) {
jclass cls = (*env)->GetObjectClass(env, p);
printf("GetId(): cls = %p", cls);
jmethodID mid = (*env)->GetMethodID(env, cls, "GetId", "(I)V");
printf("GetId(): mid = %p", mid);
(*env)->CallObjectMethod(env, p, mid, chint);
}

View File

@ -1,7 +1,7 @@
package passgo
/*
#cgo LDFLAGS: -landroid
#cgo LDFLAGS: -landroid -llog
#include <stdlib.h>
#include "jni_android.h"

View File

@ -1,5 +1,6 @@
#include <jni.h>
void registerFragment(JNIEnv *env, jobject view);
void GetId(JNIEnv* env, jobject p, int chint);
void Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint);
void Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint);