Initial commit.
This commit is contained in:
commit
b6d598696c
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
cmd/rand/rand
|
||||||
|
cmd/rand-gui/rand-gui
|
||||||
|
cmd/rand-gui/.gradle
|
||||||
|
cmd/rand-gui/gradle/
|
||||||
|
cmd/rand-gui/gradlew
|
||||||
|
cmd/rand-gui/gradlew.bat
|
||||||
|
cmd/rand-gui/build/
|
||||||
|
cmd/rand-gui/android/build/
|
||||||
|
cmd/rand-gui/android/build_go/
|
||||||
|
cmd/rand-gui/android/src/main/jniLibs/
|
||||||
|
cmd/rand-gui/bindata.go
|
22
cmd/rand-gui/Makefile
Normal file
22
cmd/rand-gui/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
darwin: bindata.go
|
||||||
|
go generate
|
||||||
|
go build
|
||||||
|
|
||||||
|
gradlew:
|
||||||
|
gradle wrapper
|
||||||
|
|
||||||
|
android: gradlew bindata.go
|
||||||
|
go generate
|
||||||
|
./gradlew build
|
||||||
|
|
||||||
|
android-install: gradlew bindata.go
|
||||||
|
go generate
|
||||||
|
./gradlew installDebug
|
||||||
|
|
||||||
|
bindata.go: assets/DroidSans.ttf
|
||||||
|
go-bindata assets/DroidSans.ttf
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf bindata.go android/build android/build_go android/src/main/jniLibs build gradlew gradlew.bat .gradle gradle commute
|
||||||
|
|
4
cmd/rand-gui/alog
Executable file
4
cmd/rand-gui/alog
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
adb logcat Rand *:S > alogs
|
||||||
|
|
201
cmd/rand-gui/android.go
Normal file
201
cmd/rand-gui/android.go
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
//+build !darwin
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xlab/android-go/android"
|
||||||
|
"github.com/xlab/android-go/app"
|
||||||
|
gl "github.com/xlab/android-go/gles31"
|
||||||
|
|
||||||
|
//"github.com/golang-ui/nuklear/nk"
|
||||||
|
"gitlab.wow.st/gmp/nuklear/nk"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
datadir = "/storage/emulated/0/Android/data/st.wow.gitlab.gmp.commute/"
|
||||||
|
fontSize = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
func platformInit() {
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.Disable(gl.DEPTH_TEST)
|
||||||
|
app.SetLogTag("Commute")
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkWin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func Terminate() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func PollEvents() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSize() (width, height int) {
|
||||||
|
handle := nk.NkPlatformDisplayHandle()
|
||||||
|
return handle.Width, handle.Height
|
||||||
|
}
|
||||||
|
|
||||||
|
func SwapBuffers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
nativeWindowEvents chan app.NativeWindowEvent
|
||||||
|
inputQueueEvents chan app.InputQueueEvent
|
||||||
|
inputQueueChan chan *android.InputQueue
|
||||||
|
backPressed bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func eventloop() {
|
||||||
|
nativeWindowEvents = make(chan app.NativeWindowEvent, 1)
|
||||||
|
inputQueueEvents = make(chan app.InputQueueEvent, 1)
|
||||||
|
inputQueueChan = make(chan *android.InputQueue, 1)
|
||||||
|
|
||||||
|
app.Main(appmain)
|
||||||
|
log(Info,"app.Main returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
func appmain(a app.NativeActivity) {
|
||||||
|
log(Info,"appmain() start")
|
||||||
|
fpsTicker := time.NewTicker(frametime)
|
||||||
|
a.HandleNativeWindowEvents(nativeWindowEvents)
|
||||||
|
a.HandleInputQueueEvents(inputQueueEvents)
|
||||||
|
log(Info,"appmain() launching init thread")
|
||||||
|
inputs := make(chan struct{},64)
|
||||||
|
go app.HandleInputQueues(inputQueueChan, func() {
|
||||||
|
a.InputQueueHandled()
|
||||||
|
}, func(ev *android.InputEvent) {
|
||||||
|
switch android.InputEventGetType(ev) {
|
||||||
|
case android.InputEventTypeKey:
|
||||||
|
key := android.KeyEventGetKeyCode(ev)
|
||||||
|
action := android.KeyEventGetAction(ev)
|
||||||
|
meta := android.KeyEventGetMetaState(ev)
|
||||||
|
switch action {
|
||||||
|
case android.KeyEventActionDown:
|
||||||
|
if key == android.KeycodeBack {
|
||||||
|
backPressed = true
|
||||||
|
inputs<- struct{}{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case android.KeyEventActionUp:
|
||||||
|
nk.NkPlatformInput(nil, &nk.PlatformKeyEvent{
|
||||||
|
Activity: a.NativeActivity(),
|
||||||
|
Action: action,
|
||||||
|
KeyCode: key,
|
||||||
|
MetaState: meta,
|
||||||
|
})
|
||||||
|
inputs<- struct{}{}
|
||||||
|
}
|
||||||
|
case android.InputEventTypeMotion:
|
||||||
|
action := android.MotionEventGetAction(ev)
|
||||||
|
switch action {
|
||||||
|
case android.MotionEventActionDown,
|
||||||
|
android.MotionEventActionMove,
|
||||||
|
android.MotionEventActionUp:
|
||||||
|
x := android.MotionEventGetX(ev, 0)
|
||||||
|
y := android.MotionEventGetY(ev, 0)
|
||||||
|
nk.NkPlatformInput(&nk.PlatformTouchEvent{
|
||||||
|
Action: action,
|
||||||
|
X: int32(x),
|
||||||
|
Y: int32(y),
|
||||||
|
}, nil)
|
||||||
|
inputs<- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
a.InitDone()
|
||||||
|
log(Info,"appmain() starting event loop")
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-a.LifecycleEvents():
|
||||||
|
log(Info,"appmain(): lifecycle ", event)
|
||||||
|
case event := <-inputQueueEvents:
|
||||||
|
log(Debug,"appmain(): inputQueueEvent ", event)
|
||||||
|
switch event.Kind {
|
||||||
|
case app.QueueCreated:
|
||||||
|
inputQueueChan <- event.Queue
|
||||||
|
case app.QueueDestroyed:
|
||||||
|
inputQueueChan <- nil
|
||||||
|
}
|
||||||
|
if ctx != nil {
|
||||||
|
gfxMain()
|
||||||
|
}
|
||||||
|
case <-fpsTicker.C:
|
||||||
|
log(DebugGfx,"appmain(): fpsTicker")
|
||||||
|
if ctx != nil {
|
||||||
|
log(DebugGfx,"gfxMain()")
|
||||||
|
fpsTicker.Stop()
|
||||||
|
gfxMain()
|
||||||
|
fpsTicker = newTicker()
|
||||||
|
}
|
||||||
|
case <-inputs:
|
||||||
|
log(Debug,"appmain(): inputs queue")
|
||||||
|
if ctx != nil {
|
||||||
|
fpsTicker.Stop()
|
||||||
|
gfxMain()
|
||||||
|
fpsTicker = newFastTicker()
|
||||||
|
}
|
||||||
|
case event := <-nativeWindowEvents:
|
||||||
|
log(Info,"appmain(): nativeWindowEvents", event)
|
||||||
|
switch event.Kind {
|
||||||
|
case app.NativeWindowRedrawNeeded:
|
||||||
|
log(Info,"appmain(): redraw")
|
||||||
|
fpsTicker.Stop()
|
||||||
|
gfxMain()
|
||||||
|
a.NativeWindowRedrawDone()
|
||||||
|
fpsTicker = newTicker()
|
||||||
|
case app.NativeWindowCreated:
|
||||||
|
log(Info,"appmain(): window created")
|
||||||
|
ctx = nk.NkPlatformInit(event.Window, nk.PlatformInstallCallbacks)
|
||||||
|
log(Info,"appmain(): init returned")
|
||||||
|
if ctx == nil {
|
||||||
|
log(Fatal,"Nuklear failed to init")
|
||||||
|
}
|
||||||
|
loadFont()
|
||||||
|
fpsTicker = newTicker()
|
||||||
|
log(Info,"appmain(): done with create window")
|
||||||
|
case app.NativeWindowDestroyed:
|
||||||
|
log(Info,"appmain(): window destroyed")
|
||||||
|
//refresh = true
|
||||||
|
fpsTicker.Stop()
|
||||||
|
nk.NkPlatformShutdown()
|
||||||
|
Drain:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-inputs:
|
||||||
|
default:
|
||||||
|
break Drain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backPressed = false
|
||||||
|
}
|
||||||
|
log(Info,"appmain: returning")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFastTicker() *time.Ticker {
|
||||||
|
return time.NewTicker(time.Second / 60)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTicker() *time.Ticker {
|
||||||
|
if y != lastY {
|
||||||
|
return time.NewTicker(time.Second / 60)
|
||||||
|
} else {
|
||||||
|
return time.NewTicker(time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BackButton(string) bool {
|
||||||
|
return backPressed
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clip(x string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
40
cmd/rand-gui/android/build.gradle
Normal file
40
cmd/rand-gui/android/build.gradle
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion = rootProject.ext.sdkVersion
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
ndk {
|
||||||
|
abiFilters rootProject.ext.archs.split(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release
|
||||||
|
debug {
|
||||||
|
jniDebuggable true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task buildGo(type: Exec) {
|
||||||
|
commandLine '../bash_script/build_go.sh', rootProject.ext.archs, rootProject.ext.sdkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareToolchain(type: Exec) {
|
||||||
|
commandLine '../bash_script/build_toolchain.sh', rootProject.ext.archs, rootProject.ext.sdkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
task cleanToolchain(type: Exec) {
|
||||||
|
commandLine 'rm', '-r', 'build_go/toolchain'
|
||||||
|
}
|
||||||
|
|
||||||
|
task cleanOutput(type: Exec) {
|
||||||
|
commandLine 'rm', '-r', 'build_go/output'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
buildGo.dependsOn prepareToolchain
|
||||||
|
preBuild.dependsOn buildGo
|
||||||
|
clean.dependsOn cleanOutput
|
||||||
|
}
|
24
cmd/rand-gui/android/src/main/AndroidManifest.xml
Normal file
24
cmd/rand-gui/android/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="st.wow.gitlab.gmp.rand"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="25" />
|
||||||
|
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
|
<application android:label="Rand" android:hasCode="false">
|
||||||
|
<activity android:name="android.app.NativeActivity"
|
||||||
|
android:label="Rand"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="gomain" />
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
BIN
cmd/rand-gui/assets/DroidSans.ttf
Normal file
BIN
cmd/rand-gui/assets/DroidSans.ttf
Normal file
Binary file not shown.
60
cmd/rand-gui/bash_script/build_go.sh
Executable file
60
cmd/rand-gui/bash_script/build_go.sh
Executable file
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#Working directory is <project root>/android
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if ! [ -d "$ANDROID_HOME" ];
|
||||||
|
then
|
||||||
|
printf "ANDROID_HOME does not point to any directory. Please set ANDROID_HOME variable\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ABIS=($(echo $1 | sed 's/,/ /g'))
|
||||||
|
ANDROID_API=$2
|
||||||
|
printf "Build Go sources using ABIs: %s Android API: %s\n" "${ABIS[*]}" "$ANDROID_API"
|
||||||
|
|
||||||
|
TOOLCHAIN_ROOT_DIR=build_go/toolchain
|
||||||
|
OUTPUT_ROOT_DIR=build_go/output
|
||||||
|
printf "Cleaning output dir %s\n" "$OUTPUT_ROOT_DIR"
|
||||||
|
rm -rf "$OUTPUT_ROOT_DIR"
|
||||||
|
|
||||||
|
for ABI in ${ABIS[*]}
|
||||||
|
do
|
||||||
|
GOARCH=
|
||||||
|
GOARM=
|
||||||
|
CC=
|
||||||
|
CXX=
|
||||||
|
CGO_CFLAGS=
|
||||||
|
|
||||||
|
case $ABI in
|
||||||
|
armeabi-v7a)
|
||||||
|
GOARCH="arm"
|
||||||
|
GOARM=7
|
||||||
|
CC="$TOOLCHAIN_ROOT_DIR/arm/bin/arm-linux-androideabi-gcc"
|
||||||
|
CXX="$TOOLCHAIN_ROOT_DIR/arm/bin/arm-linux-androideabi-g++"
|
||||||
|
CGO_CFLAGS="-march=armv7-a"
|
||||||
|
;;
|
||||||
|
x86)
|
||||||
|
GOARCH="386"
|
||||||
|
GOARM=
|
||||||
|
CC="$TOOLCHAIN_ROOT_DIR/x86/bin/i686-linux-android-gcc"
|
||||||
|
CXX="$TOOLCHAIN_ROOT_DIR/x86/bin/i686-linux-android-g++"
|
||||||
|
CGO_CFLAGS=
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
OUTPUT_DIR="$OUTPUT_ROOT_DIR/$ABI"
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
set -x
|
||||||
|
CURRENT_DIR=$(pwd)
|
||||||
|
CC="$CURRENT_DIR/android/$CC" CXX="$CURRENT_DIR/android/$CXX" CGO_ENABLED=1 \
|
||||||
|
CGO_CFLAGS="$CGO_CFLAGS" GOOS=android GOARCH="$GOARCH" GOARM="$GOARM" \
|
||||||
|
go build -i -pkgdir "$CURRENT_DIR/android/$OUTPUT_DIR" -buildmode=c-shared -o "android/src/main/jniLibs/$ABI/libgomain.so"
|
||||||
|
cd android
|
||||||
|
set +x
|
||||||
|
done
|
53
cmd/rand-gui/bash_script/build_toolchain.sh
Executable file
53
cmd/rand-gui/bash_script/build_toolchain.sh
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#Working directory is <project root>/android
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if ! [ -d "$ANDROID_HOME" ];
|
||||||
|
then
|
||||||
|
printf "ANDROID_HOME does not point to any directory. Please set ANDROID_HOME variable\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ABIS=($(echo $1 | sed 's/,/ /g'))
|
||||||
|
ANDROID_API=$2
|
||||||
|
printf "Preparing toolchains for ABIs: %s Android API: %s\n" "${ABIS[*]}" $ANDROID_API
|
||||||
|
|
||||||
|
|
||||||
|
TOOLCHAIN_ROOT_DIR=build_go/toolchain
|
||||||
|
|
||||||
|
declare -A ARCHS
|
||||||
|
for ABI in ${ABIS[*]}
|
||||||
|
do
|
||||||
|
case $ABI in
|
||||||
|
armeabi-v7a)
|
||||||
|
ARCH="arm"
|
||||||
|
;;
|
||||||
|
x86)
|
||||||
|
ARCH="x86"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ARCHS[$ARCH]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
for ARCH in ${!ARCHS[*]}
|
||||||
|
do
|
||||||
|
TOOLCHAIN_DIR="$TOOLCHAIN_ROOT_DIR/$ARCH"
|
||||||
|
|
||||||
|
if [ -d "$TOOLCHAIN_DIR" ];
|
||||||
|
then
|
||||||
|
printf "Using existing standalone toolchain for arch: %s\n" $ARCH
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "Making standalone toolchain for arch: %s\n" $ARCH
|
||||||
|
set -x
|
||||||
|
"$ANDROID_HOME"/ndk-bundle/build/tools/make_standalone_toolchain.py \
|
||||||
|
--api=$ANDROID_API --install-dir=$TOOLCHAIN_DIR \
|
||||||
|
--arch=$ARCH --stl libc++
|
||||||
|
set +x
|
||||||
|
printf "Standalone toolchain ready\n"
|
||||||
|
done
|
13
cmd/rand-gui/build.gradle
Normal file
13
cmd/rand-gui/build.gradle
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
|
}
|
||||||
|
ext {
|
||||||
|
archs = "armeabi-v7a,x86"
|
||||||
|
sdkVersion = 26
|
||||||
|
}
|
||||||
|
}
|
102
cmd/rand-gui/darwin.go
Normal file
102
cmd/rand-gui/darwin.go
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
//+build !android
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os/exec"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-gl/gl/v3.2-core/gl"
|
||||||
|
"github.com/go-gl/glfw/v3.2/glfw"
|
||||||
|
//"github.com/golang-ui/nuklear/nk"
|
||||||
|
"gitlab.wow.st/gmp/nuklear/nk"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
win *glfw.Window
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
datadir = "./"
|
||||||
|
fontSize = 24
|
||||||
|
)
|
||||||
|
|
||||||
|
func platformInit() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkWin() {
|
||||||
|
var err error
|
||||||
|
if err = glfw.Init(); err != nil {
|
||||||
|
log(Fatal, err)
|
||||||
|
}
|
||||||
|
glfw.WindowHint(glfw.ContextVersionMajor, 3)
|
||||||
|
glfw.WindowHint(glfw.ContextVersionMinor, 2)
|
||||||
|
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
|
||||||
|
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
|
||||||
|
win, err = glfw.CreateWindow(initWidth, initHeight, "Commute", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
log(Fatal, err)
|
||||||
|
}
|
||||||
|
win.MakeContextCurrent()
|
||||||
|
|
||||||
|
width, height := win.GetSize()
|
||||||
|
log(Info, "created window ", width, "x", height)
|
||||||
|
|
||||||
|
if err := gl.Init(); err != nil {
|
||||||
|
log(Fatal,"opengl: init failed: ", err)
|
||||||
|
}
|
||||||
|
gl.Viewport(0,0, int32(width), int32(height))
|
||||||
|
|
||||||
|
ctx = nk.NkPlatformInit(win, nk.PlatformInstallCallbacks)
|
||||||
|
|
||||||
|
loadFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Terminate() {
|
||||||
|
glfw.Terminate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func PollEvents() {
|
||||||
|
glfw.PollEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSize() (width, height int) {
|
||||||
|
return win.GetSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SwapBuffers() {
|
||||||
|
win.SwapBuffers()
|
||||||
|
}
|
||||||
|
|
||||||
|
func eventloop() {
|
||||||
|
for {
|
||||||
|
// if nk.Animate() && lastY != y {
|
||||||
|
if lastY != y {
|
||||||
|
glfw.WaitEventsTimeout(float64(1/60))
|
||||||
|
} else {
|
||||||
|
time.Sleep(time.Second/60)
|
||||||
|
glfw.WaitEventsTimeout(float64(1))
|
||||||
|
}
|
||||||
|
gfxMain()
|
||||||
|
glfw.WaitEventsTimeout(float64(1/60))
|
||||||
|
gfxMain()
|
||||||
|
if win.ShouldClose() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BackButton(s string) bool {
|
||||||
|
return button(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func Clip(x string) {
|
||||||
|
b := bytes.NewBuffer([]byte(x))
|
||||||
|
cmd := exec.Command("pbcopy")
|
||||||
|
cmd.Stdin = b
|
||||||
|
cmd.Run()
|
||||||
|
}
|
||||||
|
|
28
cmd/rand-gui/log.go
Normal file
28
cmd/rand-gui/log.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
golog "log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type logLevelT int
|
||||||
|
const (
|
||||||
|
Fatal logLevelT = 1 << iota
|
||||||
|
Error
|
||||||
|
Warn
|
||||||
|
Info
|
||||||
|
Debug
|
||||||
|
DebugGfx
|
||||||
|
)
|
||||||
|
|
||||||
|
var loglevel = Fatal | Error | Warn | Info
|
||||||
|
|
||||||
|
func log(level logLevelT, msg ...interface{}) {
|
||||||
|
if level & loglevel != 0 {
|
||||||
|
golog.Print(msg...)
|
||||||
|
}
|
||||||
|
if level & Fatal != 0 {
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
121
cmd/rand-gui/main.go
Normal file
121
cmd/rand-gui/main.go
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// +build darwin linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gitlab.wow.st/gmp/rand"
|
||||||
|
//"gitlab.wow.st/gmp/nuklear/nk"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
|
length = 5
|
||||||
|
buf = make([]byte,16)
|
||||||
|
copy(buf,[]byte(fmt.Sprintf("%d\000",length)))
|
||||||
|
fmt.Println(buf)
|
||||||
|
fun = rand.Char
|
||||||
|
|
||||||
|
generate()
|
||||||
|
log(Info,"Staring event loop")
|
||||||
|
uiInit()
|
||||||
|
eventloop()
|
||||||
|
log(Info,"Event loop returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
maxlen int = 40
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fun func() (byte,error)
|
||||||
|
length int
|
||||||
|
out []byte
|
||||||
|
buf []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
func generate() {
|
||||||
|
if length <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf, err := rand.Slice(fun,length)
|
||||||
|
if err != nil {
|
||||||
|
out = []byte("Error")
|
||||||
|
}
|
||||||
|
out = buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func gfxMain() {
|
||||||
|
if ctx == nil {
|
||||||
|
log(Error,"gfxMain(): ctx is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if uiBegin() {
|
||||||
|
row(4)
|
||||||
|
if button("Char") {
|
||||||
|
fun = rand.Char
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
if button("Letter") {
|
||||||
|
fun = rand.Letter
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
if button("Digit") {
|
||||||
|
fun = rand.Digit
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
if button("Symbol") {
|
||||||
|
fun = rand.Symbol
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
row(3)
|
||||||
|
if button("<") {
|
||||||
|
length -= 1;
|
||||||
|
if length == 0 {
|
||||||
|
length = 1
|
||||||
|
}
|
||||||
|
copy(buf,[]byte(fmt.Sprintf("%d\000",length)))
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
//label(fmt.Sprintf("%d",length),nk.TextAlignCentered | nk.TextAlignMiddle)
|
||||||
|
editstring(buf)
|
||||||
|
lastlen := length
|
||||||
|
nb := make([]byte,0)
|
||||||
|
for i := 0; i < len(buf); i++ {
|
||||||
|
if buf[i] == 0 || buf[i] == '\n' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nb = append(nb,buf[i])
|
||||||
|
}
|
||||||
|
num,err := strconv.Atoi(string(nb))
|
||||||
|
if err == nil {
|
||||||
|
length = num
|
||||||
|
}
|
||||||
|
if length != lastlen {
|
||||||
|
if length > maxlen {
|
||||||
|
length = maxlen
|
||||||
|
}
|
||||||
|
copy(buf,[]byte(fmt.Sprintf("%d\000",length)))
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
if button(">") {
|
||||||
|
length += 1;
|
||||||
|
if length > maxlen {
|
||||||
|
length = maxlen
|
||||||
|
}
|
||||||
|
copy(buf,[]byte(fmt.Sprintf("%d\000",length)))
|
||||||
|
generate()
|
||||||
|
}
|
||||||
|
row(1)
|
||||||
|
if button(string(out)) {
|
||||||
|
Clip(string(out))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uiEnd()
|
||||||
|
}
|
||||||
|
|
1
cmd/rand-gui/settings.gradle
Normal file
1
cmd/rand-gui/settings.gradle
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include ':android'
|
132
cmd/rand-gui/ui.go
Normal file
132
cmd/rand-gui/ui.go
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
// helper functions for UI
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
//"github.com/golang-ui/nuklear/nk"
|
||||||
|
"gitlab.wow.st/gmp/nuklear/nk"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
initWidth = 600
|
||||||
|
initHeight = 400
|
||||||
|
|
||||||
|
maxVertexBuffer = 512 * 1024
|
||||||
|
maxElementBuffer = 128 * 1024
|
||||||
|
|
||||||
|
frametime = time.Second / 30
|
||||||
|
|
||||||
|
rows = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
white nk.Color
|
||||||
|
atlas *nk.FontAtlas
|
||||||
|
sansFont *nk.Font
|
||||||
|
sansFontHandle *nk.UserFont
|
||||||
|
ctx *nk.Context
|
||||||
|
width, height int
|
||||||
|
y, lastY float32
|
||||||
|
)
|
||||||
|
|
||||||
|
func uiInit() {
|
||||||
|
platformInit()
|
||||||
|
mkWin()
|
||||||
|
white = nk.NkRgba(255,255,255,255)
|
||||||
|
table := []nk.Color{
|
||||||
|
nk.NkRgba(70, 70, 70, 255), // NK_COLOR_TEXT
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_WINDOW
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_HEADER
|
||||||
|
nk.NkRgba(0, 0, 0, 255), // NK_COLOR_BORDER
|
||||||
|
nk.NkRgba(185, 185, 185, 255), // NK_COLOR_BUTTON
|
||||||
|
nk.NkRgba(170, 170, 170, 255), // NK_COLOR_BUTTON_HOVER
|
||||||
|
nk.NkRgba(160, 160, 160, 255), // NK_COLOR_BUTTON_ACTIVE
|
||||||
|
nk.NkRgba(150, 150, 150, 255), // NK_COLOR_TOGGLE
|
||||||
|
nk.NkRgba(120, 120, 120, 255), // NK_COLOR_TOGGLE_HOVER
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_TOGGLE_CURSOR
|
||||||
|
nk.NkRgba(190, 190, 190, 255), // NK_COLOR_SELECT
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_SELECT_ACTIVE
|
||||||
|
nk.NkRgba(190, 190, 190, 255), // NK_COLOR_SLIDER
|
||||||
|
nk.NkRgba(80, 80, 80, 255), // NK_COLOR_SLIDER_CURSOR
|
||||||
|
nk.NkRgba(70, 70, 70, 255), // NK_COLOR_SLIDER_CURSOR_HOVER
|
||||||
|
nk.NkRgba(60, 60, 60, 255), // NK_COLOR_SLIDER_CURSOR_ACTIVE
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_PROPERTY
|
||||||
|
nk.NkRgba(150, 150, 150, 255), // NK_COLOR_EDIT
|
||||||
|
nk.NkRgba(0, 0, 0, 255), // NK_COLOR_EDIT_CURSOR
|
||||||
|
nk.NkRgba(175, 175, 175, 255), // NK_COLOR_COMBO
|
||||||
|
nk.NkRgba(160, 160, 160, 255), // NK_COLOR_CHART
|
||||||
|
nk.NkRgba(45, 45, 45, 255), // NK_COLOR_CHART_COLOR
|
||||||
|
nk.NkRgba( 255, 0, 0, 255), // NK_COLOR_CHART_COLOR_HIGHLIGHT
|
||||||
|
nk.NkRgba(180, 180, 180, 255), // NK_COLOR_SCROLLBAR
|
||||||
|
nk.NkRgba(140, 140, 140, 255), // NK_COLOR_SCROLLBAR_CURSOR
|
||||||
|
nk.NkRgba(150, 150, 150, 255), // NK_COLOR_SCROLLBAR_CURSOR_HOVER
|
||||||
|
nk.NkRgba(160, 160, 160, 255), // NK_COLOR_SCROLLBAR_CURSOR_ACTIVE
|
||||||
|
nk.NkRgba(180, 180, 180, 255), // NK_COLOR_TAB_HEADER
|
||||||
|
}
|
||||||
|
_ = table
|
||||||
|
// this scheme comes out all white on Android.
|
||||||
|
//nk.NkStyleFromTable(ctx, table)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadFont() {
|
||||||
|
atlas = nk.NewFontAtlas()
|
||||||
|
nk.NkFontStashBegin(&atlas)
|
||||||
|
sansFont = nk.NkFontAtlasAddFromBytes(atlas, MustAsset("assets/DroidSans.ttf"), fontSize, nil)
|
||||||
|
nk.NkFontStashEnd()
|
||||||
|
if sansFont != nil {
|
||||||
|
sansFontHandle = sansFont.Handle()
|
||||||
|
nk.NkStyleSetFont(ctx, sansFontHandle)
|
||||||
|
}
|
||||||
|
log(Info, "Font added")
|
||||||
|
}
|
||||||
|
|
||||||
|
func row(i int32,hs ...int) {
|
||||||
|
h := 1
|
||||||
|
if len(hs) > 0 {
|
||||||
|
h = hs[0]
|
||||||
|
}
|
||||||
|
nk.NkLayoutRowStatic(ctx,float32(height / (h * rows)),int32(float32(-i)+float32(width-25)/float32(i)),i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func button(text string) bool {
|
||||||
|
return nk.NkButtonLabel(ctx,text) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func label(text string, optss ...nk.Flags) {
|
||||||
|
var opts nk.Flags
|
||||||
|
if len(optss) > 0 {
|
||||||
|
opts = optss[0]
|
||||||
|
} else {
|
||||||
|
opts = nk.TextAlignLeft | nk.TextAlignMiddle
|
||||||
|
}
|
||||||
|
nk.NkLabel(ctx,text,opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func editstring(buf []byte) {
|
||||||
|
nk.NkEditFocus(ctx, nk.EditBox)
|
||||||
|
nk.NkEditStringZeroTerminated(ctx, nk.EditBox, buf, int32(len(buf)), nk.NkFilterAscii)
|
||||||
|
}
|
||||||
|
|
||||||
|
func uiBegin() bool {
|
||||||
|
nk.NkPlatformNewFrame()
|
||||||
|
// NewFrame()
|
||||||
|
lastY = y
|
||||||
|
|
||||||
|
width, height = GetSize()
|
||||||
|
|
||||||
|
bounds := nk.NkRect(0,0,float32(width),float32(height))
|
||||||
|
ret := nk.NkBegin(ctx, "Rand", bounds, nk.WindowScrollAutoHide) > 0
|
||||||
|
wpos := nk.NkWidgetPosition(ctx)
|
||||||
|
lastY = y
|
||||||
|
y = wpos.Y()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func uiEnd() {
|
||||||
|
nk.NkEnd(ctx)
|
||||||
|
nk.NkPlatformRender(nk.AntiAliasingOn, maxVertexBuffer, maxElementBuffer)
|
||||||
|
SwapBuffers()
|
||||||
|
}
|
||||||
|
|
70
cmd/rand/main.go
Normal file
70
cmd/rand/main.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gitlab.wow.st/gmp/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
func usage() {
|
||||||
|
fmt.Println("rand [-d | -l | -s] [num]")
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
args := os.Args[1:]
|
||||||
|
var f func() (byte,error)
|
||||||
|
var n int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
func() {
|
||||||
|
if len(args) == 0 {
|
||||||
|
f = rand.Char
|
||||||
|
n = 20
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(args) >= 1 {
|
||||||
|
switch args[0] {
|
||||||
|
case "-d","--digits":
|
||||||
|
f = rand.Digit
|
||||||
|
case "-l","--letters":
|
||||||
|
f = rand.Letter
|
||||||
|
case "-s","--symbols":
|
||||||
|
f = rand.Symbol
|
||||||
|
default:
|
||||||
|
f = rand.Char
|
||||||
|
n, err = strconv.Atoi(args[0])
|
||||||
|
if err != nil {
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch len(args) {
|
||||||
|
case 1:
|
||||||
|
if n == 0 {
|
||||||
|
n = 20
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if n != 0 {
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
n, err = strconv.Atoi(args[1])
|
||||||
|
if err != nil {
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
s, err := rand.Slice(f,n)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
|
os.Stdout.Write(s)
|
||||||
|
os.Stdout.Write([]byte("\n"))
|
||||||
|
}
|
||||||
|
|
50
main.go
Normal file
50
main.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
crand "crypto/rand"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
var chars []byte = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()_+-=[]{}\\|;:'\",./<>?")
|
||||||
|
var letters []byte = chars[0:52]
|
||||||
|
var digits []byte = chars[52:62]
|
||||||
|
var symbols []byte = chars[62:94]
|
||||||
|
|
||||||
|
func gen(s []byte) (byte,error) {
|
||||||
|
nBig, err := crand.Int(crand.Reader, big.NewInt(int64(len(s))))
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("Error in crypto/rand: %s",err)
|
||||||
|
}
|
||||||
|
x := nBig.Int64()
|
||||||
|
return s[x], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Letter() (byte,error) {
|
||||||
|
return gen(letters)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Digit() (byte,error) {
|
||||||
|
return gen(digits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Symbol() (byte,error) {
|
||||||
|
return gen(symbols)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Char() (byte,error) {
|
||||||
|
return gen(chars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Slice(f func() (byte,error), n int) ([]byte,error) {
|
||||||
|
ret := make([]byte,0)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
x,err := f()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret = append(ret,x)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user