diff --git a/programs/android/template/located_files.txt b/programs/android/template/located_files.txt deleted file mode 100644 index 346a6abe1..000000000 --- a/programs/android/template/located_files.txt +++ /dev/null @@ -1,4 +0,0 @@ -c:\ndk\ndk-build -c:\Program Files\Android\Android Studio\gradle\gradle-2.2.1\bin\gradle.bat -c:\Users\Robert\AppData\Local\Android\sdk1\AVD Manager.exe -c:\Program Files\Android\Android Studio\gradle\gradle-2.4\bin\gradle.bat diff --git a/programs/android/template/notes.txt b/programs/android/template/notes.txt deleted file mode 100644 index 9d80f19a9..000000000 --- a/programs/android/template/notes.txt +++ /dev/null @@ -1,178 +0,0 @@ -This is a template for creating an Android NDK project for Android Studio - -The following steps are performed on this template: - --Copy/Rename 'untitled' folder to new location - -[root] - local.properties: - -replace path references to SDK & NDK - untitled.iml - -rename file - (no other changes for root) - - [.idea] - modules.xml - -untitled - gradle.xml - -path to gradle "gradleHome" - .name - -replace content with new program name - (no other changes for .idea) - - [scopes] - (no changes required) - - [copyright] - (no changes required) - - [gradle] - (no changes required) - - [app] - app.iml - -untitled - build.gradle - -com.example.untitled - -commandLine 'c:\\ndk\\ndk-build.cmd','-C', file('src/main').absolutePath - (no other changes required) - - [src/main] - AndroidManifest.xml - -com.example.untitled - (no other changes required) - - [assets] - (no other changes required) - - [res/values] - strings.xml - -untitled - (no other changes required) - - [jni] - [temp] - -replace with a copy of everything in the temp folder - [c] - -replace with a copy of everything from the c folder - (with selective restrictions) - FILTER: - *.h - *.c - *.cpp - *.mm - EXCLUDE: - [c_compiler/*] - [*/os/*] - Application.mk - -# - #Flags for image dependency - APP_CFLAGS += -D DEPENDENCY_IMAGE_CODEC - #Flags for font dependency - APP_CFLAGS += -D DEPENDENCY_LOADFONT - #Flags for audio dependency - APP_CFLAGS += -D DEPENDENCY_AUDIO_OUT - APP_CFLAGS += -D DEPENDENCY_AUDIO_CONVERSION - APP_CFLAGS += -D DEPENDENCY_AUDIO_DECODE - - Android.mk - -# - ------------------------------------------------------------------------------------------------------------------ -include $(CLEAR_VARS) - -OPENAL_DIR := c/parts/audio/out/android/OpenAL - -AL_SOURCES := \ - $(OPENAL_DIR)/Alc/android.c \ - $(OPENAL_DIR)/OpenAL32/alAuxEffectSlot.c \ - $(OPENAL_DIR)/OpenAL32/alBuffer.c \ - $(OPENAL_DIR)/OpenAL32/alDatabuffer.c \ - $(OPENAL_DIR)/OpenAL32/alEffect.c \ - $(OPENAL_DIR)/OpenAL32/alError.c \ - $(OPENAL_DIR)/OpenAL32/alExtension.c \ - $(OPENAL_DIR)/OpenAL32/alFilter.c \ - $(OPENAL_DIR)/OpenAL32/alListener.c \ - $(OPENAL_DIR)/OpenAL32/alSource.c \ - $(OPENAL_DIR)/OpenAL32/alState.c \ - $(OPENAL_DIR)/OpenAL32/alThunk.c \ - $(OPENAL_DIR)/Alc/ALc.c \ - $(OPENAL_DIR)/Alc/alcConfig.c \ - $(OPENAL_DIR)/Alc/alcEcho.c \ - $(OPENAL_DIR)/Alc/alcModulator.c \ - $(OPENAL_DIR)/Alc/alcReverb.c \ - $(OPENAL_DIR)/Alc/alcRing.c \ - $(OPENAL_DIR)/Alc/alcThread.c \ - $(OPENAL_DIR)/Alc/ALu.c \ - $(OPENAL_DIR)/Alc/bs2b.c \ - $(OPENAL_DIR)/Alc/null.c \ - $(OPENAL_DIR)/Alc/panning.c \ - $(OPENAL_DIR)/Alc/mixer.c \ - $(OPENAL_DIR)/Alc/audiotrack.c \ - $(OPENAL_DIR)/Alc/opensles.c - - -LOCAL_MODULE := parts_audio_out -LOCAL_SRC_FILES := $(AL_SOURCES) - -LOCAL_C_INCLUDES := \ - $(HOME)/src/openal-soft/jni/OpenAL \ - $(HOME)/src/openal-soft/jni/OpenAL/include \ - $(HOME)/src/openal-soft/jni/OpenAL/OpenAL32/Include \ - c/parts/audio/out/android/OpenAL/OpenAL32/Include - -LOCAL_CFLAGS += \ - -DAL_ALEXT_PROTOTYPES \ - -MAX_SOURCES_LOW ?= 4 -MAX_SOURCES_START ?= 8 -MAX_SOURCES_HIGH ?= 64 - -LOCAL_CFLAGS += -DMAX_SOURCES_LOW=$(MAX_SOURCES_LOW) -DMAX_SOURCES_START=$(MAX_SOURCES_START) -DMAX_SOURCES_HIGH=$(MAX_SOURCES_HIGH) -LOCAL_CFLAGS += -DPOST_FROYO - -include $(BUILD_STATIC_LIBRARY) - - - - - -# PARTS/AUDIO/CONVERSION -include $(CLEAR_VARS) -LOCAL_MODULE := parts_audio_conversion -LOCAL_SRC_FILES := c/parts/audio/conversion/src/samplerate.c -LOCAL_SRC_FILES += c/parts/audio/conversion/src/src_linear.c -LOCAL_SRC_FILES += c/parts/audio/conversion/src/src_sinc.c -LOCAL_SRC_FILES += c/parts/audio/conversion/src/src_zoh.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - -# PARTS/AUDIO/CONVERSION -include $(CLEAR_VARS) -LOCAL_MODULE := parts_audio_decode_mp3 -LOCAL_SRC_FILES := c/parts/audio/decode/mp3_mini/src/minimp3.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - - -# PARTS/VIDEO/FONT/TTF -include $(CLEAR_VARS) -LOCAL_MODULE := parts_video_font_ttf -LOCAL_SRC_FILES := c/parts/video/font/ttf/src/freetypeamalgam.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) ------------------------------------------------------------------------------------------------------------------ - - -# - LOCAL_STATIC_LIBRARIES += parts_video_font_ttf - LOCAL_STATIC_LIBRARIES += parts_audio_out - LOCAL_STATIC_LIBRARIES += parts_audio_conversion - LOCAL_STATIC_LIBRARIES += parts_audio_decode_mp3 - - (no other changes required) diff --git a/programs/android/template/untitled/.idea/.name b/programs/android/template/untitled/.idea/.name deleted file mode 100644 index 64f7f1b5b..000000000 --- a/programs/android/template/untitled/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -untitled \ No newline at end of file diff --git a/programs/android/template/untitled/.idea/compiler.xml b/programs/android/template/untitled/.idea/compiler.xml deleted file mode 100644 index 217af471a..000000000 --- a/programs/android/template/untitled/.idea/compiler.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/programs/android/template/untitled/.idea/copyright/profiles_settings.xml b/programs/android/template/untitled/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf337..000000000 --- a/programs/android/template/untitled/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/programs/android/template/untitled/.idea/encodings.xml b/programs/android/template/untitled/.idea/encodings.xml deleted file mode 100644 index e206d70d8..000000000 --- a/programs/android/template/untitled/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/programs/android/template/untitled/.idea/gradle.xml b/programs/android/template/untitled/.idea/gradle.xml deleted file mode 100644 index dffab7afd..000000000 --- a/programs/android/template/untitled/.idea/gradle.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - diff --git a/programs/android/template/untitled/.idea/misc.xml b/programs/android/template/untitled/.idea/misc.xml deleted file mode 100644 index 9076de565..000000000 --- a/programs/android/template/untitled/.idea/misc.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/programs/android/template/untitled/.idea/modules.xml b/programs/android/template/untitled/.idea/modules.xml deleted file mode 100644 index e7542c636..000000000 --- a/programs/android/template/untitled/.idea/modules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/programs/android/template/untitled/.idea/scopes/scope_settings.xml b/programs/android/template/untitled/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b84..000000000 --- a/programs/android/template/untitled/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/programs/android/template/untitled/.idea/vcs.xml b/programs/android/template/untitled/.idea/vcs.xml deleted file mode 100644 index def6a6a18..000000000 --- a/programs/android/template/untitled/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/programs/android/template/untitled/app/app.iml b/programs/android/template/untitled/app/app.iml deleted file mode 100644 index d82d1de57..000000000 --- a/programs/android/template/untitled/app/app.iml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/programs/android/template/untitled/app/build.gradle b/programs/android/template/untitled/app/build.gradle deleted file mode 100644 index 4c7d72451..000000000 --- a/programs/android/template/untitled/app/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" - - - sourceSets.main { - jni.srcDirs = [] - jniLibs.srcDir 'src/main/libs' - } - - defaultConfig { - applicationId "com.example.untitled" - minSdkVersion 11 - targetSdkVersion 11 - - ndk { - //moduleName "native-activity" - stl "stlport_static" - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' - } - } - - // call regular ndk-build(.cmd) script from app directory - task ndkBuild(type: Exec) { - commandLine '$QB64_NDK_BUILD_CMD_FILE$','-C', file('src/main').absolutePath - } - - tasks.withType(JavaCompile) { - compileTask -> compileTask.dependsOn ndkBuild - } - -} diff --git a/programs/android/template/untitled/app/src/main/AndroidManifest.xml b/programs/android/template/untitled/app/src/main/AndroidManifest.xml deleted file mode 100644 index cbce140ac..000000000 --- a/programs/android/template/untitled/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/programs/android/template/untitled/app/src/main/Thumbs.db b/programs/android/template/untitled/app/src/main/Thumbs.db deleted file mode 100644 index 73bb945d0..000000000 Binary files a/programs/android/template/untitled/app/src/main/Thumbs.db and /dev/null differ diff --git a/programs/android/template/untitled/app/src/main/assets/Thumbs.db b/programs/android/template/untitled/app/src/main/assets/Thumbs.db deleted file mode 100644 index 5766945bd..000000000 Binary files a/programs/android/template/untitled/app/src/main/assets/Thumbs.db and /dev/null differ diff --git a/programs/android/template/untitled/app/src/main/assets/emptyfolder.bin b/programs/android/template/untitled/app/src/main/assets/emptyfolder.bin deleted file mode 100644 index e69de29bb..000000000 diff --git a/programs/android/template/untitled/app/src/main/jni/Android.mk b/programs/android/template/untitled/app/src/main/jni/Android.mk deleted file mode 100644 index 1d47fb236..000000000 --- a/programs/android/template/untitled/app/src/main/jni/Android.mk +++ /dev/null @@ -1,199 +0,0 @@ -# Copyright (C) 2010 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) - - -# - - -include $(CLEAR_VARS) - -OPENAL_DIR := c/parts/audio/out/android/OpenAL - -AL_SOURCES := \ - $(OPENAL_DIR)/Alc/android.c \ - $(OPENAL_DIR)/OpenAL32/alAuxEffectSlot.c \ - $(OPENAL_DIR)/OpenAL32/alBuffer.c \ - $(OPENAL_DIR)/OpenAL32/alDatabuffer.c \ - $(OPENAL_DIR)/OpenAL32/alEffect.c \ - $(OPENAL_DIR)/OpenAL32/alError.c \ - $(OPENAL_DIR)/OpenAL32/alExtension.c \ - $(OPENAL_DIR)/OpenAL32/alFilter.c \ - $(OPENAL_DIR)/OpenAL32/alListener.c \ - $(OPENAL_DIR)/OpenAL32/alSource.c \ - $(OPENAL_DIR)/OpenAL32/alState.c \ - $(OPENAL_DIR)/OpenAL32/alThunk.c \ - $(OPENAL_DIR)/Alc/ALc.c \ - $(OPENAL_DIR)/Alc/alcConfig.c \ - $(OPENAL_DIR)/Alc/alcEcho.c \ - $(OPENAL_DIR)/Alc/alcModulator.c \ - $(OPENAL_DIR)/Alc/alcReverb.c \ - $(OPENAL_DIR)/Alc/alcRing.c \ - $(OPENAL_DIR)/Alc/alcThread.c \ - $(OPENAL_DIR)/Alc/ALu.c \ - $(OPENAL_DIR)/Alc/bs2b.c \ - $(OPENAL_DIR)/Alc/null.c \ - $(OPENAL_DIR)/Alc/panning.c \ - $(OPENAL_DIR)/Alc/mixer.c \ - $(OPENAL_DIR)/Alc/audiotrack.c \ - $(OPENAL_DIR)/Alc/opensles.c - - -LOCAL_MODULE := parts_audio_out -LOCAL_SRC_FILES := $(AL_SOURCES) - -LOCAL_C_INCLUDES := \ - $(HOME)/src/openal-soft/jni/OpenAL \ - $(HOME)/src/openal-soft/jni/OpenAL/include \ - $(HOME)/src/openal-soft/jni/OpenAL/OpenAL32/Include \ - c/parts/audio/out/android/OpenAL/OpenAL32/Include - -LOCAL_CFLAGS += \ - -DAL_ALEXT_PROTOTYPES \ - -MAX_SOURCES_LOW ?= 4 -MAX_SOURCES_START ?= 8 -MAX_SOURCES_HIGH ?= 64 - -LOCAL_CFLAGS += -DMAX_SOURCES_LOW=$(MAX_SOURCES_LOW) -DMAX_SOURCES_START=$(MAX_SOURCES_START) -DMAX_SOURCES_HIGH=$(MAX_SOURCES_HIGH) -LOCAL_CFLAGS += -DPOST_FROYO - -include $(BUILD_STATIC_LIBRARY) - -# PARTS/AUDIO/CONVERSION -include $(CLEAR_VARS) -LOCAL_MODULE := parts_audio_conversion -LOCAL_SRC_FILES := c/parts/audio/conversion/src/resample.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - -# PARTS/AUDIO/DECODE/MP3 -include $(CLEAR_VARS) -LOCAL_MODULE := parts_audio_decode_mp3 -LOCAL_SRC_FILES := c/parts/audio/decode/mp3_mini/src/minimp3.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - -# PARTS/AUDIO/DECODE/OGG -include $(CLEAR_VARS) -LOCAL_MODULE := parts_audio_decode_ogg -LOCAL_SRC_FILES := c/parts/audio/decode/ogg/src/stb_vorbis.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - -# PARTS/VIDEO/FONT/TTF -include $(CLEAR_VARS) -LOCAL_MODULE := parts_video_font_ttf -LOCAL_SRC_FILES := c/parts/video/font/ttf/src/freetypeamalgam.c -#LOCAL_CFLAGS := -#LOCAL_C_INCLUDES := -include $(BUILD_STATIC_LIBRARY) -#include $(PREBUILT_STATIC_LIBRARY) - - -include $(CLEAR_VARS) - - - -LOCAL_MODULE := native-activity - -LOCAL_SRC_FILES := main.cpp c/qbx.cpp -#LOCAL_SRC_FILES := main.c GL/glew.c tut.cpp - -#GLU ES -LOCAL_C_INCLUDES += $(LOCAL_PATH)/c/parts/core/glues/src -LOCAL_SRC_FILES += c/parts/core/glues/src/glues_error.c -LOCAL_SRC_FILES += c/parts/core/glues/src/glues_mipmap.c -LOCAL_SRC_FILES += c/parts/core/glues/src/glues_project.c -LOCAL_SRC_FILES += c/parts/core/glues/src/glues_quad.c -LOCAL_SRC_FILES += c/parts/core/glues/src/glues_registry.c -#(libtess folder not added, probably not required) - -#FreeGlut -LOCAL_C_INCLUDES += $(LOCAL_PATH)/c/parts/core/android_core/include -LOCAL_C_INCLUDES += $(LOCAL_PATH)/c/parts/core/android_core/src - -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_callbacks.c -#LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_cursor.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_display.c -#LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_ext.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_font_data.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_gamemode.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_init.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_internal.h -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_input_devices.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_joystick.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_main.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_misc.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_overlay.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_spaceball.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_state.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_stroke_mono_roman.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_stroke_roman.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_structure.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_videoresize.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_window.c - -#LOCAL_SRC_FILES += c/parts/core/android_core/src/fg_menu.c - -LOCAL_SRC_FILES += c/parts/core/android_core/src/util/xparsegeometry_repl.c - - -#===ANDROID SPECIFIC FILES (also required) -LOCAL_SRC_FILES += c/parts/core/android_core/src/egl/fg_internal_egl.h -LOCAL_SRC_FILES += c/parts/core/android_core/src/egl/fg_display_egl.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/egl/fg_init_egl.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/egl/fg_structure_egl.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/egl/fg_window_egl.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/native_app_glue/android_native_app_glue.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/native_app_glue/android_native_app_glue.h -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_runtime_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_gamemode_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_input_devices_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_joystick_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_main_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_spaceball_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_state_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_window_android.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/opengles_stubs.c -LOCAL_SRC_FILES += c/parts/core/android_core/src/android/fg_internal_android.h - - - -LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM -lOpenSLES - - -#LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 - - - -LOCAL_STATIC_LIBRARIES := android_native_app_glue -LOCAL_CFLAGS := -w - -# -LOCAL_STATIC_LIBRARIES += parts_video_font_ttf -LOCAL_STATIC_LIBRARIES += parts_audio_out -LOCAL_STATIC_LIBRARIES += parts_audio_conversion -LOCAL_STATIC_LIBRARIES += parts_audio_decode_mp3 -LOCAL_STATIC_LIBRARIES += parts_audio_decode_ogg -include $(BUILD_SHARED_LIBRARY) - -$(call import-module,android/native_app_glue) diff --git a/programs/android/template/untitled/app/src/main/jni/Application.mk b/programs/android/template/untitled/app/src/main/jni/Application.mk deleted file mode 100644 index b35c97cf3..000000000 --- a/programs/android/template/untitled/app/src/main/jni/Application.mk +++ /dev/null @@ -1,38 +0,0 @@ -APP_PLATFORM := android-10 -#APP_PLATFORM := android-9 - -#APP_ABI := armeabi -# Android 4+ (Ice Cream Sandwich) requires an ARMv7 processor. (Some custom versions of Android 4+ have been made for ARMv6) -# Therefore, there isn't much point producing armeabi binaries - -APP_ABI := armeabi-v7a -APP_ABI += x86 - -APP_STL := gnustl_static - -APP_CFLAGS := -DANDROID -APP_CFLAGS += -DHAVE_STDBOOL_H -APP_CFLAGS += -DNEED_XPARSEGEOMETRY_IMPL -APP_CFLAGS += -DHAVE_XPARSEGEOMETRY -APP_CFLAGS += -DEGL_VERSION_1_0 -APP_CFLAGS += -D GL_GLEXT_PROTOTYPES - - -APP_CFLAGS += -DVERSION_MAJOR=3 -APP_CFLAGS += -DVERSION_MINOR=0 -APP_CFLAGS += -DVERSION_PATCH=0 - - -# - -#Flags for image dependency -APP_CFLAGS += -D DEPENDENCY_IMAGE_CODEC - -#Flags for font dependency -APP_CFLAGS += -D DEPENDENCY_LOADFONT - -#Flags for audio dependency -APP_CFLAGS += -D DEPENDENCY_AUDIO_OUT -APP_CFLAGS += -D DEPENDENCY_AUDIO_CONVERSION -APP_CFLAGS += -D DEPENDENCY_AUDIO_DECODE - diff --git a/programs/android/template/untitled/app/src/main/jni/c/emptyfolder.bin b/programs/android/template/untitled/app/src/main/jni/c/emptyfolder.bin deleted file mode 100644 index e69de29bb..000000000 diff --git a/programs/android/template/untitled/app/src/main/jni/main.cpp b/programs/android/template/untitled/app/src/main/jni/main.cpp deleted file mode 100644 index 32d79ea15..000000000 --- a/programs/android/template/untitled/app/src/main/jni/main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "FreeGLUT", __VA_ARGS__)) - -/* -#include -#include -#include -*/ -#include "c/libqb.cpp" - \ No newline at end of file diff --git a/programs/android/template/untitled/app/src/main/jni/temp/emptyfolder.bin b/programs/android/template/untitled/app/src/main/jni/temp/emptyfolder.bin deleted file mode 100644 index e69de29bb..000000000 diff --git a/programs/android/template/untitled/app/src/main/res/values/strings.xml b/programs/android/template/untitled/app/src/main/res/values/strings.xml deleted file mode 100644 index cdeb37251..000000000 --- a/programs/android/template/untitled/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - untitled - diff --git a/programs/android/template/untitled/build.gradle b/programs/android/template/untitled/build.gradle deleted file mode 100644 index 6a5c233c5..000000000 --- a/programs/android/template/untitled/build.gradle +++ /dev/null @@ -1,15 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' - } -} - -allprojects { - repositories { - jcenter() - } -} diff --git a/programs/android/template/untitled/gradle.properties b/programs/android/template/untitled/gradle.properties deleted file mode 100644 index d72861d28..000000000 --- a/programs/android/template/untitled/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -android.useDeprecatedNdk=true \ No newline at end of file diff --git a/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.jar b/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a8..000000000 Binary files a/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.properties b/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 0c71e760d..000000000 --- a/programs/android/template/untitled/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Apr 10 15:27:10 PDT 2013 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/programs/android/template/untitled/gradlew b/programs/android/template/untitled/gradlew deleted file mode 100644 index 91a7e269e..000000000 --- a/programs/android/template/untitled/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/programs/android/template/untitled/gradlew.bat b/programs/android/template/untitled/gradlew.bat deleted file mode 100644 index 8a0b282aa..000000000 --- a/programs/android/template/untitled/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/programs/android/template/untitled/local.properties b/programs/android/template/untitled/local.properties deleted file mode 100644 index f2e7798e8..000000000 --- a/programs/android/template/untitled/local.properties +++ /dev/null @@ -1,8 +0,0 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# -#Sun Apr 05 17:45:27 AEST 2015 -sdk.dir=C\:\\Users\\Robert\\AppData\\Local\\Android\\sdk1 -ndk.dir=C\:\\ndk \ No newline at end of file diff --git a/programs/android/template/untitled/settings.gradle b/programs/android/template/untitled/settings.gradle deleted file mode 100644 index e7b4def49..000000000 --- a/programs/android/template/untitled/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/programs/android/template/untitled/untitled.iml b/programs/android/template/untitled/untitled.iml deleted file mode 100644 index 0bb6048ae..000000000 --- a/programs/android/template/untitled/untitled.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/source/embed/footer_stub.bas b/source/embed/footer_stub.bas new file mode 100644 index 000000000..6d8004f6d --- /dev/null +++ b/source/embed/footer_stub.bas @@ -0,0 +1,2 @@ +SUB VkUpdate +END SUB diff --git a/source/embed/header_stub.bas b/source/embed/header_stub.bas new file mode 100644 index 000000000..fb300439a --- /dev/null +++ b/source/embed/header_stub.bas @@ -0,0 +1,3 @@ +'blank line +CONST TRUE = -1 +CONST FALSE = 0 diff --git a/source/qb64.bas b/source/qb64.bas index 3023639af..654905f7e 100644 --- a/source/qb64.bas +++ b/source/qb64.bas @@ -18,9 +18,6 @@ $SCREENHIDE 'INCLUDE:'qb_framework\qb_framework_global.bas' DEFLNG A-Z -'INCLUDE:'virtual_keyboard\virtual_keyboard_global.bas' -DEFLNG A-Z - '-------- Optional IDE Component (1/2) -------- '$INCLUDE:'ide\ide_global.bas' @@ -29,10 +26,6 @@ REDIM SHARED PL(0) AS INTEGER 'Priority Level DIM SHARED QuickReturn AS INTEGER Set_OrderOfOperations 'This will also make certain our directories are valid, and if not make them. -DIM SHARED VirtualKeyboardState -DIM SHARED DesiredVirtualKeyboardState -DIM SHARED RecompileAttemptsForVirtualKeyboardState - REDIM EveryCaseSet(100), SelectCaseCounter AS _UNSIGNED LONG DIM ExecLevel(255), ExecCounter AS INTEGER REDIM SHARED UserDefine(1, 100) AS STRING '0 element is the name, 1 element is the string value @@ -1192,14 +1185,8 @@ sflistn = -1 'no entries SubNameLabels = sp 'QB64 will perform a repass to resolve sub names used as labels -DesiredVirtualKeyboardState = 0 -RecompileAttemptsForVirtualKeyboardState = 0 - recompile: -'move desired state into active state -VirtualKeyboardState = DesiredVirtualKeyboardState - lastLineReturn = 0 lastLine = 0 firstLine = 1 @@ -1572,13 +1559,8 @@ DO IF lastLine <> 0 OR firstLine <> 0 THEN lineBackup$ = wholeline$ 'backup the real line (will be blank when lastline is set) - IF VirtualKeyboardState THEN - IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\header.bas" - IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\footer.bas" - ELSE - IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\header_stub.bas" - IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\footer_stub.bas" - END IF + IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\embed\header_stub.bas" + IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\embed\footer_stub.bas" firstLine = 0: lastLine = 0 GOTO forceInclude_prepass forceIncludeCompleted_prepass: @@ -1605,32 +1587,6 @@ DO temp$ = LTRIM$(RTRIM$(UCASE$(wholestv$))) - IF temp$ = "$VIRTUALKEYBOARD:ON" THEN - DesiredVirtualKeyboardState = 1 - IF VirtualKeyboardState = 0 THEN - IF RecompileAttemptsForVirtualKeyboardState = 0 THEN - 'this is the first time a conflict has occurred, so react immediately with a full recompilation using the desired state - RecompileAttemptsForVirtualKeyboardState = RecompileAttemptsForVirtualKeyboardState + 1 - GOTO do_recompile - ELSE - 'continue compilation to retrieve the final state requested and act on that as required - END IF - END IF - END IF - - IF temp$ = "$VIRTUALKEYBOARD:OFF" THEN - DesiredVirtualKeyboardState = 0 - IF VirtualKeyboardState <> 0 THEN - IF RecompileAttemptsForVirtualKeyboardState = 0 THEN - 'this is the first time a conflict has occurred, so react immediately with a full recompilation using the desired state - RecompileAttemptsForVirtualKeyboardState = RecompileAttemptsForVirtualKeyboardState + 1 - GOTO do_recompile - ELSE - 'continue compilation to retrieve the final state requested and act on that as required - END IF - END IF - END IF - IF LEFT$(temp$, 4) = "$IF " THEN IF RIGHT$(temp$, 5) <> " THEN" THEN a$ = "$IF without THEN": GOTO errmes temp$ = LTRIM$(MID$(temp$, 4)) 'strip off the $IF and extra spaces @@ -2929,13 +2885,8 @@ DO IF lastLine <> 0 OR firstLine <> 0 THEN lineBackup$ = a3$ 'backup the real first line (will be blank when lastline is set) - IF VirtualKeyboardState THEN - IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\header.bas" - IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\footer.bas" - ELSE - IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\header_stub.bas" - IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\virtual_keyboard\embed\footer_stub.bas" - END IF + IF firstLine <> 0 THEN forceIncludeFromRoot$ = "source\embed\header_stub.bas" + IF lastLine <> 0 THEN forceIncludeFromRoot$ = "source\embed\footer_stub.bas" firstLine = 0: lastLine = 0 GOTO forceInclude forceIncludeCompleted: @@ -3126,11 +3077,13 @@ DO END IF IF a3u$ = "$VIRTUALKEYBOARD:ON" THEN + 'Deprecated; does nothing. layout$ = "$VIRTUALKEYBOARD:ON" GOTO finishednonexec END IF IF a3u$ = "$VIRTUALKEYBOARD:OFF" THEN + 'Deprecated; does nothing. layout$ = "$VIRTUALKEYBOARD:OFF" GOTO finishednonexec END IF @@ -10988,11 +10941,6 @@ FOR x = 1 TO commonarraylistn NEXT IF Debug THEN PRINT #9, "Finished COMMON array list check!" -IF DesiredVirtualKeyboardState <> VirtualKeyboardState THEN - RecompileAttemptsForVirtualKeyboardState = RecompileAttemptsForVirtualKeyboardState + 1 - recompile = 1 -END IF - IF recompile THEN do_recompile: IF Debug THEN PRINT #9, "Recompile required!" @@ -24888,8 +24836,5 @@ END SUB 'INCLUDE:'qb_framework\qb_framework_methods.bas' DEFLNG A-Z -'INCLUDE:'virtual_keyboard\virtual_keyboard_methods.bas' -DEFLNG A-Z - '-------- Optional IDE Component (2/2) -------- '$INCLUDE:'ide\ide_methods.bas' diff --git a/source/qb_framework/qb_framework_global.bas b/source/qb_framework/qb_framework_global.bas deleted file mode 100644 index 1ac2adccd..000000000 --- a/source/qb_framework/qb_framework_global.bas +++ /dev/null @@ -1,172 +0,0 @@ -'#################### QB-FRAMEWORK: Environment #################### -DEFLNG A-Z -'DEFLNG A-Z isn't required, but certain functions require LONG type variables -'as their parameters and return data in them, for example QB_NODE_each(...) -'################################################## - -'#################### QB-FRAMEWORK: Global #################### -DIM SHARED QB_DEBUG AS LONG '1 or 0 -DIM SHARED QB_DEBUG_VERBOSE AS LONG '1 or 0 -QB_DEBUG = 0 -QB_DEBUG_VERBOSE = 0 'set in conjunction with QB_DEBUG for more detailed debug infromation -IF QB_DEBUG_VERBOSE THEN QB_DEBUG = 1 -'Quick copy-paste references: -' QB_DEBUG_VERBOSE = 1: QB_DEBUG = 1 -' QB_DEBUG_VERBOSE = 0: QB_DEBUG = 0 -'################################################## - -'#################### EACH: Global #################### -'Handle Handlers (used to manage a set of handles) -CONST QB_EACH_NO_BLANK& = 0 'the default, blank entries will not be returned -CONST QB_EACH_ALLOW_BLANK& = 1 'captures implied blanks in adjacent, leading & trailing separators -CONST QB_EACH_ALLOW_ALL_BLANK& = 2 'also captures blank if entire parent is blank (not captured by default) - -'#################### HANDLE: Global #################### -'Handle Handlers (used to manage a set of handles) -TYPE __QB_HANDLE_HANDLER - lastFreedListIndex AS LONG '0=none - lastHandle AS LONG - count AS LONG -END TYPE -REDIM SHARED __QB_HANDLE_handler(1 + 0) AS __QB_HANDLE_HANDLER -'manually setup the first handle handler to maintain handles to our handle handlers -__QB_HANDLE_handler(1).lastHandle = 1 -__QB_HANDLE_handler(1).lastFreedListIndex = 0 -'Freed List -TYPE __QB_HANDLE_FREEDLIST - handle AS LONG - prevFreedListIndex AS LONG 'of same owner -END TYPE -REDIM SHARED __QB_HANDLE_freedList(1 + 0) AS __QB_HANDLE_FREEDLIST -DIM SHARED __QB_HANDLE_freedList_Last AS LONG: __QB_HANDLE_freedList_Last = 1 -DIM SHARED __QB_HANDLE_freedList_Next AS LONG: __QB_HANDLE_freedList_Next = 1 -'Freed-Freed List -REDIM SHARED __QB_HANDLE_freedFreedList(1 + 0) AS LONG -DIM SHARED __QB_HANDLE_freedFreedList_Last AS LONG: __QB_HANDLE_freedFreedList_Last = 1 -DIM SHARED __QB_HANDLE_freedFreedList_Next AS LONG: __QB_HANDLE_freedFreedList_Next = 1 -'################################################## - -'#################### DATETIME: Global #################### -CONST QB_DATETIME_TYPE_LOCAL = 1 'local time -CONST QB_DATETIME_TYPE_OFFSET = 3 -CONST QB_DATETIME_TYPE_DURATION = 4 -'For duration: -' 1 day=24 hours regardless of timezone -' 1 year=366 days regardless of year -' 1 month=31 days regardless of month -TYPE QB_DATETIME - reserved AS LONG - days AS LONG '1-31 - months AS LONG '1-12 - years AS LONG 'eg. 2015 - hours AS LONG '0-23 - minutes AS LONG '0-59 - seconds AS LONG '0-59 - milliseconds AS LONG '0-999 - microseconds AS LONG '0-999 (a microsecond is 1/1000th of a millisecond) - type AS LONG -END TYPE -DIM SHARED __QB_DATETIME_TYPE_EMPTY AS QB_DATETIME -REDIM SHARED __QB_DATETIME(0 + 1) AS QB_DATETIME -DIM SHARED __QB_DATETIME_ubound AS LONG: __QB_DATETIME_ubound = 1 -DIM SHARED __QB_DATETIME_handleSet AS LONG: __QB_DATETIME_handleSet = QB_HANDLE_newSet -'################################################## - -'#################### STRING: Global #################### -REDIM SHARED __QB_STR_string(1 + 0) AS STRING -REDIM SHARED __QB_STR_stringValid(1 + 0) AS LONG -DIM SHARED __QB_STR_stringUbound AS LONG: __QB_STR_stringUbound = 1 -DIM SHARED __QB_STR_handleSet AS LONG: __QB_STR_handleSet = QB_HANDLE_newSet -DIM SHARED QB_STR_QUOTE AS STRING: QB_STR_QUOTE = CHR$(34) -'################################################## - -'#################### NODE: Global #################### -CONST QB_NODE_TYPE_HASHSET& = 1 -CONST QB_NODE_TYPE_LIST& = 2 -CONST QB_NODE_TYPE_DICTIONARY& = 4 -CONST QB_NODE_TYPE_VALUE& = 8 'a simple value, optionally with a label - -CONST QB_NODE_ALLOW_DUPLICATE_KEYS& = 256 -CONST QB_NODE_CASE_SENSITIVE& = 512 -CONST QB_NODE_AVOID_DUPLICATE_VALUES_PER_KEY& = 1024 'new entries will not be added to a key if it already contains the value unless nTh is specified -CONST QB_NODE_DUPLICATE_VALUES_CASE_SENSITIVE& = 2048 'duplicate values check is case sensitive -CONST QB_NODE_DESTROY_ORPHANED_CHILDNODES& = 4096 - -CONST QB_NODE_FORMAT_LONG& = 1 -CONST QB_NODE_FORMAT_STR& = 2 -CONST QB_NODE_FORMAT_BOOL& = 4 -CONST QB_NODE_FORMAT_NULL& = 8 - -CONST QB_TRUE& = -1 -CONST QB_FALSE& = 0 -CONST QB_NULL& = -2 - -TYPE QB_NODE_TYPE - valid AS LONG - type AS LONG - flags AS LONG - 'linkage - parent AS LONG - firstChild AS LONG - lastChild AS LONG - count AS LONG - next AS LONG - prev AS LONG - owner AS LONG 'optional - 'label & value - label AS LONG - labelFormat AS LONG 'eg. QB_NODE_FORMAT_STR - value AS LONG - valueFormat AS LONG - 'hashsets & dictionaries - hashOffset AS LONG 'added to all keys to increase the chance of uniqueness against other KVP sets with different owners - hashReference AS LONG 'handle/value of the hashtable reference which points to this node -END TYPE - -DIM SHARED QB_NODE_TYPE_EMPTY AS QB_NODE_TYPE -QB_NODE_TYPE_EMPTY.labelFormat = QB_NODE_FORMAT_NULL -QB_NODE_TYPE_EMPTY.valueFormat = QB_NODE_FORMAT_NULL -REDIM SHARED __QB_NODE(0 + 1) AS QB_NODE_TYPE -REDIM SHARED __QB_NODE_hashLists(0 + 16777215) AS LONG -DIM SHARED __QB_NODE_ubound: __QB_NODE_ubound = 1 -DIM SHARED __QB_NODE_handleSet AS LONG: __QB_NODE_handleSet = QB_HANDLE_newSet - -'################################################## - -'#################### __JSON: Global #################### -CONST QB_JSON_STRING& = 1 -CONST QB_JSON_NUMBER& = 2 -CONST QB_JSON_BOOL& = 3 -CONST QB_JSON_NULL& = 4 -'http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf -'\b Backspace CHR$(8) -'\f Form feed CHR$(12) -'\n New line CHR$(10) -'\r Carriage return CHR$(13) -'\t Tab CHR$(9) -'\" Double quote CHR$(34) -'\\ Backslash caracter CHR$(92) -DIM SHARED __QB_JSON_escape_lookup(255) AS LONG -__QB_JSON_escape_lookup(8) = ASC("b") -__QB_JSON_escape_lookup(12) = ASC("f") -__QB_JSON_escape_lookup(10) = ASC("n") -__QB_JSON_escape_lookup(13) = ASC("r") -__QB_JSON_escape_lookup(9) = ASC("t") -__QB_JSON_escape_lookup(34) = 34 -__QB_JSON_escape_lookup(92) = ASC("\") -DIM SHARED __QB_JSON_escape_lookup_reversed(255) AS LONG -__QB_JSON_escape_lookup_reversed(ASC("b")) = 8 -__QB_JSON_escape_lookup_reversed(ASC("f")) = 12 -__QB_JSON_escape_lookup_reversed(ASC("n")) = 10 -__QB_JSON_escape_lookup_reversed(ASC("r")) = 13 -__QB_JSON_escape_lookup_reversed(ASC("t")) = 9 -__QB_JSON_escape_lookup_reversed(34) = 34 -__QB_JSON_escape_lookup_reversed(ASC("\")) = 92 -__QB_JSON_escape_lookup_reversed(ASC("B")) = 8 -__QB_JSON_escape_lookup_reversed(ASC("F")) = 12 -__QB_JSON_escape_lookup_reversed(ASC("N")) = 10 -__QB_JSON_escape_lookup_reversed(ASC("R")) = 13 -__QB_JSON_escape_lookup_reversed(ASC("T")) = 9 -__QB_JSON_escape_lookup_reversed(ASC("'")) = 39 'allow for escaping single quotes \' -_MAPUNICODE &H00A0~& TO 255 -'################################################## diff --git a/source/qb_framework/qb_framework_methods.bas b/source/qb_framework/qb_framework_methods.bas deleted file mode 100644 index cc471fb5b..000000000 --- a/source/qb_framework/qb_framework_methods.bas +++ /dev/null @@ -1,1968 +0,0 @@ -DEFLNG A-Z - -'#################### NODESET: Methods #################### - -FUNCTION QB_FRAMEWORK_leakInfo$ -DIM QB__handlesets AS LONG -QB__handlesets = QB_HANDLE_count(1) -DIM QB__nodes AS LONG -QB__nodes = QB_HANDLE_count(__QB_NODE_handleSet) -DIM QB__datetimes AS LONG -QB__datetimes = QB_HANDLE_count(__QB_DATETIME_handleSet) -DIM QB__strings AS LONG -QB__strings = QB_HANDLE_count(__QB_STR_handleSet) -DIM QB__leakInfo AS LONG -QB__leakInfo = QB_NODE_newDictionary -QB_NODE_assign QB__leakInfo, QB_NODE_newValueWithLabel_long("HANDLE_set_count", QB__handlesets) -QB_NODE_assign QB__leakInfo, QB_NODE_newValueWithLabel_long("STR_count", QB__strings) -QB_NODE_assign QB__leakInfo, QB_NODE_newValueWithLabel_long("NODE_count", QB__nodes) -QB_NODE_assign QB__leakInfo, QB_NODE_newValueWithLabel_long("DATETIME_count", QB__datetimes) -QB_NODE_assign QB__leakInfo, QB_NODE_newValueWithLabel_long("global_hash_table_size", (UBOUND(__QB_NODE_hashLists) + 1) * 4) -QB_FRAMEWORK_leakInfo$ = QB_NODESET_serialize(QB__leakInfo, "json") -QB_NODE_destroy QB__leakInfo -END FUNCTION - -SUB QB_NODESET_free (QB__selIn AS LONG) -IF QB__selIn < 0 THEN - QB_NODE_destroy -QB__selIn 'destroy this list/hashset of nodes -END IF -END SUB - -FUNCTION QB_NODESET_count& (QB__selIn AS LONG) -QB_NODESET_count& = QB_NODESET_count_PRESERVE&(QB__selIn) -QB_NODESET_free QB__selIn -END FUNCTION -FUNCTION QB_NODESET_count_PRESERVE& (QB__selIn AS LONG) -IF QB__selIn < 0 THEN - QB_NODESET_count_PRESERVE& = __QB_NODE(-QB__selIn).count -ELSE - IF QB__selIn <> 0 THEN - QB_NODESET_count_PRESERVE& = 1 - ELSE - QB_NODESET_count_PRESERVE& = 0 - END IF -END IF -END FUNCTION - -FUNCTION QB_NODESET_equal& (QB__selIn AS LONG, value AS STRING) -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -DIM QB__newSel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - IF __QB_NODE(QB__sel).valueFormat = QB_NODE_FORMAT_STR THEN - IF QB_STR_get(__QB_NODE(QB__sel).value) = value THEN - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - END IF - END IF - LOOP -ELSE - QB__sel = QB__selIn - IF __QB_NODE(QB__sel).valueFormat = QB_NODE_FORMAT_STR THEN - IF QB_STR_get(__QB_NODE(QB__sel).value) = value THEN - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - END IF - END IF -END IF -QB_NODESET_equal& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_label_equal& (QB__selIn AS LONG, value AS STRING) -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -DIM QB__newSel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - IF __QB_NODE(QB__sel).labelFormat = QB_NODE_FORMAT_STR THEN - IF QB_STR_get(__QB_NODE(QB__sel).label) = value THEN - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - END IF - END IF - LOOP -ELSE - QB__sel = QB__selIn - IF __QB_NODE(QB__sel).labelFormat = QB_NODE_FORMAT_STR THEN - IF QB_STR_get(__QB_NODE(QB__sel).label) = value THEN - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - END IF - END IF -END IF -QB_NODESET_label_equal& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_allChildren& (QB__selIn AS LONG) 'all decendants, all depths -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - IF __QB_NODE(QB__sel).count THEN - __QB_NODESET_addChildren QB__sel, QB__selOut - END IF - LOOP -ELSE - QB__sel = QB__selIn - IF __QB_NODE(QB__sel).count THEN - __QB_NODESET_addChildren QB__sel, QB__selOut - END IF -END IF -QB_NODESET_allChildren& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_children& (QB__selIn AS LONG) 'only 1st level decendants -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - IF __QB_NODE(QB__sel).count THEN - __QB_NODESET_addChildrenWithDepth QB__sel, QB__selOut, 1, 1, 1 - END IF - LOOP -ELSE - QB__sel = QB__selIn - IF __QB_NODE(QB__sel).count THEN - __QB_NODESET_addChildrenWithDepth QB__sel, QB__selOut, 1, 1, 1 - END IF -END IF -QB_NODESET_children& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_parent& (QB__selIn AS LONG) -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -DIM QB__newSel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - IF __QB_NODE(QB__sel).parent THEN - QB__newSel = QB_NODE_newLabel_long(__QB_NODE(QB__sel).parent) - QB_NODE_assign QB__selOut, QB__newSel - END IF - LOOP -ELSE - QB__sel = QB__selIn - IF __QB_NODE(QB__sel).parent THEN - QB__newSel = QB_NODE_newLabel_long(__QB_NODE(QB__sel).parent) - QB_NODE_assign QB__selOut, QB__newSel - END IF -END IF -QB_NODESET_parent& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_node& (QB__selIn AS LONG) -IF QB__selIn >= 0 THEN - QB_NODESET_node& = QB__selIn - 'note: not a nodeset, no need to call nodeset free - EXIT FUNCTION -END IF -DIM QB__sel AS LONG -QB__sel = __QB_NODE(-QB__selIn).firstChild -IF QB__sel <> 0 THEN - QB__sel = __QB_NODE(QB__sel).label -END IF -QB_NODESET_node& = QB__sel -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_parents& (QB__selIn AS LONG) -DIM QB__selOut AS LONG: QB__selOut = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -DIM QB__newSel AS LONG -IF QB__selIn < 0 THEN - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - QB__sel = __QB_NODE(QB__sel).parent - DO WHILE QB__sel - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - QB__sel = __QB_NODE(QB__sel).parent - LOOP - LOOP -ELSE - QB__sel = QB__selIn - QB__sel = __QB_NODE(QB__sel).parent - DO WHILE QB__sel - QB__newSel = QB_NODE_newLabel_long(QB__sel) - QB_NODE_assign QB__selOut, QB__newSel - QB__sel = __QB_NODE(QB__sel).parent - LOOP -END IF -QB_NODESET_parents& = -QB__selOut -QB_NODESET_free QB__selIn -END FUNCTION - -FUNCTION QB_NODESET_each& (QB__SelInI AS LONG, QB__selIn AS LONG, QB__selInIterator AS LONG) -DIM QB__ret AS LONG -QB__ret = QB_NODESET_each_PRESERVE(QB__SelInI, QB__selIn, QB__selInIterator) -IF QB__ret = 0 THEN QB_NODESET_free QB__selIn -QB_NODESET_each& = QB__ret -END FUNCTION -FUNCTION QB_NODESET_each_PRESERVE& (QB__SelInI AS LONG, QB__selIn AS LONG, QB__selInIterator AS LONG) -IF QB__selIn > 0 THEN - IF QB__selInIterator = 0 THEN - QB_NODESET_each_PRESERVE& = -1 - QB__SelInI = QB__selIn - ELSE - QB__selInIterator = 1 - QB_NODESET_each_PRESERVE& = 0 - QB__SelInI = 0 - END IF -ELSE - DIM QB__ret AS LONG - QB_NODESET_each_PRESERVE = QB_NODE_each(QB__SelInI, -QB__selIn, QB__selInIterator) - IF QB__SelInI <> 0 THEN QB__SelInI = __QB_NODE(QB__SelInI).label -END IF -END FUNCTION - -FUNCTION QB_NODESET_deserialize& (json AS STRING, format AS STRING) 'only "json" is supported -'prepass to make deserializing by scanning (INSTR) for : { } [ ] , work -DIM json2 AS STRING -json2 = SPACE$(LEN(json) * 6) 'the maximum size preparsed content can grow is 6x -i2 = 0 -inblock = 0 -lastA = 0 -lastLastA = 0 -FOR i1 = 1 TO LEN(json) - a = ASC(json, i1) - IF inblock THEN - IF a = 58 OR a = 123 OR a = 125 OR a = 91 OR a = 93 OR a = 44 THEN 'escape... : { } [ ] , - IF a = 58 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u003A" - IF a = 123 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u007B" - IF a = 125 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u007D" - IF a = 91 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u005B" - IF a = 93 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u005D" - IF a = 44 THEN i2 = i2 + 6: MID$(json2, i2 - 5, 6) = "\u002C" - ELSE - i2 = i2 + 1: ASC(json2, i2) = a - END IF - IF a = inblock AND ((lastA <> 92) OR (lastA = 92 AND lastLastA = 92)) THEN inblock = 0 'note: we allow \' - ELSE - IF a = 34 THEN inblock = 34 - IF a = 39 THEN inblock = 39 - i2 = i2 + 1: ASC(json2, i2) = a - END IF - lastLastA = lastA - lastA = a -NEXT -json2 = LEFT$(json2, i2) -json2 = LTRIM$(RTRIM$(json2)) -DIM QB__index AS LONG -QB__index = 1 -QB_NODESET_deserialize& = __QB_JSON_deserialize(json2, QB__index, 0) -END FUNCTION - -FUNCTION QB_NODESET_serialize$ (QB__selIn AS LONG, format AS STRING) 'only "json" is supported -QB_NODESET_serialize$ = QB_NODESET_serialize_PRESERVE$(QB__selIn, format) -QB_NODESET_free QB__selIn -END FUNCTION -FUNCTION QB_NODESET_serialize_PRESERVE$ (QB__selIn AS LONG, format AS STRING) 'only "json" is supported -DIM QB__ret AS STRING -DIM QB__SelInI AS LONG: DIM QB__SelInIterator AS LONG -DIM QB__sel AS LONG -IF QB__selIn < 0 THEN - DIM QB__n AS LONG - DO WHILE QB_NODE_each(QB__SelInI, -QB__selIn, QB__SelInIterator) - QB__sel = __QB_NODE(QB__SelInI).label - QB__n = QB__n + 1 - __QB_JSON_serialize QB__ret, QB__sel, 0 - IF __QB_NODE(-QB__selIn).count <> QB__n THEN QB__ret = QB__ret + "," - LOOP -ELSE - QB__sel = QB__selIn - __QB_JSON_serialize QB__ret, QB__sel, 0 -END IF -QB_NODESET_serialize_PRESERVE$ = QB__ret -END FUNCTION - -'######################################## - -'#################### DATETIME: Methods #################### -FUNCTION QB_DATETIME_new (dateTimeType AS LONG) -DIM QB__handle AS LONG -QB__handle = QB_HANDLE_new(__QB_DATETIME_handleSet) -IF QB__handle > __QB_DATETIME_ubound THEN - __QB_DATETIME_ubound = QB__handle * 2 - REDIM _PRESERVE __QB_DATETIME(__QB_DATETIME_ubound) AS QB_DATETIME -END IF -__QB_DATETIME(QB__handle) = __QB_DATETIME_TYPE_EMPTY -__QB_DATETIME(QB__handle).reserved = 1 -__QB_DATETIME(QB__handle).type = dateTimeType -QB_DATETIME_new& = QB__handle -END FUNCTION - -SUB QB_DATETIME_get (QB__handle AS LONG, dateTimeToPopulate AS QB_DATETIME) -dateTimeToPopulate = __QB_DATETIME(QB__handle) -END SUB - -SUB QB_DATETIME_set (QB__handle AS LONG, dateTimeToPopulate AS QB_DATETIME) -__QB_DATETIME(QB__handle) = dateTimeToPopulate -END SUB - -SUB QB_DATETIME_free (QB__handle AS LONG) -IF QB__handle > __QB_DATETIME_ubound OR QB__handle <= 0 THEN ERROR 258: EXIT SUB 'invalid handle -IF __QB_DATETIME(QB__handle).reserved = 0 THEN ERROR 258: EXIT SUB -__QB_DATETIME(QB__handle).reserved = 0 -QB_HANDLE_free QB__handle, __QB_DATETIME_handleSet -END SUB - -FUNCTION QB_DATETIME_now -DIM QB__handle AS LONG -QB__handle = QB_DATETIME_new(QB_DATETIME_TYPE_LOCAL) -DIM QB__date AS STRING -QB__date = DATE$ 'mm-dd-yyyy -DIM QB__time AS STRING -QB__time = TIME$ 'hh:mm:ss -DIM QB__timer AS DOUBLE -QB__timer = TIMER(0.001) -__QB_DATETIME(QB__handle).months = VAL(MID$(QB__date, 1, 2)) -__QB_DATETIME(QB__handle).days = VAL(MID$(QB__date, 4, 2)) -__QB_DATETIME(QB__handle).years = VAL(MID$(QB__date, 7, 4)) -__QB_DATETIME(QB__handle).hours = VAL(MID$(QB__time, 1, 2)) -__QB_DATETIME(QB__handle).minutes = VAL(MID$(QB__time, 4, 2)) -__QB_DATETIME(QB__handle).seconds = VAL(MID$(QB__time, 7, 2)) -DIM QB__msStr AS STRING -DIM QB__ms AS LONG -QB__msStr = LTRIM$(STR$(QB__timer - INT(QB__timer))) -IF LEN(QB__msStr) > 4 THEN QB__msStr = LEFT$(QB__msStr, 4) -QB__ms = VAL(QB__msStr) * 1000 -IF QB__ms >= 1000 THEN QB__ms = 0 -__QB_DATETIME(QB__handle).milliseconds = QB__ms -QB_DATETIME_now& = QB__handle -END FUNCTION - -FUNCTION QB_DATETIME_format$ (QB__handle AS LONG, format AS STRING) -'Example: -' PRINT QB_DATETIME_format(myDateHandle, "D/M/YYYY H:mm:ss {AM}") 'could print "31/3/2012 5:02:05 PM" -' -'YYYY - 4 digit year -'YY - 2 digit year -'MM - 2 digit month -'M - 1 or 2 digit month -'DD - 2 digit day -'D - 1 or 2 digit day -'{TH},{Th},{th} -'{JAN},{jan},{Jan} -'{JANUARY},{january},{January} -'{MONDAY},{Monday},{monday} -'hh - 2 digit hour (24 hour time) -'HH - 2 digit hour (12 hour time) -'h - 1 or 2 digit hour (24 hour time) -'H - 1 or 2 digit hour (12 hour time) -'mm - 2 digit minutes -'m - 1 or 2 digit minutes -'ss - 2 digit seconds -'s - 1 or 2 digit seconds -'zzz - 3 digit milliseconds -'z - 1, 2 or 3 digit milliseconds -'{AM},{am} -DIM QB__out AS STRING -QB__out = "" -DIM QB__i AS LONG -DIM QB__fi AS LONG -DIM QB__s AS STRING -DIM QB__i1 AS LONG - -DIM QB__minDigits AS LONG -DIM QB__value AS STRING - -DIM QB__rhs AS STRING - -DIM QB__n AS LONG -DIM QB__x AS LONG - -DIM QB__smartCase AS LONG - -FOR QB__fi = 1 TO LEN(format) - - FOR QB__i = 1 TO 100 - - QB__minDigits = -1 'N/A - QB__smartCase = 0 'match case exactly - - QB__s = "" - - QB__n = 0 - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{am}" - QB__smartCase = 1 - IF __QB_DATETIME(QB__handle).hours > 11 THEN QB__value = "pm" ELSE QB__value = "am" - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{th}" - QB__smartCase = 1 - QB__value = "th" - IF __QB_DATETIME(QB__handle).days MOD 10 = 1 THEN QB__value = "st" - IF __QB_DATETIME(QB__handle).days MOD 10 = 2 THEN QB__value = "nd" - IF __QB_DATETIME(QB__handle).days MOD 10 = 3 THEN QB__value = "rd" - IF __QB_DATETIME(QB__handle).days > 10 AND __QB_DATETIME(QB__handle).days < 14 THEN QB__value = "th" - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{monday}" - QB__smartCase = 1 - DIM QB__month AS LONG - DIM QB__year AS LONG - DIM QB__day AS LONG - DIM QB__newYear AS STRING - DIM QB__century AS LONG - DIM QB__dmy AS LONG - 'http://brisray.com/qbasic/qdate.htm - QB__day = __QB_DATETIME(QB__handle).days - QB__month = __QB_DATETIME(QB__handle).months - QB__year = __QB_DATETIME(QB__handle).years - IF QB__month < 3 THEN - QB__month = QB__month + 12 - QB__year = QB__year - 1 - END IF - '*** Add 1 to the month and multiply by 2.61 - '*** Drop the fraction (not round) afterwards - QB__month = QB__month + 1 - QB__month = FIX(QB__month * 2.61) - '*** Add Day, Month and the last two digits of the year - QB__newYear = LTRIM$(STR$(QB__year)) - QB__year = VAL(RIGHT$(QB__newYear, 2)) - QB__dmy = QB__day + QB__month + QB__year - QB__century = VAL(LEFT$(QB__newYear, 2)) - '*** Add a quarter of the last two digits of the year - '*** (truncated not rounded) - QB__year = FIX(QB__year / 4) - QB__dmy = QB__dmy + QB__year - '*** Add the following factors for the year - IF QB__century = 18 THEN QB__century = 2 - IF QB__century = 19 THEN QB__century = 0 - IF QB__century = 20 THEN QB__century = 6 - IF QB__century = 21 THEN QB__century = 4 - QB__dmy = QB__dmy + QB__century - '*** The day of the week is the modulus of DMY divided by 7 - QB__dmy = QB__dmy MOD 7 - IF QB__dmy = 0 THEN QB__value = "sunday" - IF QB__dmy = 1 THEN QB__value = "monday" - IF QB__dmy = 2 THEN QB__value = "tuesday" - IF QB__dmy = 3 THEN QB__value = "wednesday" - IF QB__dmy = 4 THEN QB__value = "thursday" - IF QB__dmy = 5 THEN QB__value = "friday" - IF QB__dmy = 6 THEN QB__value = "saturday" - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{mon}" - QB__smartCase = 1 - 'http://brisray.com/qbasic/qdate.htm - QB__day = __QB_DATETIME(QB__handle).days - QB__month = __QB_DATETIME(QB__handle).months - QB__year = __QB_DATETIME(QB__handle).years - IF QB__month < 3 THEN - QB__month = QB__month + 12 - QB__year = QB__year - 1 - END IF - '*** Add 1 to the month and multiply by 2.61 - '*** Drop the fraction (not round) afterwards - QB__month = QB__month + 1 - QB__month = FIX(QB__month * 2.61) - '*** Add Day, Month and the last two digits of the year - QB__newYear = LTRIM$(STR$(QB__year)) - QB__year = VAL(RIGHT$(QB__newYear, 2)) - QB__dmy = QB__day + QB__month + QB__year - QB__century = VAL(LEFT$(QB__newYear, 2)) - '*** Add a quarter of the last two digits of the year - '*** (truncated not rounded) - QB__year = FIX(QB__year / 4) - QB__dmy = QB__dmy + QB__year - '*** Add the following factors for the year - IF QB__century = 18 THEN QB__century = 2 - IF QB__century = 19 THEN QB__century = 0 - IF QB__century = 20 THEN QB__century = 6 - IF QB__century = 21 THEN QB__century = 4 - QB__dmy = QB__dmy + QB__century - '*** The day of the week is the modulus of DMY divided by 7 - QB__dmy = QB__dmy MOD 7 - IF QB__dmy = 0 THEN QB__value = "sun" - IF QB__dmy = 1 THEN QB__value = "mon" - IF QB__dmy = 2 THEN QB__value = "tue" - IF QB__dmy = 3 THEN QB__value = "wed" - IF QB__dmy = 4 THEN QB__value = "thu" - IF QB__dmy = 5 THEN QB__value = "fri" - IF QB__dmy = 6 THEN QB__value = "sat" - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{jan}" - QB__smartCase = 1 - IF __QB_DATETIME(QB__handle).months = 1 THEN QB__value = "jan" - IF __QB_DATETIME(QB__handle).months = 2 THEN QB__value = "feb" - IF __QB_DATETIME(QB__handle).months = 3 THEN QB__value = "mar" - IF __QB_DATETIME(QB__handle).months = 4 THEN QB__value = "apr" - IF __QB_DATETIME(QB__handle).months = 5 THEN QB__value = "may" - IF __QB_DATETIME(QB__handle).months = 6 THEN QB__value = "jun" - IF __QB_DATETIME(QB__handle).months = 7 THEN QB__value = "jul" - IF __QB_DATETIME(QB__handle).months = 8 THEN QB__value = "aug" - IF __QB_DATETIME(QB__handle).months = 9 THEN QB__value = "sep" - IF __QB_DATETIME(QB__handle).months = 10 THEN QB__value = "oct" - IF __QB_DATETIME(QB__handle).months = 11 THEN QB__value = "nov" - IF __QB_DATETIME(QB__handle).months = 12 THEN QB__value = "dec" - END IF - - - - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "{january}" - QB__smartCase = 1 - IF __QB_DATETIME(QB__handle).months = 1 THEN QB__value = "january" - IF __QB_DATETIME(QB__handle).months = 2 THEN QB__value = "february" - IF __QB_DATETIME(QB__handle).months = 3 THEN QB__value = "march" - IF __QB_DATETIME(QB__handle).months = 4 THEN QB__value = "april" - IF __QB_DATETIME(QB__handle).months = 5 THEN QB__value = "may" - IF __QB_DATETIME(QB__handle).months = 6 THEN QB__value = "june" - IF __QB_DATETIME(QB__handle).months = 7 THEN QB__value = "july" - IF __QB_DATETIME(QB__handle).months = 8 THEN QB__value = "august" - IF __QB_DATETIME(QB__handle).months = 9 THEN QB__value = "september" - IF __QB_DATETIME(QB__handle).months = 10 THEN QB__value = "october" - IF __QB_DATETIME(QB__handle).months = 11 THEN QB__value = "november" - IF __QB_DATETIME(QB__handle).months = 12 THEN QB__value = "december" - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "YYYY": QB__minDigits = 4: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).years) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "YY": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).years MOD 100) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "MM": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).months) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "M": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).months) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "DD": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).days) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "D": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).days) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "hh": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).hours) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "h": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).hours) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "HH": QB__minDigits = 2: - QB__x = __QB_DATETIME(QB__handle).hours - IF QB__x > 12 THEN QB__x = QB__x - 12 - IF QB__x = 0 THEN QB__x = 12 - QB__value = QB_STR_long(QB__x) - END IF - QB__n = QB__n + 1: IF QB__i = QB__n THEN - QB__s = "H": QB__minDigits = 1 - QB__x = __QB_DATETIME(QB__handle).hours - IF QB__x > 12 THEN QB__x = QB__x - 12 - IF QB__x = 0 THEN QB__x = 12 - QB__value = QB_STR_long(QB__x) - END IF - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "mm": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).minutes) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "m": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).minutes) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "ss": QB__minDigits = 2: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).seconds) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "s": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).seconds) - - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "zzz": QB__minDigits = 3: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).milliseconds) - QB__n = QB__n + 1: IF QB__i = QB__n THEN QB__s = "z": QB__minDigits = 1: QB__value = QB_STR_long(__QB_DATETIME(QB__handle).milliseconds) - - - IF QB__s <> "" THEN - - IF QB__smartCase THEN - QB__rhs = LCASE$(RIGHT$(format, LEN(format) - QB__fi + 1)) + " " - ELSE - QB__rhs = RIGHT$(format, LEN(format) - QB__fi + 1) + " " - END IF - - IF LEFT$(QB__rhs, LEN(QB__s)) = QB__s THEN - IF QB__minDigits <> -1 THEN - IF LEN(QB__value) < QB__minDigits THEN - QB__value = STRING$(QB__minDigits - LEN(QB__value), "0") + QB__value - END IF - END IF - IF QB__smartCase THEN - QB__rhs = RIGHT$(format, LEN(format) - QB__fi + 1) + " " - QB__value = __QB_DATETIME_format_smartCase$(QB__rhs, QB__value) - END IF - - QB__out = QB__out + QB__value - QB__fi = QB__fi + LEN(QB__s) - 1 - EXIT FOR - END IF - END IF - NEXT - IF QB__i = 101 THEN QB__out = QB__out + MID$(format, QB__fi, 1) -NEXT -QB_DATETIME_format$ = QB__out -END FUNCTION - -'######################################## - - -'#################### STRING: Methods #################### - -FUNCTION QB_STR_empty& -DIM QB__handle AS LONG -QB__handle = QB_HANDLE_new(__QB_STR_handleSet) -IF QB__handle > __QB_STR_stringUbound THEN - __QB_STR_stringUbound = QB__handle * 2 - REDIM _PRESERVE __QB_STR_string(__QB_STR_stringUbound) AS STRING - REDIM _PRESERVE __QB_STR_stringValid(__QB_STR_stringUbound) AS LONG -END IF -__QB_STR_stringValid(QB__handle) = 1 -IF LEN(__QB_STR_string(QB__handle)) <> 0 THEN __QB_STR_string(QB__handle) = "" -QB_STR_empty& = QB__handle -END FUNCTION - -FUNCTION QB_STR_new& (Value AS STRING) -DIM QB__handle AS LONG -QB__handle = QB_HANDLE_new(__QB_STR_handleSet) -IF QB__handle > __QB_STR_stringUbound THEN - __QB_STR_stringUbound = QB__handle * 2 - REDIM _PRESERVE __QB_STR_string(__QB_STR_stringUbound) AS STRING - REDIM _PRESERVE __QB_STR_stringValid(__QB_STR_stringUbound) AS LONG -END IF -__QB_STR_stringValid(QB__handle) = 1 -__QB_STR_string(QB__handle) = Value -QB_STR_new& = QB__handle -END FUNCTION - -FUNCTION QB_STR_get$ (handle AS LONG) -IF handle > __QB_STR_stringUbound OR handle <= 0 THEN - $CHECKING:OFF - ERROR 258 'invalid handle - EXIT SUB - $CHECKING:ON -END IF -IF __QB_STR_stringValid(handle) = 0 THEN - $CHECKING:OFF - ERROR 258 'invalid handle - EXIT SUB - $CHECKING:ON -END IF -QB_STR_get$ = __QB_STR_string(handle) -END FUNCTION - -SUB QB_STR_set (handle AS LONG, value AS STRING) -IF handle > __QB_STR_stringUbound OR handle <= 0 THEN ERROR 258: EXIT SUB 'invalid handle -IF __QB_STR_stringValid(handle) = 0 THEN ERROR 258: EXIT SUB -__QB_STR_string(handle) = value -END SUB - -SUB QB_STR_free (handle AS LONG) -IF handle > __QB_STR_stringUbound OR handle <= 0 THEN ERROR 258: EXIT SUB 'invalid handle -IF __QB_STR_stringValid(handle) = 0 THEN ERROR 258: EXIT SUB -__QB_STR_stringValid(handle) = 0 -QB_HANDLE_free handle, __QB_STR_handleSet -END SUB - -FUNCTION QB_STR_long$ (value AS LONG) 'returns a string representation of a long value -QB_STR_long$ = LTRIM$(STR$(value)) -END FUNCTION - -'################################################## - - -'#################### HANDLE: Methods #################### - -FUNCTION QB_HANDLE_newSet& -DIM QB__context AS LONG -QB__context = QB_HANDLE_new(1) -IF UBOUND(__QB_HANDLE_handler) < QB__context THEN - REDIM _PRESERVE __QB_HANDLE_handler(QB__context * 2) AS __QB_HANDLE_HANDLER -END IF -__QB_HANDLE_handler(QB__context).lastFreedListIndex = 0 -__QB_HANDLE_handler(QB__context).lastHandle = 0 -__QB_HANDLE_handler(QB__context).count = 0 -QB_HANDLE_newSet& = QB__context -END FUNCTION - -SUB QB_HANDLE_freeSet (context AS LONG) -QB_HANDLE_free context, 1 -END SUB - -FUNCTION QB_HANDLE_count& (context AS LONG) -QB_HANDLE_count& = __QB_HANDLE_handler(context).count -END FUNCTION - -FUNCTION QB_HANDLE_new& (context AS LONG) -__QB_HANDLE_handler(context).count = __QB_HANDLE_handler(context).count + 1 -DIM QB__handle AS LONG -IF __QB_HANDLE_handler(context).lastFreedListIndex = 0 THEN - QB__handle = __QB_HANDLE_handler(context).lastHandle + 1 - __QB_HANDLE_handler(context).lastHandle = QB__handle - QB_HANDLE_new& = QB__handle - EXIT FUNCTION -END IF -DIM __QB_HANDLE_lastIndex AS LONG -__QB_HANDLE_lastIndex = __QB_HANDLE_handler(context).lastFreedListIndex -QB__handle = __QB_HANDLE_freedList(__QB_HANDLE_lastIndex).handle -__QB_HANDLE_handler(context).lastFreedListIndex = __QB_HANDLE_freedList(__QB_HANDLE_lastIndex).prevFreedListIndex -'add to freed-freed list so the freed structure can be reused -IF __QB_HANDLE_freedFreedList_Next > __QB_HANDLE_freedFreedList_Last THEN - __QB_HANDLE_freedFreedList_Last = __QB_HANDLE_freedFreedList_Next * 2 - REDIM _PRESERVE __QB_HANDLE_freedFreedList(__QB_HANDLE_freedFreedList_Last) AS LONG -END IF -__QB_HANDLE_freedFreedList(__QB_HANDLE_freedFreedList_Next) = __QB_HANDLE_lastIndex -__QB_HANDLE_freedFreedList_Next = __QB_HANDLE_freedFreedList_Next + 1 -QB_HANDLE_new& = QB__handle -END FUNCTION - -SUB QB_HANDLE_free (handle AS LONG, context AS LONG) 'MUST pass a valid handle -__QB_HANDLE_handler(context).count = __QB_HANDLE_handler(context).count - 1 -'add handle to freed list -DIM QB__index AS LONG -IF __QB_HANDLE_freedFreedList_Next > 1 THEN 'recover from freed-freed list? - __QB_HANDLE_freedFreedList_Next = __QB_HANDLE_freedFreedList_Next - 1 - QB__index = __QB_HANDLE_freedFreedList(__QB_HANDLE_freedFreedList_Next) -ELSE - IF __QB_HANDLE_freedList_Next > __QB_HANDLE_freedList_Last THEN - __QB_HANDLE_freedList_Last = __QB_HANDLE_freedList_Next * 2 - REDIM _PRESERVE __QB_HANDLE_freedList(__QB_HANDLE_freedList_Last) AS __QB_HANDLE_FREEDLIST - END IF - QB__index = __QB_HANDLE_freedList_Next - __QB_HANDLE_freedList_Next = __QB_HANDLE_freedList_Next + 1 -END IF -__QB_HANDLE_freedList(QB__index).prevFreedListIndex = __QB_HANDLE_handler(context).lastFreedListIndex -__QB_HANDLE_freedList(QB__index).handle = handle -__QB_HANDLE_handler(context).lastFreedListIndex = QB__index -END SUB - -'################################################## - - -'#################### EACH: Methods #################### - -FUNCTION QB_EACH_str_in_str& (value AS STRING, parent AS STRING, separator AS STRING, flags AS LONG, i AS LONG) -'requirements: -' iterator must be a LONG, initially set to 0 -'notes: -' refer to constants for available flags (0 is default) -DIM QB__byteValue AS LONG -DIM QB__parentLen AS LONG -DIM QB__sepValue AS LONG -DIM QB__i1 AS LONG -DIM QB__retry AS LONG -QB__sepValue = ASC(separator) -QB__parentLen = LEN(parent) -DO - i = i + 1 - IF i > QB__parentLen THEN - value = "" - IF i = QB__parentLen + 1 THEN - IF QB__parentLen <> 0 THEN - IF ASC(parent, i - 1) = QB__sepValue THEN - IF (flags AND (QB_EACH_ALLOW_BLANK OR QB_EACH_ALLOW_ALL_BLANK)) <> 0 THEN QB_EACH_str_in_str& = -1 - END IF - ELSE - IF (flags AND QB_EACH_ALLOW_ALL_BLANK) <> 0 THEN QB_EACH_str_in_str& = -1 - END IF - END IF - EXIT FUNCTION - END IF - QB__i1 = i - byteValue = ASC(parent, i) - $CHECKING:OFF - DO WHILE byteValue <> QB__sepValue - i = i + 1 - IF i > QB__parentLen THEN EXIT DO - byteValue = ASC(parent, i) - LOOP - $CHECKING:ON - value = MID$(parent, QB__i1, i - QB__i1) - IF LEN(value) = 0 AND (flags AND (QB_EACH_ALLOW_BLANK OR QB_EACH_ALLOW_ALL_BLANK)) = 0 THEN - QB__retry = 1 - ELSE - QB__retry = 0 - END IF -LOOP WHILE QB__retry -QB_EACH_str_in_str& = -1 -END FUNCTION - -FUNCTION QB_EACH_long_in_str& (value AS LONG, parent AS STRING, separator AS STRING, i AS LONG) -'requirements: -' a comma separated list of valid LONG values -' no whitespace -' no leading, trailing or adjacent commas -' iterator must be a LONG -' value must be a LONG -DIM QB__byteValue AS LONG -DIM QB__parentLen AS LONG -DIM QB__negate AS LONG -DIM QB__sepValue AS LONG -QB__sepValue = ASC(separator) -QB__parentLen = LEN(parent) -value = 0 'reset value (avoids undefined results) -i = i + 1 -IF i > QB__parentLen THEN EXIT FUNCTION -QB__byteValue = ASC(parent, i) -IF QB__byteValue = 45 THEN - QB__negate = 1 - i = i + 1 - QB__byteValue = ASC(parent, i) -END IF -DO WHILE QB__byteValue <> QB__sepValue - value = value * 10 + QB__byteValue - 48 - i = i + 1 - IF i > QB__parentLen THEN EXIT DO - QB__byteValue = ASC(parent, i) -LOOP -IF QB__negate THEN value = -value -QB_EACH_long_in_str& = -1 -END FUNCTION - -'################################################## - - -'#################### Key Value Pair Dictionary Look-Ups: Methods #################### - - - -FUNCTION QB_NODE_newValueWithLabel& (label AS STRING, value AS STRING) 'assume str_str -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).label = QB_STR_new(label) -__QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).value = QB_STR_new(value) -QB_NODE_newValueWithLabel& = QB__handle -END FUNCTION - - -FUNCTION QB_NODE_newValueWithLabel_long& (label AS STRING, value AS LONG) 'assume str_long -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).label = QB_STR_new(label) -__QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_LONG -__QB_NODE(QB__handle).value = value -QB_NODE_newValueWithLabel_long& = QB__handle -END FUNCTION - -FUNCTION QB_NODE_newValueWithLabel_bool& (label AS STRING, value AS LONG) 'assume str_bool -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).label = QB_STR_new(label) -__QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_BOOL -IF value = 0 THEN - __QB_NODE(QB__handle).value = QB_FALSE -ELSE - __QB_NODE(QB__handle).value = QB_TRUE -END IF -QB_NODE_newValueWithLabel_bool& = QB__handle -END FUNCTION - -FUNCTION QB_NODE_newLabel& (label AS STRING) 'assume str -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).label = QB_STR_new(label) -QB_NODE_newLabel& = QB__handle -END FUNCTION - -FUNCTION QB_NODE_newValue& (value AS STRING) 'assume str -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_STR -__QB_NODE(QB__handle).value = QB_STR_new(value) -QB_NODE_newValue& = QB__handle -END FUNCTION - -FUNCTION QB_NODE_newLabel_long& (label AS LONG) -DIM QB__handle AS LONG -QB__handle = __QB_NODE_new&(QB_NODE_TYPE_VALUE) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_LONG -__QB_NODE(QB__handle).label = label -QB_NODE_newLabel_long& = QB__handle -END FUNCTION - -FUNCTION QB_NODE_typeName$ (nodeType AS LONG) -IF nodeType = 1 THEN QB_NODE_typeName$ = "HASHSET" -IF nodeType = 2 THEN QB_NODE_typeName$ = "LIST" -IF nodeType = 4 THEN QB_NODE_typeName$ = "DICTIONARY" -IF nodeType = 8 THEN QB_NODE_typeName$ = "VALUE" -END FUNCTION - -FUNCTION QB_NODE_new& (nodeType AS LONG, flags AS LONG) -IF QB_DEBUG_VERBOSE THEN PRINT "QB_NODE_new()" -DIM QB__handle AS LONG -QB__handle = QB_HANDLE_new(__QB_NODE_handleSet) -IF QB__handle > __QB_NODE_ubound THEN - __QB_NODE_ubound = QB__handle * 2 - REDIM _PRESERVE __QB_NODE(__QB_NODE_ubound) AS QB_NODE_TYPE -END IF -__QB_NODE(QB__handle) = QB_NODE_TYPE_EMPTY -__QB_NODE(QB__handle).valid = 1 -__QB_NODE(QB__handle).type = nodeType -__QB_NODE(QB__handle).flags = flags -IF nodeType AND (QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_DICTIONARY) THEN - __QB_NODE(QB__handle).hashOffset = INT(RND * 16777215) -END IF -IF QB_DEBUG THEN PRINT "Created node type"; nodeType -QB_NODE_new& = QB__handle -END FUNCTION - - -FUNCTION QB_NODE_newDictionary& -QB_NODE_newDictionary& = QB_NODE_new(QB_NODE_TYPE_DICTIONARY, 0) -END FUNCTION - -FUNCTION QB_NODE_newList& -QB_NODE_newList& = QB_NODE_new(QB_NODE_TYPE_LIST, 0) -END FUNCTION - -FUNCTION QB_NODE_newHashSet& -QB_NODE_newHashSet& = QB_NODE_new(QB_NODE_TYPE_HASHSET, 0) -END FUNCTION - -SUB QB_NODE_setValue_format (QB__handle AS LONG, value AS LONG, format AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'format-specific validation here -__QB_NODE(QB__handle).value = value -__QB_NODE(QB__handle).valueFormat = format -END SUB - -SUB QB_NODE_setLabel_format (QB__handle AS LONG, label AS LONG, format AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE + QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_LIST + QB_NODE_TYPE_DICTIONARY) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'format-specific validation here -__QB_NODE(QB__handle).label = label -__QB_NODE(QB__handle).labelFormat = format -END SUB - -SUB QB_NODE_setValue (QB__handle AS LONG, value AS STRING) 'assume str -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE) = -1 THEN EXIT FUNCTION -$CHECKING:ON -__QB_NODE(QB__handle).value = QB_STR_new(value) -__QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_STR -END SUB - -SUB QB_NODE_setLabel (QB__handle AS LONG, label AS STRING) 'assume str -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE + QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_LIST + QB_NODE_TYPE_DICTIONARY) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'TODO: If parent is a dictionary/hashset detach then reattach -__QB_NODE(QB__handle).label = QB_STR_new(label) -__QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR -END SUB - -FUNCTION QB_NODE_value$ (QB__handle AS LONG) 'assume str -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'format-specific validation here -IF __QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_STR THEN - QB_NODE_value$ = QB_STR_get(__QB_NODE(QB__handle).value) - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_LONG THEN - QB_NODE_value$ = QB_STR_long(__QB_NODE(QB__handle).value) - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_NULL THEN - QB_NODE_value$ = "null" - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_BOOL THEN - IF __QB_NODE(QB__handle).value <> 0 THEN - QB_NODE_value$ = "true" - ELSE - QB_NODE_value$ = "false" - END IF - EXIT FUNCTION -END IF -QB_NODE_value$ = "undefined" -END SUB - -FUNCTION QB_NODE_label$ (QB__handle AS LONG) 'assume str -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_VALUE) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'format-specific validation here -IF __QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR THEN - QB_NODE_label$ = QB_STR_get(__QB_NODE(QB__handle).label) - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_LONG THEN - QB_NODE_label$ = QB_STR_long(__QB_NODE(QB__handle).label) - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_NULL THEN - QB_NODE_label$ = "null" - EXIT FUNCTION -END IF -IF __QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_BOOL THEN - IF __QB_NODE(QB__handle).label <> 0 THEN - QB_NODE_label$ = "true" - ELSE - QB_NODE_label$ = "false" - END IF - EXIT FUNCTION -END IF -QB_NODE_label$ = "undefined" -END SUB - -FUNCTION QB_NODE_count& (QB__handle AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_LIST) = -1 THEN EXIT FUNCTION -$CHECKING:ON -QB_NODE_count& = __QB_NODE(QB__handle).count -END FUNCTION - -FUNCTION QB_NODE_each& (child AS LONG, parent AS LONG, i AS LONG) -$CHECKING:OFF -IF i = 0 THEN - IF __QB_NODE_validateHandle(parent, QB_NODE_TYPE_LIST + QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_DICTIONARY) = -1 THEN EXIT FUNCTION -END IF -$CHECKING:ON -'i is either 0(on first call), -1(end of set reached) or the NEXT node -IF i = -1 THEN - child = 0 - EXIT FUNCTION -END IF -IF i = 0 THEN - child = __QB_NODE(parent).firstChild -ELSE - child = i -END IF -IF child = 0 THEN 'node does not exist - i = -1 - EXIT FUNCTION -END IF -i = __QB_NODE(child).next -IF i = 0 THEN - i = -1 -END IF -QB_NODE_each& = -1 -END FUNCTION - -FUNCTION QB_NODE_eachWithLabel_format& (child AS LONG, parent AS LONG, label AS LONG, labelFormat AS LONG, i AS LONG) -$CHECKING:OFF -IF i = 0 THEN - IF __QB_NODE_validateHandle(parent, QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) = -1 THEN EXIT FUNCTION -END IF -$CHECKING:ON -IF __QB_NODE(parent).type AND (QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) THEN - 'i is either 0(on first call), -1(end of set reached) or the NEXT node - IF i = -1 THEN - child = 0 - EXIT FUNCTION - END IF - DIM QB__label AS STRING - IF i = 0 THEN - DIM QB__hashValue AS LONG - IF labelFormat = QB_NODE_FORMAT_LONG THEN - QB__hashValue = __QB_NODE_hashLong(label, __QB_NODE(parent).hashOffset) - ELSE - IF labelFormat = QB_NODE_FORMAT_STR THEN - QB__label = QB_STR_get(label) - IF (__QB_NODE(parent).flags AND QB_NODE_CASE_SENSITIVE) = 0 THEN - QB__label = LCASE$(QB__label) - END IF - QB__hashValue = __QB_NODE_hashStr(QB__label, __QB_NODE(parent).hashOffset) - END IF - END IF - DIM QB__hashList AS LONG - QB__hashList = __QB_NODE_hashLists(QB__hashValue) - IF QB__hashList = 0 THEN - 'no hash list exists - i = -1 - EXIT FUNCTION - END IF - i = __QB_NODE(QB__hashList).firstChild - ELSE - IF labelFormat = QB_NODE_FORMAT_STR THEN - QB__label = QB_STR_get(label) - IF (__QB_NODE(parent).flags AND QB_NODE_CASE_SENSITIVE) = 0 THEN - QB__label = LCASE$(QB__label) - END IF - END IF - END IF - DO - IF i = 0 THEN - i = -1 - EXIT FUNCTION - END IF - 'check if current node matches label - IF __QB_NODE(i).owner = parent THEN 'same owner - IF __QB_NODE(i).labelFormat = labelFormat THEN 'same label format - DIM QB__same AS LONG - QB__same = 0 - IF labelFormat = QB_NODE_FORMAT_LONG THEN - IF __QB_NODE(i).label = label THEN QB__same = 1 - ELSE - IF QB_STR_get(__QB_NODE(i).label) = QB__label THEN QB__same = 1 - END IF - IF QB__same THEN 'same label - child = __QB_NODE(i).value - i = __QB_NODE(i).next - IF i = 0 THEN - i = -1 - END IF - QB_NODE_eachWithLabel_format& = -1 - EXIT FUNCTION - END IF - END IF - END IF - i = __QB_NODE(i).next - LOOP -END IF 'DICTIONARY -END FUNCTION - -FUNCTION QB_NODE_withLabel_format& (parent AS LONG, label AS LONG, labelFormat AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(parent, QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) = -1 THEN EXIT FUNCTION -$CHECKING:ON -IF __QB_NODE(parent).type AND (QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) THEN - DIM QB__label AS STRING - DIM QB__hashValue AS LONG - IF labelFormat = QB_NODE_FORMAT_LONG THEN - QB__hashValue = __QB_NODE_hashLong(label, __QB_NODE(parent).hashOffset) - ELSE - IF labelFormat = QB_NODE_FORMAT_STR THEN - QB__label = QB_STR_get(label) - IF (__QB_NODE(parent).flags AND QB_NODE_CASE_SENSITIVE) = 0 THEN - QB__label = LCASE$(QB__label) - END IF - QB__hashValue = __QB_NODE_hashStr(QB__label, __QB_NODE(parent).hashOffset) - END IF - END IF - DIM QB__hashList AS LONG - QB__hashList = __QB_NODE_hashLists(QB__hashValue) - IF QB__hashList = 0 THEN EXIT FUNCTION - DIM QB__i AS LONG - QB__i = __QB_NODE(QB__hashList).firstChild - DO WHILE QB__i <> 0 - IF __QB_NODE(QB__i).owner = parent THEN 'same owner - IF __QB_NODE(QB__i).labelFormat = labelFormat THEN 'same label format - DIM QB__same AS LONG - QB__same = 0 - IF labelFormat = QB_NODE_FORMAT_LONG THEN - IF __QB_NODE(QB__i).label = label THEN QB__same = 1 - ELSE - IF QB_STR_get(__QB_NODE(QB__i).label) = QB__label THEN QB__same = 1 - END IF - IF QB__same THEN 'same label - QB_NODE_withLabel_format& = __QB_NODE(QB__i).value - EXIT FUNCTION - END IF - END IF - END IF - QB__i = __QB_NODE(QB__i).next - LOOP - EXIT FUNCTION 'not found -END IF 'DICTIONARY -END FUNCTION - -FUNCTION QB_NODE_valueOfLabel$ (parent AS LONG, label AS STRING) 'assume str-label, str-value -DIM QB__i AS LONG -QB__i = QB_NODE_withLabel&(parent, label) -IF QB__i THEN - QB_NODE_valueOfLabel$ = QB_NODE_value(QB__i) -END IF -END FUNCTION - -FUNCTION QB_NODE_valueOfLabel_long& (parent AS LONG, label AS STRING) 'assume str-label -DIM QB__i AS LONG -QB__i = QB_NODE_withLabel&(parent, label) -IF QB__i THEN - QB_NODE_valueOfLabel_long& = __QB_NODE(QB__i).value -END IF -END FUNCTION - -FUNCTION QB_NODE_valueOfLabel_bool& (parent AS LONG, label AS STRING) 'assume str-label -DIM QB__i AS LONG -QB__i = QB_NODE_withLabel&(parent, label) -IF QB__i THEN - QB_NODE_valueOfLabel_bool& = __QB_NODE(QB__i).value -END IF -END FUNCTION - -FUNCTION QB_NODE_withLabel& (parent AS LONG, label AS STRING) -$CHECKING:OFF -IF __QB_NODE_validateHandle(parent, QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) = -1 THEN EXIT FUNCTION -$CHECKING:ON -IF __QB_NODE(parent).type AND (QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) THEN - DIM QB__label AS STRING - DIM QB__hashValue AS LONG - QB__label = label - IF (__QB_NODE(parent).flags AND QB_NODE_CASE_SENSITIVE) = 0 THEN - QB__label = LCASE$(QB__label) - END IF - QB__hashValue = __QB_NODE_hashStr(QB__label, __QB_NODE(parent).hashOffset) - DIM QB__hashList AS LONG - QB__hashList = __QB_NODE_hashLists(QB__hashValue) - IF QB__hashList = 0 THEN EXIT FUNCTION - DIM QB__i AS LONG - QB__i = __QB_NODE(QB__hashList).firstChild - DO WHILE QB__i <> 0 - IF __QB_NODE(QB__i).owner = parent THEN 'same owner - IF __QB_NODE(QB__i).labelFormat = QB_NODE_FORMAT_STR THEN 'same label format - DIM QB__same AS LONG - QB__same = 0 - IF QB_STR_get(__QB_NODE(QB__i).label) = QB__label THEN QB__same = 1 - IF QB__same THEN 'same label - QB_NODE_withLabel& = __QB_NODE(QB__i).value - EXIT FUNCTION - END IF - END IF - END IF - QB__i = __QB_NODE(QB__i).next - LOOP - EXIT FUNCTION 'not found -END IF 'DICTIONARY -END FUNCTION - - -SUB QB_NODE_assign (parent AS LONG, child AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(child, QB_NODE_TYPE_VALUE + QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_LIST + QB_NODE_TYPE_DICTIONARY) = -1 THEN EXIT FUNCTION -IF __QB_NODE_validateHandle(parent, QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_LIST + QB_NODE_TYPE_DICTIONARY) = -1 THEN EXIT FUNCTION -$CHECKING:ON - -IF __QB_NODE(parent).type AND (QB_NODE_TYPE_LIST) THEN - QB_NODE_detach child - __QB_NODE_append parent, child -END IF - -IF __QB_NODE(parent).type AND (QB_NODE_TYPE_DICTIONARY + QB_NODE_TYPE_HASHSET) THEN - QB_NODE_detach child - - DIM QB__label AS STRING - DIM QB__hashValue AS LONG - - IF __QB_NODE(child).labelFormat = QB_NODE_FORMAT_LONG THEN - QB__hashValue = __QB_NODE_hashLong(__QB_NODE(child).label, __QB_NODE(parent).hashOffset) - ELSE - IF __QB_NODE(child).labelFormat = QB_NODE_FORMAT_STR THEN - QB__label = QB_STR_get(__QB_NODE(child).label) - IF (__QB_NODE(parent).flags AND QB_NODE_CASE_SENSITIVE) = 0 THEN - QB__label = LCASE$(QB__label) - END IF - QB__hashValue = __QB_NODE_hashStr(QB__label, __QB_NODE(parent).hashOffset) - END IF - END IF - DIM QB__hashList AS LONG - QB__hashList = __QB_NODE_hashLists(QB__hashValue) - DIM QB__canReplace AS LONG - QB__canReplace = 1 - IF (__QB_NODE(parent).flags AND QB_NODE_ALLOW_DUPLICATE_KEYS) <> 0 THEN - QB__canReplace = 0 - IF (__QB_NODE(parent).flags AND QB_NODE_AVOID_DUPLICATE_VALUES_PER_KEY) <> 0 THEN QB__canReplace = 1 - END IF - - DIM QB__childValue AS STRING - IF (__QB_NODE(parent).flags AND QB_NODE_AVOID_DUPLICATE_VALUES_PER_KEY) <> 0 AND __QB_NODE(child).labelFormat = QB_NODE_FORMAT_STR THEN - QB__childValue = QB_STR_get(__QB_NODE(child).value) - IF (__QB_NODE(parent).flags AND QB_NODE_DUPLICATE_VALUES_CASE_SENSITIVE) = 0 THEN QB__childValue = LCASE$(QB__childValue) - END IF - - IF QB__hashList = 0 OR QB__canReplace = 0 THEN - IF QB__hashList = 0 THEN - QB__hashList = QB_NODE_new(QB_NODE_TYPE_LIST, 0) - __QB_NODE_hashLists(QB__hashValue) = QB__hashList - __QB_NODE(QB__hashList).hashReference = QB__hashValue - END IF - ELSE - DIM QB__this AS LONG - DIM QB__i AS LONG - DO WHILE QB_NODE_each(QB__this, QB__hashList, QB__i) - IF __QB_NODE(QB__this).owner = parent THEN 'same owner - IF __QB_NODE(QB__this).labelFormat = __QB_NODE(child).labelFormat THEN 'same label format - DIM QB__same AS LONG - QB__same = 0 - IF __QB_NODE(child).labelFormat = QB_NODE_FORMAT_LONG THEN - IF __QB_NODE(QB__this).label = __QB_NODE(child).label THEN QB__same = 1 - ELSE - IF QB_STR_get(__QB_NODE(QB__this).label) = QB__label THEN QB__same = 1 - END IF - IF QB__same THEN 'same label - IF (__QB_NODE(parent).flags AND QB_NODE_ALLOW_DUPLICATE_KEYS) <> 0 THEN - IF (__QB_NODE(parent).flags AND QB_NODE_AVOID_DUPLICATE_VALUES_PER_KEY) <> 0 THEN - IF __QB_NODE(QB__this).valueFormat = __QB_NODE(child).valueFormat THEN 'same value format - IF __QB_NODE(child).labelFormat = QB_NODE_FORMAT_LONG THEN - IF __QB_NODE(child).value = __QB_NODE(QB__this).value THEN - 'optionally, destroy this child - IF __QB_NODE(parent).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - QB_NODE_destroy child - END IF - EXIT SUB 'entry already exists - END IF - ELSE - IF (__QB_NODE(parent).flags AND QB_NODE_DUPLICATE_VALUES_CASE_SENSITIVE) <> 0 THEN - IF QB_STR_get(__QB_NODE(QB__this).value) = QB__childValue THEN - 'optionally, destroy this child - IF __QB_NODE(parent).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - QB_NODE_destroy child - END IF - EXIT SUB 'entry already exists - END IF - ELSE - IF LCASE$(QB_STR_get(__QB_NODE(QB__this).value)) = QB__childValue THEN - 'optionally, destroy this child - IF __QB_NODE(parent).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - QB_NODE_destroy child - END IF - EXIT SUB 'entry already exists - END IF - END IF - END IF - END IF - END IF - ELSE - 'duplicate keys not allowed - __QB_NODE_append parent, child - 'update existing reference to child - DIM QB__oldChild AS LONG - QB__oldChild = __QB_NODE(QB__this).value - __QB_NODE_detach QB__oldChild 'generic detach must be used (reference will be re-used) - 'optionally, destroy old child - IF __QB_NODE(parent).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - QB_NODE_destroy QB__oldChild - END IF - __QB_NODE(QB__this).value = child - __QB_NODE(child).hashReference = QB__this - EXIT SUB - END IF - END IF - END IF - END IF - LOOP - END IF - 'create new reference to child - __QB_NODE_append parent, child - DIM QB__ref AS LONG - QB__ref = QB_NODE_new(QB_NODE_TYPE_VALUE, 0) - IF __QB_NODE(child).labelFormat = QB_NODE_FORMAT_LONG THEN - QB_NODE_setLabel_format QB__ref, __QB_NODE(child).label, QB_NODE_FORMAT_LONG - ELSE - QB_NODE_setLabel_format QB__ref, QB_STR_new(QB__label), QB_NODE_FORMAT_STR - END IF - QB_NODE_setValue_format QB__ref, child, QB_NODE_FORMAT_LONG - __QB_NODE(QB__ref).owner = parent 'owner allows searching elimination of conflicting hash entries from other sets - 'add reference to list - __QB_NODE_append QB__hashList, QB__ref - __QB_NODE(child).hashReference = QB__ref -END IF 'dictionary - - - - - - - - -END SUB 'assign - -SUB QB_NODE_detach (QB__handle AS LONG) -IF QB_DEBUG_VERBOSE THEN - PRINT "QB_NODE_detach: Node"; QB__handle; "of type: " + QB_NODE_typeName(__QB_NODE(QB__handle).type) -END IF -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, 0) = -1 THEN EXIT FUNCTION -$CHECKING:ON -DIM QB__parent AS LONG -DIM QB__ref AS LONG -DIM QB__ref_parent AS LONG -'dictionaries & hashsets require removal of their hash table reference link -QB__parent = __QB_NODE(QB__handle).parent -IF QB__parent THEN 'has parent - IF __QB_NODE(QB__parent).type AND (QB_NODE_TYPE_HASHSET + QB_NODE_TYPE_DICTIONARY) THEN - QB__ref = __QB_NODE(QB__handle).hashReference - QB__ref_parent = __QB_NODE(QB__ref).parent - IF __QB_NODE(QB__ref_parent).count = 1 THEN - 'last reference - IF QB_DEBUG_VERBOSE THEN - PRINT "QB_NODE_detach: Calling destroy on parent hashreference-list node"; QB__ref_parent; "of type: " + QB_NODE_typeName(__QB_NODE(QB__ref_parent).type) + " (no more entries)" - END IF - 'clear the hash entry pointing to this list - __QB_NODE_hashLists(__QB_NODE(QB__ref_parent).hashReference) = 0 'step 1 (must happen before step 2) - __QB_NODE_destroy QB__ref_parent 'step 2 - ELSE - __QB_NODE_destroy QB__ref - END IF - IF __QB_NODE(QB__parent).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - __QB_NODE_detach QB__handle 'perform generic detach - __QB_NODE_destroy QB__handle - EXIT FUNCTION - END IF - __QB_NODE_detach QB__handle 'perform generic detach - EXIT FUNCTION - END IF -END IF -__QB_NODE_detach QB__handle 'perform generic detach -END SUB - -SUB QB_NODE_destroy (QB__handle AS LONG) -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, 0) = -1 THEN EXIT FUNCTION -$CHECKING:ON -'destroy this node and all its children recursively -__QB_NODE_destroy QB__handle -END SUB - -SUB __QB_NODE_destroy (QB__handle AS LONG) - -IF QB_DEBUG_VERBOSE THEN - PRINT "__QB_NODE_destroy: Will destroy node"; QB__handle; "of type: " + QB_NODE_typeName(__QB_NODE(QB__handle).type) -END IF - -'when a collection is being destroyed, prevent QB_NODE_DESTROY_ORPHANED_CHILDNODES from firing a delete operation twice -IF __QB_NODE(QB__handle).flags AND QB_NODE_DESTROY_ORPHANED_CHILDNODES THEN - __QB_NODE(QB__handle).flags = __QB_NODE(QB__handle).flags - QB_NODE_DESTROY_ORPHANED_CHILDNODES -END IF - -'before any node can be destroyed it must be detached -QB_NODE_detach QB__handle -'destroy this node's children (if any) -DIM QB__child AS LONG -DIM QB__next AS LONG -QB__child = __QB_NODE(QB__handle).firstChild -DO WHILE QB__child - QB__next = __QB_NODE(QB__child).next - IF QB_DEBUG_VERBOSE THEN - PRINT "__QB_NODE_destroy: Calling destroy on child node"; QB__child; "of type: " + QB_NODE_typeName(__QB_NODE(QB__child).type) - END IF - __QB_NODE_destroy QB__child - QB__child = QB__next -LOOP -'destroy this object -IF QB_DEBUG_VERBOSE THEN - PRINT "__QB_NODE_destroy: Destroying node"; QB__handle; "of type: " + QB_NODE_typeName(__QB_NODE(QB__handle).type) -END IF -$CHECKING:OFF -IF __QB_NODE_validateHandle(QB__handle, 0) = -1 THEN EXIT FUNCTION -$CHECKING:ON -__QB_NODE(QB__handle).valid = 0 -'cleanup string references -IF __QB_NODE(QB__handle).valueFormat = QB_NODE_FORMAT_STR THEN - QB_STR_free __QB_NODE(QB__handle).value -END IF -IF __QB_NODE(QB__handle).labelFormat = QB_NODE_FORMAT_STR THEN - QB_STR_free __QB_NODE(QB__handle).label -END IF -QB_HANDLE_free QB__handle, __QB_NODE_handleSet -END SUB - -FUNCTION __QB_NODE_new& (nodeType AS LONG) -IF QB_DEBUG_VERBOSE THEN PRINT "__QB_NODE_new()" -DIM QB__handle AS LONG -QB__handle = QB_HANDLE_new(__QB_NODE_handleSet) -IF QB__handle > __QB_NODE_ubound THEN - __QB_NODE_ubound = QB__handle * 2 - REDIM _PRESERVE __QB_NODE(__QB_NODE_ubound) AS QB_NODE_TYPE -END IF -__QB_NODE(QB__handle) = QB_NODE_TYPE_EMPTY -__QB_NODE(QB__handle).valid = 1 -__QB_NODE(QB__handle).type = nodeType -IF QB_DEBUG_VERBOSE THEN PRINT "Created node type"; nodeType -__QB_NODE_new& = QB__handle -END FUNCTION - -SUB __QB_NODE_append (parent AS LONG, child AS LONG) -'generic append to end of parent list -'assumes child is detached -__QB_NODE(child).parent = parent -IF __QB_NODE(parent).firstChild = 0 THEN - 'is first entry in list - __QB_NODE(parent).count = 1 - __QB_NODE(parent).firstChild = child - __QB_NODE(parent).lastChild = child -ELSE - 'add to existing list - DIM QB__i AS LONG - QB__i = __QB_NODE(parent).lastChild - __QB_NODE(parent).count = __QB_NODE(parent).count + 1 - __QB_NODE(parent).lastChild = child - __QB_NODE(QB__i).next = child - __QB_NODE(child).prev = QB__i -END IF -END SUB - -FUNCTION __QB_NODE_hashLong (value AS LONG, baseOffset AS LONG) -__QB_NODE_hashLong = (value + baseOffset) AND &HFFFFFF~& -END FUNCTION - -FUNCTION __QB_NODE_hashStr (value AS STRING, baseOffset AS LONG) -DIM QB__keyNameLen AS LONG -DIM QB__i AS LONG -DIM QB__hashValue AS LONG -QB__keyNameLen = LEN(value) -QB__i = 1 -DO WHILE QB__i <= QB__keyNameLen - QB__hashValue = QB__hashValue + ASC(value, QB__i) * QB__i * 15 - QB__i = QB__i + 1 -LOOP -__QB_NODE_hashStr = (QB__hashValue + baseOffset) AND &HFFFFFF~& -END FUNCTION - -FUNCTION __QB_NODE_validateHandle (handle AS LONG, optionalRequiredType AS LONG) -$CHECKING:OFF -IF handle > __QB_NODE_ubound OR handle <= 0 THEN ERROR 258: EXIT FUNCTION 'invalid handle -IF __QB_NODE(handle).valid = 0 THEN ERROR 258: EXIT FUNCTION -IF optionalRequiredType <> 0 THEN - IF (optionalRequiredType AND __QB_NODE(handle).type) = 0 THEN - ERROR 258 - __QB_NODE_validateHandle = -1 - EXIT FUNCTION - END IF -END IF -$CHECKING:ON -END FUNCTION - -SUB __QB_NODE_detach (handle AS LONG) -IF QB_DEBUG_VERBOSE THEN - PRINT "__QB_NODE_detach: Node"; handle; "of type: " + QB_NODE_typeName(__QB_NODE(handle).type) -END IF -'generic detach method (regardless of parent type) -DIM QB__i -QB__i = __QB_NODE(handle).next -IF QB__i THEN - __QB_NODE(QB__i).prev = __QB_NODE(handle).prev -END IF -QB__i = __QB_NODE(handle).prev -IF QB__i THEN - __QB_NODE(QB__i).next = __QB_NODE(handle).next -END IF -QB__i = __QB_NODE(handle).parent -IF QB__i THEN - IF __QB_NODE(QB__i).firstChild = handle THEN __QB_NODE(QB__i).firstChild = __QB_NODE(handle).next - IF __QB_NODE(QB__i).lastChild = handle THEN __QB_NODE(QB__i).lastChild = __QB_NODE(handle).prev - __QB_NODE(QB__i).count = __QB_NODE(QB__i).count - 1 - __QB_NODE(handle).parent = 0 -END IF -__QB_NODE(handle).next = 0 -__QB_NODE(handle).prev = 0 -__QB_NODE(handle).hashReference = 0 -END SUB - -'################################################## - - - -SUB __QB_NODESET_addChildren (QB__parent AS LONG, QB__selOut AS LONG) -DIM QB__child AS LONG -DIM QB__newSel AS LONG -QB__child = __QB_NODE(QB__parent).firstChild -DO WHILE QB__child - QB__newSel = QB_NODE_newLabel_long(QB__child) - QB_NODE_assign QB__selOut, QB__newSel - IF __QB_NODE(QB__child).firstChild THEN __QB_NODESET_addChildren QB__child, QB__selOut - QB__child = __QB_NODE(QB__child).next -LOOP -END SUB - -SUB __QB_NODESET_addChildrenWithDepth (QB__parent AS LONG, QB__selOut AS LONG, currentDepth AS LONG, minDepth AS LONG, maxDepth AS LONG) -DIM QB__child AS LONG -DIM QB__newSel AS LONG -QB__child = __QB_NODE(QB__parent).firstChild -DO WHILE QB__child - IF currentDepth >= minDepth THEN - QB__newSel = QB_NODE_newLabel_long(QB__child) - QB_NODE_assign QB__selOut, QB__newSel - END IF - IF currentDepth < maxDepth THEN - IF __QB_NODE(QB__child).firstChild THEN - __QB_NODESET_addChildrenWithDepth QB__child, QB__selOut, currentDepth + 1, minDepth, maxDepth - END IF - END IF - QB__child = __QB_NODE(QB__child).next -LOOP -END SUB - - - -SUB __QB_NODE_debugInfo (QB__i AS LONG) -PRINT "-------- __QB_NODE_debugInfo:"; QB__i; "--------" -'type -DIM QB__type AS LONG -QB__type = __QB_NODE(QB__i).type -PRINT "TYPE: " + QB_NODE_typeName(QB__type) -'label -IF __QB_NODE(QB__i).labelFormat = QB_NODE_FORMAT_STR THEN - PRINT "LABEL: " + QB_STR_get(__QB_NODE(QB__i).label) -END IF -'value -IF __QB_NODE(QB__i).valueFormat = QB_NODE_FORMAT_STR THEN - PRINT "VALUE: " + QB_STR_get(__QB_NODE(QB__i).value) -END IF -IF __QB_NODE(QB__i).parent THEN - PRINT "Has parent of type " + QB_NODE_typeName(__QB_NODE(__QB_NODE(QB__i).parent).type) + " ["; __QB_NODE(QB__i).parent; "]" -ELSE - PRINT "This is a root element" -END IF -IF __QB_NODE(QB__i).firstChild THEN - PRINT "Has child of type " + QB_NODE_typeName(__QB_NODE(__QB_NODE(QB__i).firstChild).type) + " ["; __QB_NODE(QB__i).firstChild; "]" -END IF -IF __QB_NODE(QB__i).next THEN - PRINT "Has next sibling of type " + QB_NODE_typeName(__QB_NODE(__QB_NODE(QB__i).next).type) + " ["; __QB_NODE(QB__i).next; "]" -END IF -IF __QB_NODE(QB__i).prev THEN - PRINT "Has previous sibling of type " + QB_NODE_typeName(__QB_NODE(__QB_NODE(QB__i).prev).type) + " ["; __QB_NODE(QB__i).prev; "]" -END IF -PRINT "----------------" -END SUB - -'################################################## - - -'#################### JSON: Private Methods #################### - -FUNCTION __QB_JSON_unescape$ (QB__in AS STRING, QB__detectedFormat AS LONG, QB__detectedFormatValue AS LONG) -'-unescapes string -'-strips paired single or double quotes -'-detects data type (string, number, bool, null) -'-very permissive -QB__detectedFormat = 0 -QB__detectedFormatValue = 0 -DIM QB__out AS STRING -DIM QB__i1 AS LONG -DIM QB__i2 AS LONG -DIM QB__i3 AS LONG -DIM QB__in_len AS LONG -DIM QB__a AS LONG -DIM QB__a2 AS LONG -DIM QB__hex AS STRING -DIM QB__hex_len AS LONG -DIM QB__quoted AS LONG -QB__in_len = LEN(QB__in) -QB__out = SPACE$(QB__in_len) 'output is never longer than input -QB__i1 = 1 -QB__i2 = 0 -QB__i = 0 -'trim -QB__in = LTRIM$(RTRIM$(QB__in)) -QB__in_len = LEN(QB__in) -'strip quotes -IF ASC(QB__in) = 34 OR ASC(QB__in) = 39 THEN - IF ASC(QB__in, QB__in_len) = ASC(QB__in) AND QB__in_len > 1 THEN - QB__quoted = ASC(QB__in) - QB__detectedFormat = QB_NODE_FORMAT_STR - QB__in_len = QB__in_len - 2 - QB__in = MID$(QB__in, 2, QB__in_len) - END IF -END IF -'detect type if not quoted -IF QB__quoted = 0 THEN - IF QB__in_len = 4 THEN - IF LCASE$(QB__in) = "true" THEN QB__in = "true": QB__detectedFormat = QB_NODE_FORMAT_BOOL: QB__detectedFormatValue = QB_TRUE - IF LCASE$(QB__in) = "null" THEN QB__in = "null": QB__detectedFormat = QB_NODE_FORMAT_NULL: QB__detectedFormatValue = QB_NULL - END IF - IF QB__in_len = 5 THEN - IF LCASE$(QB__in) = "false" THEN QB__in = "false": QB__detectedFormat = QB_NODE_FORMAT_BOOL: QB__detectedFormatValue = QB_FALSE - END IF - IF QB__detectedFormat = 0 THEN - QB__a = ASC(QB__in) - IF QB__a >= 48 AND QB__a <= 57 THEN '0-9 - IF INSTR(QB__in, ".") = 0 THEN - QB__detectedFormat = QB_NODE_FORMAT_LONG: QB__detectedFormatValue = VAL(QB__in) - END IF - ELSE - IF QB__a = 45 THEN '- - IF INSTR(QB__in, ".") = 0 THEN - QB__detectedFormat = QB_NODE_FORMAT_LONG: QB__detectedFormatValue = VAL(QB__in) - END IF - END IF - IF QB__a = 46 THEN '. - 'TODO: decimal support - END IF - END IF - IF QB__detectedFormat = 0 THEN QB__detectedFormat = QB_NODE_FORMAT_STR - END IF -END IF -'if a string, parse to convert escaped content -IF QB__detectedFormat = QB_NODE_FORMAT_STR THEN - DO WHILE QB__i1 <= QB__in_len - QB__a = ASC(QB__in, QB__i1) - IF QB__a <> 92 OR QB__i1 = QB__in_len THEN 'not \ or at end - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a - ELSE - QB__i1 = QB__i1 + 1: QB__a = ASC(QB__in, QB__i1) - QB__a2 = __QB_JSON_escape_lookup_reversed(QB__a) - IF QB__a2 THEN - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a2 - ELSE - IF QB__a = 117 OR QB__a = 85 AND QB__i1 + 4 <= QB__in_len THEN 'u or U - QB__a2 = VAL("&H" + MID$(QB__in, QB__i1 + 1, 4) + "~&") 'unicode code point - QB__i1 = QB__i1 + 4 - QB__a = 0 - IF QB__a2 = 0 THEN - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = 0 - ELSE - 'todo: replace with dictionary lookup - FOR QB__i3 = 1 TO 255 - IF QB__a2 = _MAPUNICODE(QB__i3) THEN - QB__a = QB__i3 - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a - EXIT FOR - END IF - NEXT - IF QB__i3 = 256 THEN 'could not locate a match for the character, show a question mark - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = 63 '? - END IF - END IF - ELSE - 'unknown \??? combination (add as is) - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = 92 '\ - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a '2nd character - END IF - END IF - END IF - QB__i1 = QB__i1 + 1 - LOOP - __QB_JSON_unescape$ = LEFT$(QB__out, QB__i2) -ELSE - __QB_JSON_unescape$ = QB__in -END IF -END FUNCTION - -FUNCTION __QB_JSON_escape$ (QB__in AS STRING) -DIM QB__out AS STRING -DIM QB__i1 AS LONG -DIM QB__i2 AS LONG -DIM QB__in_len AS LONG -DIM QB__a AS LONG -DIM QB__a2 AS LONG -DIM QB__hex AS STRING -DIM QB__hex_len AS LONG -QB__in_len = LEN(QB__in) -QB__out = SPACE$(QB__in_len * 6) 'worst possible case is double size (\uXXXX) -QB__i1 = 1 -QB__i2 = 0 -QB__i = 0 -DO WHILE QB__i1 <= QB__in_len - QB__a = ASC(QB__in, QB__i1) - IF QB__a <> 92 AND QB__a <> 34 AND (QB__a >= 32 AND QB__a <= 126) THEN 'not \ or " and valid standard ASCII - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a - ELSE - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = 92 '\ - QB__a2 = __QB_JSON_escape_lookup(QB__a) - IF QB__a2 THEN - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a2 - ELSE - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = 117 'u - IF QB__a = 0 THEN - QB__hex = "0" - ELSE - QB__hex = HEX$(_MAPUNICODE(QB__a)) - END IF - QB__hex_len = LEN(QB__hex) - QB__a2 = 48 - FOR QB__i = 1 TO 4 - IF 5 - QB__i <= QB__hex_len THEN - QB__a2 = ASC(QB__hex, QB__i - (4 - QB__hex_len)) - END IF - QB__i2 = QB__i2 + 1: ASC(QB__out, QB__i2) = QB__a2 - NEXT - END IF - END IF - QB__i1 = QB__i1 + 1 -LOOP -__QB_JSON_escape$ = LEFT$(QB__out, QB__i2) -END FUNCTION - -FUNCTION __QB_JSON_output_string$ (QB__in AS STRING) -__QB_JSON_output_string$ = QB_STR_QUOTE + __QB_JSON_escape$(QB__in) + QB_STR_QUOTE -END FUNCTION - -SUB __QB_JSON_serialize (json AS STRING, first AS LONG, addSiblings AS LONG) -DIM QB__i AS LONG -QB__i = first -DO WHILE QB__i - IF QB__i <> first THEN - json = json + "," - END IF - IF __QB_NODE(QB__i).type = QB_NODE_TYPE_DICTIONARY THEN - IF __QB_NODE(QB__i).labelFormat = QB_NODE_FORMAT_STR THEN - json = json + __QB_JSON_output_string(QB_STR_get(__QB_NODE(QB__i).label)) + ":" - END IF - json = json + "{" - __QB_JSON_serialize json, __QB_NODE(QB__i).firstChild, 1 - json = json + "}" - END IF - IF __QB_NODE(QB__i).type = QB_NODE_TYPE_LIST THEN - IF __QB_NODE(QB__i).labelFormat = QB_NODE_FORMAT_STR THEN - json = json + __QB_JSON_output_string(QB_STR_get(__QB_NODE(QB__i).label)) + ":" - END IF - json = json + "[" - __QB_JSON_serialize json, __QB_NODE(QB__i).firstChild, 1 - json = json + "]" - END IF - IF __QB_NODE(QB__i).type = QB_NODE_TYPE_VALUE THEN - IF __QB_NODE(QB__i).labelFormat = QB_NODE_FORMAT_STR THEN - json = json + __QB_JSON_output_string(QB_STR_get(__QB_NODE(QB__i).label)) + ":" - END IF - IF __QB_NODE(QB__i).valueFormat <> QB_NODE_FORMAT_STR THEN - json = json + QB_NODE_value(QB__i) - ELSE - json = json + __QB_JSON_output_string(QB_NODE_value(QB__i)) - END IF - END IF - IF addSiblings THEN - QB__i = __QB_NODE(QB__i).next - ELSE - QB__i = 0 - END IF -LOOP -END SUB - - -FUNCTION __QB_JSON_deserialize (QB__json AS STRING, QB__index AS LONG, QB__parent AS LONG) -'returns the first node created - -DIM QB__firstNodeCreated AS LONG -DIM QB__ignore AS LONG - -DIM QB__index1 AS LONG -QB__index1 = QB__index - -DIM QB__asc AS LONG -DIM QB__labelIndex AS LONG -DIM QB__label AS STRING -DIM QB__value AS STRING -DIM QB__obj AS LONG -DIM QB__objAdded AS LONG -DIM QB__final AS LONG -DIM QB__detectedFormat AS LONG -DIM QB__detectedFormatValue AS LONG -DIM QB__contentExists AS LONG -DO WHILE QB__index <= LEN(QB__json) + 1 - IF QB__index = LEN(QB__json) + 1 THEN - QB__final = 1 - QB__asc = 32 'whitespace - ELSE - QB__asc = ASC(QB__json, QB__index) - END IF - - IF QB__asc = 44 OR QB__asc = 125 OR QB__asc = 93 OR QB__final <> 0 THEN ', } ] final - IF QB__objAdded = 0 AND QB__contentExists <> 0 THEN - QB__value = MID$(QB__json, QB__index1, (QB__index - QB__index1)) - 'TODO: derive value format here - QB__obj = QB_NODE_new(QB_NODE_TYPE_VALUE, 0) - IF QB__firstNodeCreated = 0 THEN QB__firstNodeCreated = QB__obj - IF QB__label <> "" THEN - QB_NODE_setLabel QB__obj, __QB_JSON_unescape$(QB__label, 0, 0) - QB__label = "" - END IF - QB__value = __QB_JSON_unescape$(QB__value, QB__detectedFormat, QB__detectedFormatValue) - IF QB__detectedFormat = QB_NODE_FORMAT_STR THEN - QB_NODE_setValue_format QB__obj, QB_STR_new(QB__value), QB__detectedFormat - ELSE - QB_NODE_setValue_format QB__obj, QB__detectedFormatValue, QB__detectedFormat - END IF - IF QB__parent <> 0 THEN QB_NODE_assign QB__parent, QB__obj - END IF - 'end of block encountered? - IF QB__asc = 125 OR QB__asc = 93 OR QB__final <> 0 THEN '} ] final - __QB_JSON_deserialize = QB__firstNodeCreated - EXIT FUNCTION - END IF - QB__index1 = QB__index + 1 - QB__objAdded = 0 - QB__contentExists = 0 - END IF - - IF QB__asc <> 44 AND QB__asc <> 32 AND QB__asc <> 9 THEN QB__contentExists = 1 - - IF QB__asc = 58 THEN ': - IF LEN(QB__label) THEN - 'already has label - PRINT "Invalid label separator encountered ':'" - END - END IF - QB__label = MID$(QB__json, QB__index1, (QB__index - QB__index1)) - QB__index1 = QB__index + 1 'move start location - QB__contentExists = 0 - END IF - - IF QB__asc = 123 THEN '{ - IF QB__objAdded <> 0 THEN - PRINT "Expected ," - END - END IF - QB__obj = QB_NODE_newDictionary - IF QB__firstNodeCreated = 0 THEN QB__firstNodeCreated = QB__obj - IF QB__label <> "" THEN - QB_NODE_setLabel QB__obj, __QB_JSON_unescape$(QB__label, 0, 0) - QB__label = "" - END IF - QB__index = QB__index + 1 - QB__ignore = __QB_JSON_deserialize(QB__json, QB__index, QB__obj) - IF ASC(QB__json, QB__index) <> 125 THEN '} - PRINT "Expected }" - END - END IF - IF QB__parent <> 0 THEN QB_NODE_assign QB__parent, QB__obj - QB__objAdded = 1 - QB__contentExists = 0 - END IF - - IF QB__asc = 91 THEN '[ - IF QB__objAdded <> 0 THEN - PRINT "Expected ," - END IF - QB__obj = QB_NODE_newList - IF QB__firstNodeCreated = 0 THEN QB__firstNodeCreated = QB__obj - IF QB__label <> "" THEN - QB_NODE_setLabel QB__obj, __QB_JSON_unescape$(QB__label, 0, 0) - QB__label = "" - END IF - QB__index = QB__index + 1 - QB__ignore = __QB_JSON_deserialize(QB__json, QB__index, QB__obj) - IF ASC(QB__json, QB__index) <> 93 THEN '] - PRINT "Expected ]" - END - END IF - IF QB__parent <> 0 THEN QB_NODE_assign QB__parent, QB__obj - QB__objAdded = 1 - QB__contentExists = 0 - END IF - - QB__index = QB__index + 1 -LOOP -PRINT "Unexpected end of loop encountered" -END - -END FUNCTION - -'################################################## - -'#################### DATETIME: Private Methods #################### - -FUNCTION __QB_DATETIME_format_smartCase$ (format AS STRING, value AS STRING) -DIM QB__type AS LONG -DIM QB__a AS LONG -DIM QB__a2 AS LONG -QB__a = ASC(format, 2) -QB__a2 = ASC(format, 3) -IF QB__a >= 65 AND QB__a <= 90 THEN - IF QB__a2 >= 65 AND QB__a2 <= 90 THEN - value = UCASE$(value) - ELSE - value = UCASE$(LEFT$(value, 1)) + LCASE$(MID$(value, 2)) - END IF -ELSE - value = LCASE$(value) -END IF -__QB_DATETIME_format_smartCase$ = value -END FUNCTION - -'################################################## \ No newline at end of file diff --git a/source/virtual_keyboard/embed/footer.bas b/source/virtual_keyboard/embed/footer.bas deleted file mode 100644 index b319e5b7d..000000000 --- a/source/virtual_keyboard/embed/footer.bas +++ /dev/null @@ -1,2 +0,0 @@ -'$include:'..\..\qb_framework\qb_framework_methods.bas' -'$include:'..\virtual_keyboard_methods.bas' diff --git a/source/virtual_keyboard/embed/header.bas b/source/virtual_keyboard/embed/header.bas deleted file mode 100644 index 129b2516e..000000000 --- a/source/virtual_keyboard/embed/header.bas +++ /dev/null @@ -1,7 +0,0 @@ -'$include:'..\..\qb_framework\qb_framework_global.bas' -'$include:'..\virtual_keyboard_global.bas' -DEFSNG A-Z -$INSTALLFILES "..\..\..\cyberbit.ttf" -$INSTALLFILES "..\layouts\virtual_keyboard_layout_default.txt" -dim shared appRootPath as string -appRootPath$=_CWD$+"\" '_CWD$ is the application root when the program launches, preserve this value for later use before client program changes the path diff --git a/source/virtual_keyboard/layouts/virtual_keyboard_layout_default.txt b/source/virtual_keyboard/layouts/virtual_keyboard_layout_default.txt deleted file mode 100644 index c2a9399a0..000000000 --- a/source/virtual_keyboard/layouts/virtual_keyboard_layout_default.txt +++ /dev/null @@ -1 +0,0 @@ -{"width":90,"keys":[{"type":"keySet","x":0,"y":30,"width":6,"height":3,"label":"\u2261","childKeys":[{"type":"key","offsetX":25,"offsetY":-30,"width":34,"height":6,"label":"","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_SPACE"}}},{"type":"key","offsetX":86,"offsetY":-30,"width":4,"height":6,"label":"Esc","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_ESCAPE"}}},{"type":"key","offsetX":0,"offsetY":-24,"width":14,"height":6,"label":"Shift","locks":true,"lockIsTemporary":true,"events":{"keydown":{"keyCode":"KEY_LSHIFT"}}},{"type":"key","offsetX":0,"offsetY":-18,"width":11,"height":6,"label":"Caps Lock","locks":true,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_CAPSLOCK"}}},{"type":"key","offsetX":0,"offsetY":-12,"width":9,"height":6,"label":"Tab","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_TAB"}}},{"type":"key","offsetX":78,"offsetY":-6,"width":12,"height":6,"label":"Back Space","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_BACKSPACE"}}},{"type":"key","offsetX":72,"offsetY":-6,"width":6,"height":6,"label":"=","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_EQUAL"},"keydownWithShift":{"keyCode":"KEY_PLUS","label":"+"}}},{"type":"key","offsetX":66,"offsetY":-6,"width":6,"height":6,"label":"-","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_MINUS"},"keydownWithShift":{"keyCode":"KEY_UNDERSCORE","label":"_"}}},{"type":"key","offsetX":60,"offsetY":-6,"width":6,"height":6,"label":"0","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_0"},"keydownWithShift":{"keyCode":"KEY_CLOSE_BRACKET","label":")"}}},{"type":"key","offsetX":54,"offsetY":-6,"width":6,"height":6,"label":"9","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_9"},"keydownWithShift":{"keyCode":"KEY_OPEN_BRACKET","label":"("}}},{"type":"key","offsetX":48,"offsetY":-6,"width":6,"height":6,"label":"8","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_8"},"keydownWithShift":{"keyCode":"KEY_STAR","label":"*"}}},{"type":"key","offsetX":42,"offsetY":-6,"width":6,"height":6,"label":"7","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_7"},"keydownWithShift":{"keyCode":"KEY_AND","label":"&"}}},{"type":"key","offsetX":36,"offsetY":-6,"width":6,"height":6,"label":"6","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_6"},"keydownWithShift":{"keyCode":"KEY_CARET","label":"^"}}},{"type":"key","offsetX":30,"offsetY":-6,"width":6,"height":6,"label":"5","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_5"},"keydownWithShift":{"keyCode":"KEY_PERCENT","label":"%"}}},{"type":"key","offsetX":18,"offsetY":-6,"width":6,"height":6,"label":"3","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_3"},"keydownWithShift":{"keyCode":"KEY_HASH","label":"#"}}},{"type":"key","offsetX":24,"offsetY":-6,"width":6,"height":6,"label":"4","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_4"},"keydownWithShift":{"keyCode":"KEY_DOLLAR","label":"$"}}},{"type":"key","offsetX":0,"offsetY":-30,"width":9,"height":6,"label":"Ctrl","locks":true,"lockIsTemporary":true,"events":{"keydown":{"keyCode":"KEY_LCTRL"}}},{"type":"key","offsetX":9,"offsetY":-30,"width":8,"height":6,"label":"\u2302","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LSUPER"}}},{"type":"key","offsetX":17,"offsetY":-30,"width":8,"height":6,"label":"Alt","locks":true,"lockIsTemporary":true,"events":{"keydown":{"keyCode":"KEY_LALT"}}},{"type":"key","offsetX":59,"offsetY":-30,"width":9,"height":6,"label":"Alt","locks":true,"lockIsTemporary":true,"events":{"keydown":{"keyCode":"KEY_RALT"}}},{"type":"key","offsetX":80,"offsetY":-24,"width":10,"height":6,"label":"Shift","locks":true,"lockIsTemporary":true,"events":{"keydown":{"keyCode":"KEY_RSHIFT"}}},{"type":"key","offsetX":74,"offsetY":-30,"width":6,"height":6,"label":"\u2193","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_DOWN"}}},{"type":"key","offsetX":68,"offsetY":-30,"width":6,"height":6,"label":"\u2190","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LEFT"}}},{"type":"key","offsetX":80,"offsetY":-30,"width":6,"height":6,"label":"\u2192","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_RIGHT"}}},{"type":"key","offsetX":74,"offsetY":-24,"width":6,"height":6,"label":"\u2191","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_UP"}}},{"type":"key","offsetX":68,"offsetY":-24,"width":6,"height":6,"label":"/","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_FORWARD_SLASH"},"keydownWithShift":{"keyCode":"KEY_QUESTION","label":"?"}}},{"type":"key","offsetX":62,"offsetY":-24,"width":6,"height":6,"label":".","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_DOT"},"keydownWithShift":{"keyCode":"KEY_GREATER_THAN","label":">"}}},{"type":"key","offsetX":56,"offsetY":-24,"width":6,"height":6,"label":",","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_COMMA"},"keydownWithShift":{"keyCode":"KEY_LESS_THAN","label":"<"}}},{"type":"key","offsetX":50,"offsetY":-24,"width":6,"height":6,"label":"m","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_M"},"keydownWithShift":{"keyCode":"KEY_UCASE_M","label":"M"}}},{"type":"key","offsetX":44,"offsetY":-24,"width":6,"height":6,"label":"n","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_N"},"keydownWithShift":{"keyCode":"KEY_UCASE_N","label":"N"}}},{"type":"key","offsetX":38,"offsetY":-24,"width":6,"height":6,"label":"b","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_B"},"keydownWithShift":{"keyCode":"KEY_UCASE_B","label":"B"}}},{"type":"key","offsetX":32,"offsetY":-24,"width":6,"height":6,"label":"v","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_V"},"keydownWithShift":{"keyCode":"KEY_UCASE_V","label":"V"}}},{"type":"key","offsetX":26,"offsetY":-24,"width":6,"height":6,"label":"c","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_C"},"keydownWithShift":{"keyCode":"KEY_UCASE_C","label":"C"}}},{"type":"key","offsetX":20,"offsetY":-24,"width":6,"height":6,"label":"x","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_X"},"keydownWithShift":{"keyCode":"KEY_UCASE_X","label":"X"}}},{"type":"key","offsetX":14,"offsetY":-24,"width":6,"height":6,"label":"z","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_Z"},"keydownWithShift":{"keyCode":"KEY_UCASE_Z","label":"Z"}}},{"type":"key","offsetX":77,"offsetY":-18,"width":13,"height":6,"label":"Enter","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_ENTER"}}},{"type":"key","offsetX":81,"offsetY":-12,"width":9,"height":6,"label":"\\","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_BACK_SLASH"},"keydownWithShift":{"keyCode":"KEY_VERTICAL_BAR","label":"|"}}},{"type":"key","offsetX":71,"offsetY":-18,"width":6,"height":6,"label":"'","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_APOSTROPHE"},"keydownWithShift":{"keyCode":"KEY_QUOTE","label":"\""}}},{"type":"key","offsetX":65,"offsetY":-18,"width":6,"height":6,"label":";","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_SEMICOLON"},"keydownWithShift":{"keyCode":"KEY_COLON","label":":"}}},{"type":"key","offsetX":59,"offsetY":-18,"width":6,"height":6,"label":"l","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_L"},"keydownWithShift":{"keyCode":"KEY_UCASE_L","label":"L"}}},{"type":"key","offsetX":53,"offsetY":-18,"width":6,"height":6,"label":"k","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_K"},"keydownWithShift":{"keyCode":"KEY_UCASE_K","label":"K"}}},{"type":"key","offsetX":47,"offsetY":-18,"width":6,"height":6,"label":"j","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_J"},"keydownWithShift":{"keyCode":"KEY_UCASE_J","label":"J"}}},{"type":"key","offsetX":41,"offsetY":-18,"width":6,"height":6,"label":"h","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_H"},"keydownWithShift":{"keyCode":"KEY_UCASE_H","label":"H"}}},{"type":"key","offsetX":35,"offsetY":-18,"width":6,"height":6,"label":"g","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_G"},"keydownWithShift":{"keyCode":"KEY_UCASE_G","label":"G"}}},{"type":"key","offsetX":29,"offsetY":-18,"width":6,"height":6,"label":"f","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_F"},"keydownWithShift":{"keyCode":"KEY_UCASE_F","label":"F"}}},{"type":"key","offsetX":23,"offsetY":-18,"width":6,"height":6,"label":"d","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_D"},"keydownWithShift":{"keyCode":"KEY_UCASE_D","label":"D"}}},{"type":"key","offsetX":17,"offsetY":-18,"width":6,"height":6,"label":"s","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_S"},"keydownWithShift":{"keyCode":"KEY_UCASE_S","label":"S"}}},{"type":"key","offsetX":11,"offsetY":-18,"width":6,"height":6,"label":"a","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_A"},"keydownWithShift":{"keyCode":"KEY_UCASE_A","label":"A"}}},{"type":"key","offsetX":12,"offsetY":-6,"width":6,"height":6,"label":"2","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_2"},"keydownWithShift":{"keyCode":"KEY_AT","label":"@"}}},{"type":"key","offsetX":75,"offsetY":-12,"width":6,"height":6,"label":"]","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_CLOSE_BRACKET_SQUARE"},"keydownWithShift":{"keyCode":"KEY_CLOSE_BRACKET_CURLY","label":"}"}}},{"type":"key","offsetX":69,"offsetY":-12,"width":6,"height":6,"label":"[","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_OPEN_BRACKET_SQUARE"},"keydownWithShift":{"keyCode":"KEY_OPEN_BRACKET_CURLY","label":"{"}}},{"type":"key","offsetX":63,"offsetY":-12,"width":6,"height":6,"label":"p","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_P"},"keydownWithShift":{"keyCode":"KEY_UCASE_P","label":"P"}}},{"type":"key","offsetX":57,"offsetY":-12,"width":6,"height":6,"label":"o","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_O"},"keydownWithShift":{"keyCode":"KEY_UCASE_O","label":"O"}}},{"type":"key","offsetX":51,"offsetY":-12,"width":6,"height":6,"label":"i","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_I"},"keydownWithShift":{"keyCode":"KEY_UCASE_I","label":"I"}}},{"type":"key","offsetX":45,"offsetY":-12,"width":6,"height":6,"label":"u","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_U"},"keydownWithShift":{"keyCode":"KEY_UCASE_U","label":"U"}}},{"type":"key","offsetX":39,"offsetY":-12,"width":6,"height":6,"label":"y","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_Y"},"keydownWithShift":{"keyCode":"KEY_UCASE_Y","label":"Y"}}},{"type":"key","offsetX":33,"offsetY":-12,"width":6,"height":6,"label":"t","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_T"},"keydownWithShift":{"keyCode":"KEY_UCASE_T","label":"T"}}},{"type":"key","offsetX":27,"offsetY":-12,"width":6,"height":6,"label":"r","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_R"},"keydownWithShift":{"keyCode":"KEY_UCASE_R","label":"R"}}},{"type":"key","offsetX":21,"offsetY":-12,"width":6,"height":6,"label":"e","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_E"},"keydownWithShift":{"keyCode":"KEY_UCASE_E","label":"E"}}},{"type":"key","offsetX":15,"offsetY":-12,"width":6,"height":6,"label":"w","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_W"},"keydownWithShift":{"keyCode":"KEY_UCASE_W","label":"W"}}},{"type":"key","offsetX":9,"offsetY":-12,"width":6,"height":6,"label":"q","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_LCASE_Q"},"keydownWithShift":{"keyCode":"KEY_UCASE_Q","label":"Q"}}},{"type":"key","offsetX":6,"offsetY":-6,"width":6,"height":6,"label":"1","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_1"},"keydownWithShift":{"keyCode":"KEY_EXCLAMATION","label":"!"}}},{"type":"key","offsetX":0,"offsetY":-6,"width":6,"height":6,"label":"`","locks":false,"lockIsTemporary":false,"events":{"keydown":{"keyCode":"KEY_REVERSE_APOSTROPHE"},"keydownWithShift":{"keyCode":"KEY_TILDE","label":"~"}}}]}]} diff --git a/source/virtual_keyboard/virtual_keyboard_global.bas b/source/virtual_keyboard/virtual_keyboard_global.bas deleted file mode 100644 index c317326bf..000000000 --- a/source/virtual_keyboard/virtual_keyboard_global.bas +++ /dev/null @@ -1,177 +0,0 @@ -DEFSNG A-Z - -DECLARE LIBRARY - SUB requestKeyboardOverlayImage (BYVAL handle AS LONG) - SUB mouseinput_mode (BYVAL exclusive AS LONG) - FUNCTION func__mouseinput_exclusive& -END DECLARE - -'VK Constants -'$include:'virtual_keyboard_keycodes.bas' -'$include:'virtual_keyboard_keypush.bas' - -'VK Types -TYPE VKEY_EVENT - keydown AS LONG -END TYPE - -TYPE VKEY_DPAD - up AS VKEY_EVENT - down AS VKEY_EVENT - left AS VKEY_EVENT - right AS VKEY_EVENT - x AS SINGLE '-1 to 1 - y AS SINGLE '-1 to 1 - dx AS LONG '-1, 0, 1 - dy AS LONG '-1, 0, 1 - lastKeyDx AS LONG '-1, 0, 1 - lastKeyDy AS LONG '-1, 0, 1 -END TYPE - -TYPE VKEY_TYPE - active AS LONG '1=in use - internal AS LONG - role AS STRING * 4 - state AS LONG - label AS STRING * 100 - x AS LONG 'left hand side - y AS LONG 'from base of screen - w AS LONG 'width - h AS LONG 'height (default is 10) - parent AS LONG - offsetX AS LONG - offsetY AS LONG - held AS LONG - event AS VKEY_EVENT - - hasShiftedEvent AS LONG - shiftedEvent AS VKEY_EVENT 'eg. when shifted or caps lock is on - shiftedLabel AS STRING * 100 - - locks AS LONG '1 or 0 eg. num lock, scroll lock, caps lock - lockIsTemporary AS LONG 'eg shift key, locks till next press - locked AS LONG - dpad AS VKEY_DPAD - - - subImage AS LONG - - image AS LONG - highlightImage AS LONG - selectedImage AS LONG - shiftedImage AS LONG - shiftedHighlightImage AS LONG - shiftedSelectedImage AS LONG - - reDraw AS LONG - - 'key repeat - lastKeydownTime AS SINGLE - keyRepeatCount AS LONG - keyRepeatKeyCode AS LONG - -END TYPE - -'VK Global Variables -DIM SHARED VK(1000) AS VKEY_TYPE -DIM SHARED VkLast - -DIM SHARED VkEmpty AS VKEY_TYPE -VkEmpty.label = "" - -DIM SHARED VkHide: VkHide = 1 - -DIM SHARED VkUnitStepY: VkUnitStepY = 6 -DIM SHARED VkNewKeySize: VkNewKeySize = 6 -DIM SHARED VkDefaultWidth: VkDefaultWidth = 6 -DIM SHARED VkLastSelectionPage: VkLastSelectionPage = 1 -DIM SHARED VkUnitSize 'size of a unit in pixels (floating point) - -DIM SHARED VkDefaultSelectKeyPage: VkDefaultSelectKeyPage = 1 -DIM SHARED VkFont -DIM SHARED VkFontSmall -DIM SHARED VkKeyNameLookup AS LONG -DIM SHARED VkKeyCodeLookup AS LONG -VkAddKeyNames - -'fonts are loaded on startup, not all sizes are available and the system will -'find/use the best match -DIM SHARED vkFonts(1000) AS LONG -DIM SHARED vkFontAllow(1000) AS LONG -vkFontAllow(8)=1 -vkFontAllow(9)=1 -vkFontAllow(10)=1 -vkFontAllow(11)=1 -vkFontAllow(12)=1 -vkFontAllow(14)=1 -vkFontAllow(16)=1 -vkFontAllow(18)=1 -vkFontAllow(20)=1 -vkFontAllow(24)=1 -vkFontAllow(28)=1 -vkFontAllow(32)=1 -vkFontAllow(36)=1 -vkFontAllow(48)=1 -vkFontAllow(72)=1 -vkFontAllow(100)=1 - -DIM SHARED VkBgTex -DIM SHARED VkBorderTex -DIM SHARED VkInternalBgTex -DIM SHARED VkInternalBorderTex -DIM SHARED VkClearTex - -DIM SHARED VkSelectedKey -DIM SHARED VkAddShiftedKey - -DIM SHARED VkWinX -DIM SHARED VkWinY -DIM SHARED VkOverlay 'an image overlayed over the other content -DIM SHARED VkBackbuffer 'backbuffer of overlay - -DIM SHARED VkExiting -DIM SHARED VkExited - -DIM SHARED VkReset - -DIM SHARED VkDelayStartTime AS DOUBLE -DIM SHARED VkDelay AS DOUBLE -VkDelayStartTime=TIMER(0.001) -VkDelay=1 'programs typically set their screen resolution on start, so wait a second before trying to build a keyboard which matches that resolution -DIM SHARED VkDelayedReset - -DIM SHARED VkWidthInUnits - -DIM SHARED VkTimer -VkTimer = _FREETIMER - -DIM SHARED VkReDraw AS LONG: VkReDraw = 1 - -DIM SHARED VkDelayUntilFirstRepeat AS SINGLE: VkDelayUntilFirstRepeat = 0.75 -DIM SHARED VkDelayUntilFollowingRepeats AS SINGLE: VkDelayUntilFollowingRepeats = 0.025 '40 per sec - -TYPE VkRegTypeX - ax AS INTEGER - bx AS INTEGER - cx AS INTEGER - dx AS INTEGER - bp AS INTEGER - si AS INTEGER - di AS INTEGER - flags AS INTEGER - ds AS INTEGER - es AS INTEGER -END TYPE -DIM SHARED VkReg AS VkRegTypeX - -DIM SHARED VkSharedMouseMx AS LONG -DIM SHARED VkSharedMouseMy AS LONG -DIM SHARED VkSharedMouseMb AS LONG - -DIM SHARED VkSharedInputMode AS LONG: VkSharedInputMode = -1 - -ON TIMER(VkTimer, .01) VkUpdate -TIMER(VkTimer) ON - -DIM SHARED VkMousePipe AS LONG -DIM SHARED VkMousePipeCapture AS LONG \ No newline at end of file diff --git a/source/virtual_keyboard/virtual_keyboard_keycodes.bas b/source/virtual_keyboard/virtual_keyboard_keycodes.bas deleted file mode 100644 index eb4bd2132..000000000 --- a/source/virtual_keyboard/virtual_keyboard_keycodes.bas +++ /dev/null @@ -1,207 +0,0 @@ -CONST VK_KEY_PAUSE& = 100019 -CONST VK_KEY_NUMLOCK& = 100300 -CONST VK_KEY_CAPSLOCK& = 100301 -CONST VK_KEY_SCROLLOCK& = 100302 -CONST VK_KEY_RSHIFT& = 100303 -CONST VK_KEY_LSHIFT& = 100304 -CONST VK_KEY_RCTRL& = 100305 -CONST VK_KEY_LCTRL& = 100306 -CONST VK_KEY_RALT& = 100307 -CONST VK_KEY_LALT& = 100308 -CONST VK_KEY_RMETA& = 100309 'Left 'Apple' key (MacOSX) -CONST VK_KEY_LMETA& = 100310 'Right 'Apple' key (MacOSX) -CONST VK_KEY_LSUPER& = 100311 'Left "Windows" key -CONST VK_KEY_RSUPER& = 100312 'Right "Windows"key -CONST VK_KEY_MODE& = 100313 '"AltGr" key -CONST VK_KEY_COMPOSE& = 100314 -CONST VK_KEY_HELP& = 100315 -CONST VK_KEY_PRINT& = 100316 -CONST VK_KEY_SYSREQ& = 100317 -CONST VK_KEY_BREAK& = 100318 -CONST VK_KEY_MENU& = 100319 -CONST VK_KEY_POWER& = 100320 -CONST VK_KEY_EURO& = 100321 -CONST VK_KEY_UNDO& = 100322 -CONST VK_KEY_KP0& = 100256 -CONST VK_KEY_KP1& = 100257 -CONST VK_KEY_KP2& = 100258 -CONST VK_KEY_KP3& = 100259 -CONST VK_KEY_KP4& = 100260 -CONST VK_KEY_KP5& = 100261 -CONST VK_KEY_KP6& = 100262 -CONST VK_KEY_KP7& = 100263 -CONST VK_KEY_KP8& = 100264 -CONST VK_KEY_KP9& = 100265 -CONST VK_KEY_KP_PERIOD& = 100266 -CONST VK_KEY_KP_DIVIDE& = 100267 -CONST VK_KEY_KP_MULTIPLY& = 100268 -CONST VK_KEY_KP_MINUS& = 100269 -CONST VK_KEY_KP_PLUS& = 100270 -CONST VK_KEY_KP_ENTER& = 100271 -CONST VK_KEY_KP_INSERT& = 200000 -CONST VK_KEY_KP_END& = 200001 -CONST VK_KEY_KP_DOWN& = 200002 -CONST VK_KEY_KP_PAGE_DOWN& = 200003 -CONST VK_KEY_KP_LEFT& = 200004 -CONST VK_KEY_KP_MIDDLE& = 200005 -CONST VK_KEY_KP_RIGHT& = 200006 -CONST VK_KEY_KP_HOME& = 200007 -CONST VK_KEY_KP_UP& = 200008 -CONST VK_KEY_KP_PAGE_UP& = 200009 -CONST VK_KEY_KP_DELETE& = 200010 -CONST VK_KEY_SCROLL_LOCK_MODE& = 200011 -CONST VK_KEY_INSERT_MODE& = 200012 - -CONST VK_KEY_F1& = 15104 -CONST VK_KEY_F2& = 15360 -CONST VK_KEY_F3& = 15616 -CONST VK_KEY_F4& = 15872 -CONST VK_KEY_F5& = 16128 -CONST VK_KEY_F6& = 16384 -CONST VK_KEY_F7& = 16640 -CONST VK_KEY_F8& = 16896 -CONST VK_KEY_F9& = 17152 -CONST VK_KEY_F10& = 17408 -CONST VK_KEY_F11& = 34048 -CONST VK_KEY_F12& = 34304 - -CONST VK_KEY_INSERT& = 20992 -CONST VK_KEY_DELETE& = 21248 -CONST VK_KEY_HOME& = 18176 -CONST VK_KEY_END& = 20224 -CONST VK_KEY_PAGE_UP& = 18688 -CONST VK_KEY_PAGE_DOWN& = 20736 - -CONST VK_KEY_UP& = 18432 -CONST VK_KEY_DOWN& = 20480 -CONST VK_KEY_LEFT& = 19200 -CONST VK_KEY_RIGHT& = 19712 - -CONST VK_KEY_BACKSPACE& = 8 -CONST VK_KEY_TAB& = 9 - -CONST VK_KEY_ENTER& = 13 -CONST VK_KEY_ESCAPE& = 27 - -CONST VK_KEY_SPACE& = 32 -CONST VK_KEY_EXCLAMATION& = 33 -CONST VK_KEY_QUOTE& = 34 -CONST VK_KEY_HASH& = 35 -CONST VK_KEY_DOLLAR& = 36 -CONST VK_KEY_PERCENT& = 37 -CONST VK_KEY_AND& = 38 -CONST VK_KEY_APOSTROPHE& = 39 -CONST VK_KEY_OPEN_BRACKET& = 40 -CONST VK_KEY_CLOSE_BRACKET& = 41 -CONST VK_KEY_STAR& = 42 -CONST VK_KEY_PLUS& = 43 -CONST VK_KEY_COMMA& = 44 -CONST VK_KEY_MINUS& = 45 -CONST VK_KEY_DOT& = 46 -CONST VK_KEY_FORWARD_SLASH& = 47 -CONST VK_KEY_0& = 48 -CONST VK_KEY_1& = 49 -CONST VK_KEY_2& = 50 -CONST VK_KEY_3& = 51 -CONST VK_KEY_4& = 52 -CONST VK_KEY_5& = 53 -CONST VK_KEY_6& = 54 -CONST VK_KEY_7& = 55 -CONST VK_KEY_8& = 56 -CONST VK_KEY_9& = 57 -CONST VK_KEY_COLON& = 58 -CONST VK_KEY_SEMICOLON& = 59 -CONST VK_KEY_LESS_THAN& = 60 -CONST VK_KEY_EQUAL& = 61 -CONST VK_KEY_GREATER_THAN& = 62 -CONST VK_KEY_QUESTION& = 63 -CONST VK_KEY_AT& = 64 -CONST VK_KEY_A& = 65 -CONST VK_KEY_B& = 66 -CONST VK_KEY_C& = 67 -CONST VK_KEY_D& = 68 -CONST VK_KEY_E& = 69 -CONST VK_KEY_F& = 70 -CONST VK_KEY_G& = 71 -CONST VK_KEY_H& = 72 -CONST VK_KEY_I& = 73 -CONST VK_KEY_J& = 74 -CONST VK_KEY_K& = 75 -CONST VK_KEY_L& = 76 -CONST VK_KEY_M& = 77 -CONST VK_KEY_N& = 78 -CONST VK_KEY_O& = 79 -CONST VK_KEY_P& = 80 -CONST VK_KEY_Q& = 81 -CONST VK_KEY_R& = 82 -CONST VK_KEY_S& = 83 -CONST VK_KEY_T& = 84 -CONST VK_KEY_U& = 85 -CONST VK_KEY_V& = 86 -CONST VK_KEY_W& = 87 -CONST VK_KEY_X& = 88 -CONST VK_KEY_Y& = 89 -CONST VK_KEY_Z& = 90 -CONST VK_KEY_UCASE_A& = 65 -CONST VK_KEY_UCASE_B& = 66 -CONST VK_KEY_UCASE_C& = 67 -CONST VK_KEY_UCASE_D& = 68 -CONST VK_KEY_UCASE_E& = 69 -CONST VK_KEY_UCASE_F& = 70 -CONST VK_KEY_UCASE_G& = 71 -CONST VK_KEY_UCASE_H& = 72 -CONST VK_KEY_UCASE_I& = 73 -CONST VK_KEY_UCASE_J& = 74 -CONST VK_KEY_UCASE_K& = 75 -CONST VK_KEY_UCASE_L& = 76 -CONST VK_KEY_UCASE_M& = 77 -CONST VK_KEY_UCASE_N& = 78 -CONST VK_KEY_UCASE_O& = 79 -CONST VK_KEY_UCASE_P& = 80 -CONST VK_KEY_UCASE_Q& = 81 -CONST VK_KEY_UCASE_R& = 82 -CONST VK_KEY_UCASE_S& = 83 -CONST VK_KEY_UCASE_T& = 84 -CONST VK_KEY_UCASE_U& = 85 -CONST VK_KEY_UCASE_V& = 86 -CONST VK_KEY_UCASE_W& = 87 -CONST VK_KEY_UCASE_X& = 88 -CONST VK_KEY_UCASE_Y& = 89 -CONST VK_KEY_UCASE_Z& = 90 -CONST VK_KEY_OPEN_BRACKET_SQUARE& = 91 -CONST VK_KEY_BACK_SLASH& = 92 -CONST VK_KEY_CLOSE_BRACKET_SQUARE& = 93 -CONST VK_KEY_CARET& = 94 -CONST VK_KEY_UNDERSCORE& = 95 -CONST VK_KEY_REVERSE_APOSTROPHE& = 96 -CONST VK_KEY_LCASE_A& = 97 -CONST VK_KEY_LCASE_B& = 98 -CONST VK_KEY_LCASE_C& = 99 -CONST VK_KEY_LCASE_D& = 100 -CONST VK_KEY_LCASE_E& = 101 -CONST VK_KEY_LCASE_F& = 102 -CONST VK_KEY_LCASE_G& = 103 -CONST VK_KEY_LCASE_H& = 104 -CONST VK_KEY_LCASE_I& = 105 -CONST VK_KEY_LCASE_J& = 106 -CONST VK_KEY_LCASE_K& = 107 -CONST VK_KEY_LCASE_L& = 108 -CONST VK_KEY_LCASE_M& = 109 -CONST VK_KEY_LCASE_N& = 110 -CONST VK_KEY_LCASE_O& = 111 -CONST VK_KEY_LCASE_P& = 112 -CONST VK_KEY_LCASE_Q& = 113 -CONST VK_KEY_LCASE_R& = 114 -CONST VK_KEY_LCASE_S& = 115 -CONST VK_KEY_LCASE_T& = 116 -CONST VK_KEY_LCASE_U& = 117 -CONST VK_KEY_LCASE_V& = 118 -CONST VK_KEY_LCASE_W& = 119 -CONST VK_KEY_LCASE_X& = 120 -CONST VK_KEY_LCASE_Y& = 121 -CONST VK_KEY_LCASE_Z& = 122 -CONST VK_KEY_OPEN_BRACKET_CURLY& = 123 -CONST VK_KEY_VERTICAL_BAR& = 124 -CONST VK_KEY_CLOSE_BRACKET_CURLY& = 125 -CONST VK_KEY_TILDE& = 126 -CONST VK_KEY_BACKSPACE_ALTERNATE& = 127 diff --git a/source/virtual_keyboard/virtual_keyboard_keypush.bas b/source/virtual_keyboard/virtual_keyboard_keypush.bas deleted file mode 100644 index e6267e503..000000000 --- a/source/virtual_keyboard/virtual_keyboard_keypush.bas +++ /dev/null @@ -1,11 +0,0 @@ -DECLARE LIBRARY "" - SUB keydown_ascii (BYVAL keycode~&) - SUB keyup_ascii (BYVAL keycode~&) - SUB keydown_unicode (BYVAL keycode~&) - SUB keyup_unicode (BYVAL keycode~&) - SUB keydown_vk (BYVAL keycode~&) - SUB keyup_vk (BYVAL keycode~&) - 'these map directly to keydown/keyup except for unicode which remaps extended CP437 & double-width - SUB keydown (BYVAL keycode~&) - SUB keyup (BYVAL keycode~&) -END DECLARE \ No newline at end of file diff --git a/source/virtual_keyboard/virtual_keyboard_methods.bas b/source/virtual_keyboard/virtual_keyboard_methods.bas deleted file mode 100644 index 89518fe29..000000000 --- a/source/virtual_keyboard/virtual_keyboard_methods.bas +++ /dev/null @@ -1,2811 +0,0 @@ -DEFSNG A-Z - - -SUB VkResetMenu 'clears internal keys and rebuilds primary menu - -VkRemoveInternal - -i = VkByRole("ROOT") - -c = 0 -'add menu - -IF VkHide <> 0 THEN - c = c + 1 - i2 = VkNew - VkReLabel i2, "Show" - VK(i2).parent = i - VK(i2).offsetX = VkDefaultWidth * c - VK(i2).internal = 1 - VK(i2).role = "SHOW" - VK(i2).w = VkNewKeySize -ELSE - c = c + 1 - i2 = VkNew - VkReLabel i2, "Hide" - VK(i2).parent = i - VK(i2).offsetX = VkDefaultWidth * c - VK(i2).internal = 1 - VK(i2).role = "HIDE" - VK(i2).w = VkNewKeySize -END IF - - -c = c + 1 -i2 = VkNew -VkReLabel i2, "File" -VK(i2).parent = i -VK(i2).offsetX = VkDefaultWidth * c -VK(i2).internal = 1 -VK(i2).role = "FILE" -VK(i2).w = VkNewKeySize -VK(i2).locks = 1 - -c = c + 1 -i2 = VkNew -VkReLabel i2, "Edit" -VK(i2).parent = i -VK(i2).offsetX = VkDefaultWidth * c -VK(i2).internal = 1 -VK(i2).role = "EDIT" -VK(i2).w = VkNewKeySize -VK(i2).locks = 1 - -c = c + 1 -i2 = VkNew -VkReLabel i2, "Size" -VK(i2).parent = i -VK(i2).offsetX = VkDefaultWidth * c -VK(i2).internal = 1 -VK(i2).role = "SIZE" -VK(i2).w = VkNewKeySize -VK(i2).locks = 1 - -c = c + 1 -i2 = VkNew -VkReLabel i2, "Abc.." -VK(i2).parent = i -VK(i2).offsetX = VkDefaultWidth * c -VK(i2).internal = 1 -VK(i2).role = "ABC." -VK(i2).w = VkNewKeySize -VK(i2).locks = 1 - -'POSTPONED UNTIL 2ND RELEASE -'c = c + 1 -'i2 = VkNew -'VkReLabel i2, "Type" -'VK(i2).parent = i -'VK(i2).offsetX = VkDefaultWidth * c -'VK(i2).internal = 1 -'VK(i2).role = "TYPE" -'VK(i2).w = VkNewKeySize -'VK(i2).locks = 1 - -'DEPRECATED (MOUSE PIPES REMOVED THE REQUIREMENT FOR INPUT MODE SELECTION) -'c = c + 1 -'i2 = VkNew -'VkReLabel i2, "Input Mode" -'VK(i2).parent = i -'VK(i2).offsetX = VkDefaultWidth * c -'VK(i2).internal = 1 -'VK(i2).role = "IMOD" -'VK(i2).w = VkNewKeySize -'VK(i2).locks = 1 - -END SUB - - -SUB VkSelectKey (page) - -VkDefaultSelectKeyPage = page - -VkRemoveInternal - -rt = VkByRole("ROOT") - -i2 = VkNew -VK(i2).offsetX = 0 -VK(i2).offsetY = -1 * VkUnitStepY -VK(i2).parent = rt -VkReLabel i2, CHR$(26) -VK(i2).internal = 1 -VK(i2).role = "NSET" -p = page + 1 -VK(i2).state = p - -i2 = VkNew -VK(i2).offsetX = 0 -VK(i2).offsetY = -2 * VkUnitStepY -VK(i2).parent = rt -VkReLabel i2, CHR$(27) -VK(i2).internal = 1 -VK(i2).role = "PSET" -p = page - 1 -IF p < 1 THEN p = 1 -VK(i2).state = p - - -'a = -1000 - -DIM range(100, 1 TO 2) AS LONG - -r = 0 - -'key groups (first because they are more useful than individual keys) - -r = r + 1: range(r, 1) = -1001: range(r, 2) = range(r, 1) 'Set: Full KB -r = r + 1: range(r, 1) = -1000: range(r, 2) = range(r, 1) 'Set: F1-F12 -r = r + 1: range(r, 1) = -1002: range(r, 2) = range(r, 1) 'Set: Game Controller -r = r + 1: range(r, 1) = -1003: range(r, 2) = range(r, 1) 'Set: Arrow Pad -r = r + 1: range(r, 1) = -1004: range(r, 2) = range(r, 1) 'Set: WASD Pad -r = r + 1: range(r, 1) = -1005: range(r, 2) = range(r, 1) 'Set: Ins-Home-PageUp Del-End-PageDown -r = r + 1: range(r, 1) = -1006: range(r, 2) = range(r, 1) 'Set: Num Pad - - - - -'D-Pad -r = r + 1: range(r, 1) = 1000: range(r, 2) = 1004 'D-Pad - -'"safe"/essential ASCII (reordered for convenience) -r = r + 1: range(r, 1) = 97: range(r, 2) = 122 'a-z -r = r + 1: range(r, 1) = 48: range(r, 2) = 57 '0-9 -r = r + 1: range(r, 1) = 65: range(r, 2) = 90 'A-Z -r = r + 1: range(r, 1) = 32: range(r, 2) = 32 'SPACE -r = r + 1: range(r, 1) = 13: range(r, 2) = 13 'ENTER -r = r + 1: range(r, 1) = 8: range(r, 2) = 8 'BACKSPACE -r = r + 1: range(r, 1) = 9: range(r, 2) = 9 'TAB -r = r + 1: range(r, 1) = 33: range(r, 2) = 47 '" "-"/" -r = r + 1: range(r, 1) = 58: range(r, 2) = 64 '":"-"@" -r = r + 1: range(r, 1) = 91: range(r, 2) = 96 '"["-"`" -r = r + 1: range(r, 1) = 123: range(r, 2) = 126 '"{"-"~" -r = r + 1: range(r, 1) = 27: range(r, 2) = 27 'ESCAPE -r = r + 1: range(r, 1) = 1005: range(r, 2) = 1035 '(see below) -'arrow keys -'INSERT, etc -'F1-F12 -'standard modifier keys (SHIFT, ALT, etc) -'other special keys (Windows key, ...) - -'extended ASCII -r = r + 1: range(r, 1) = 127: range(r, 2) = 255 - -'"unsafe" ASCII (placed after all content to avoid confusion with arrows) -r = r + 1: range(r, 1) = 1: range(r, 2) = 7 -r = r + 1: range(r, 1) = 10: range(r, 2) = 12 -r = r + 1: range(r, 1) = 14: range(r, 2) = 26 -'r = r + 1: range(r, 1) = 28: range(r, 2) = 31-4 - - - -ranges = r -a = range(1, 1) - -FOR cpage = 1 TO page - FOR y = 0 TO -3 STEP -1 - FOR x = 1 TO 7 - - - IF cpage = page THEN - i2 = VkNew - VK(i2).offsetX = x * VkDefaultWidth + 1 - VK(i2).offsetY = y * VkUnitStepY - VK(i2).parent = rt - END IF - - IF a <= 255 AND a >= 0 THEN - - IF cpage = page THEN - VkReLabel i2, CHR$(a) - IF a = 32 THEN VkReLabel i2, "Space" - IF a = 13 THEN VkReLabel i2, "Enter" - IF a = 8 THEN VkReLabel i2, "Back Space" - IF a = 9 THEN VkReLabel i2, "Tab" - IF a = 0 THEN VkReLabel i2, "Null" - IF a = 7 THEN VkReLabel i2, "Bell" - IF a = 10 THEN VkReLabel i2, "Line Feed" - IF a = 11 THEN VkReLabel i2, "Vert Tab" - IF a = 12 THEN VkReLabel i2, "Form Feed" - IF a = 27 THEN VkReLabel i2, "Esc" - IF a = 255 THEN VkReLabel i2, "Nbsp" - VK(i2).event.keydown = a - END IF - - - - ELSE - - label$ = "?" - code = 63 - lockIsTemporary = 0 - locks = 0 - - - 'key sets - IF a = -1000 THEN label$ = "F1-F12": code = a - IF a = -1001 THEN label$ = "Full KB": code = a - IF a = -1002 THEN label$ = "Game Controller": code = a - IF a = -1003 THEN label$ = "Arrow Pad": code = a - IF a = -1004 THEN label$ = "WASD Pad": code = a - IF a = -1005 THEN label$ = "Ins-Home-PageUp Del-End-PageDown": code = a - IF a = -1006 THEN label$ = "Num Pad": code = a - - - - n = 1000 - 1 - - n = n + 1: IF a = n THEN label$ = "Virtual Joystick": code = -1 - - 'n = n + 1: IF a = n THEN label$ = CHR$(24) + "[UP-ARROW]": code = VK_KEY_UP - 'n = n + 1: IF a = n THEN label$ = CHR$(25) + "[DOWN-ARROW]": code = VK_KEY_DOWN - 'n = n + 1: IF a = n THEN label$ = CHR$(27) + "[LEFT-ARROW]": code = VK_KEY_LEFT - 'n = n + 1: IF a = n THEN label$ = CHR$(26) + "[RIGHT-ARROW]": code = VK_KEY_RIGHT - n = n + 1: IF a = n THEN label$ = CHR$(24): code = VK_KEY_UP - n = n + 1: IF a = n THEN label$ = CHR$(25): code = VK_KEY_DOWN - n = n + 1: IF a = n THEN label$ = CHR$(27): code = VK_KEY_LEFT - n = n + 1: IF a = n THEN label$ = CHR$(26): code = VK_KEY_RIGHT - - n = n + 1: IF a = n THEN label$ = "Ins": code = VK_KEY_INSERT - n = n + 1: IF a = n THEN label$ = "Del": code = VK_KEY_DELETE - n = n + 1: IF a = n THEN label$ = "Home": code = VK_KEY_HOME - n = n + 1: IF a = n THEN label$ = "End": code = VK_KEY_END - n = n + 1: IF a = n THEN label$ = "Page Up": code = VK_KEY_PAGE_UP - n = n + 1: IF a = n THEN label$ = "Page Down": code = VK_KEY_PAGE_DOWN - - - n = n + 1: IF a = n THEN label$ = "F1": code = VK_KEY_F1 - n = n + 1: IF a = n THEN label$ = "F2": code = VK_KEY_F2 - n = n + 1: IF a = n THEN label$ = "F3": code = VK_KEY_F3 - n = n + 1: IF a = n THEN label$ = "F4": code = VK_KEY_F4 - n = n + 1: IF a = n THEN label$ = "F5": code = VK_KEY_F5 - n = n + 1: IF a = n THEN label$ = "F6": code = VK_KEY_F6 - n = n + 1: IF a = n THEN label$ = "F7": code = VK_KEY_F7 - n = n + 1: IF a = n THEN label$ = "F8": code = VK_KEY_F8 - n = n + 1: IF a = n THEN label$ = "F9": code = VK_KEY_F9 - n = n + 1: IF a = n THEN label$ = "F10": code = VK_KEY_F10 - n = n + 1: IF a = n THEN label$ = "F11": code = VK_KEY_F11 - n = n + 1: IF a = n THEN label$ = "F12": code = VK_KEY_F12 - - n = n + 1 - IF a = n THEN - label$ = "Shift (Left)" - code = VK_KEY_LSHIFT - locks = 1: lockIsTemporary = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Shift (Right)" - code = VK_KEY_RSHIFT - locks = 1: lockIsTemporary = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Ctrl (Left)" - code = VK_KEY_LCTRL - locks = 1: lockIsTemporary = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Ctrl (Right)" - code = VK_KEY_RCTRL - locks = 1: lockIsTemporary = 1 - END IF - - n = n + 1 - IF a = n THEN - label$ = "Alt (Left)" - code = VK_KEY_LALT - locks = 1: lockIsTemporary = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Alt (Right)" - code = VK_KEY_RALT - locks = 1: lockIsTemporary = 1 - END IF - - n = n + 1 - IF a = n THEN - label$ = "Caps Lock" - code = VK_KEY_CAPSLOCK - locks = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Num Lock" - code = VK_KEY_NUMLOCK - locks = 1 - END IF - n = n + 1 - IF a = n THEN - label$ = "Scr Lock" - code = VK_KEY_SCROLLOCK - locks = 1 - END IF - - n = n + 1: IF a = n THEN label$ = "Win (Left)": code = VK_KEY_LSUPER - n = n + 1: IF a = n THEN label$ = "Win (Right)": code = VK_KEY_RSUPER - n = n + 1: IF a = n THEN label$ = "Apple (Left)": code = VK_KEY_LMETA - n = n + 1: IF a = n THEN label$ = "Apple (Right)": code = VK_KEY_RMETA - - 'SCREEN 2 - 'PRINT n-1 - - - - 'CONST KEY_KP0& = 100256 - 'CONST KEY_KP1& = 100257 - 'CONST KEY_KP2& = 100258 - 'CONST KEY_KP3& = 100259 - 'CONST KEY_KP4& = 100260 - 'CONST KEY_KP5& = 100261 - 'CONST KEY_KP6& = 100262 - 'CONST KEY_KP7& = 100263 - 'CONST KEY_KP8& = 100264 - 'CONST KEY_KP9& = 100265 - 'CONST KEY_KP_PERIOD& = 100266 - 'CONST KEY_KP_DIVIDE& = 100267 - 'CONST KEY_KP_MULTIPLY& = 100268 - 'CONST KEY_KP_MINUS& = 100269 - 'CONST KEY_KP_PLUS& = 100270 - 'CONST KEY_KP_ENTER& = 100271 - 'CONST KEY_KP_INSERT& = 200000 - 'CONST KEY_KP_END& = 200001 - 'CONST KEY_KP_DOWN& = 200002 - 'CONST KEY_KP_PAGE_DOWN& = 200003 - 'CONST KEY_KP_LEFT& = 200004 - 'CONST KEY_KP_MIDDLE& = 200005 - 'CONST KEY_KP_RIGHT& = 200006 - 'CONST KEY_KP_HOME& = 200007 - 'CONST KEY_KP_UP& = 200008 - 'CONST KEY_KP_PAGE_UP& = 200009 - 'CONST KEY_KP_DELETE& = 200010 - - size = LEN(label$) - - text$ = label$ - IF INSTR(text$, " ") THEN - text2$ = RIGHT$(text$, LEN(text$) - INSTR(text$, " ")) - text$ = LEFT$(text$, INSTR(text$, " ") - 1) - IF LEN(text2$) > LEN(text$) THEN size = LEN(text2$) ELSE size = LEN(text$) - END IF - - - IF size > 5 THEN - x = x + (size - 5) \ 5 + 1 - IF cpage = page THEN VK(i2).w = VkDefaultWidth + ((size - 5) \ 5 + 1) * VkDefaultWidth - END IF - - IF cpage = page THEN - VkReLabel i2, label$ - VK(i2).event.keydown = code - VK(i2).lockIsTemporary = lockIsTemporary - VK(i2).locks = locks - END IF - END IF - - IF cpage = page THEN - VK(i2).internal = 1 - VK(i2).role = "VALU" - END IF - - 'END IF - - a = a + 1 - - FOR r = 0 TO ranges - IF range(r, 2) + 1 = a THEN - IF r = ranges THEN noMore = 1 ELSE a = range(r + 1, 1) - EXIT FOR - END IF - NEXT - - IF noMore THEN EXIT SUB - - NEXT - NEXT -NEXT -END SUB - - - - -SUB VkPress (i) - - -role$ = VK(i).role - -IF role$ = "ROOT" THEN - VkAddShiftedKey = 0 - IF VK(i).locked = 0 THEN - VK(i).held = 1 - VK(i).locked = 1 - - VkResetMenu - - ELSE - 'remove all internal keys - VkRemoveInternal - VK(i).locked = 0 - END IF - EXIT SUB - -END IF - -IF role$ = "AA.." THEN - IF VkSelectedKey <> 0 THEN - IF VK(VkSelectedKey).event.keydown >= 0 THEN - VkAddShiftedKey = 0 - VkSelectKey VkDefaultSelectKeyPage - END IF - END IF - EXIT SUB -END IF - -IF role$ = "^AA." THEN - IF VkSelectedKey <> 0 THEN - IF VK(VkSelectedKey).event.keydown >= 0 THEN - VkAddShiftedKey = 1 - VkSelectKey VkDefaultSelectKeyPage - END IF - END IF - EXIT SUB -END IF - -IF role$ = "ADDK" THEN - VkSelectedKey = 0 - VkAddShiftedKey = 0 - VkSelectKey VkDefaultSelectKeyPage - EXIT SUB -END IF - -IF role$ = "DELK" THEN - i2 = VkSelectedKey - IF i2 <> 0 THEN - 'if this is a parent handle, all children need to be detached first - IF VK(i2).event.keydown = -2 THEN 'keyset handle - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).parent = 0 - VK(i3).offsetX = 0 - VK(i3).offsetY = 0 - END IF - END IF - NEXT - END IF - VkRemove i2 - VkSelectedKey = 0 - VkResetMenu - END IF - EXIT SUB -END IF - - -IF role$ = "DSET" THEN - i2 = VkSelectedKey - hasChildren = 0 - IF i2 <> 0 THEN - 'if this is a parent handle, all children need to be deleted first - IF VK(i2).event.keydown = -2 THEN 'keyset handle - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - IF VK(i3).parent = i2 THEN - VkRemove i3 - hasChildren = 1 - END IF - END IF - NEXT - END IF - IF hasChildren THEN - VkRemove i2 - VkSelectedKey = 0 - VkResetMenu - END IF - END IF - EXIT SUB -END IF - -IF role$ = "DALL" THEN - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - IF VK(i3).internal = 0 THEN - VkRemove i3 - END IF - END IF - NEXT - VkSelectedKey = 0 - VkResetMenu - EXIT SUB -END IF - -IF role$ = "EDIT" THEN - IF VK(i).locked = 1 THEN - VkResetMenu - ELSE - VkHide = 0 'do not hide keybaord when editing - VkResetMenu - i = VkByRole(role$) - VK(i).locked = 1 - - ox = VK(i).offsetX - - oy = 0 - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Add Keys" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "ADDK" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Del Key" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "DELK" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Del Set" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "DSET" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Del All" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "DALL" - VK(i2).w = VkNewKeySize - - - END IF - VkReDraw = 1 - EXIT SUB -END IF 'edit - -IF role$ = "HIDE" THEN - VkHide = -1 - VkResetMenu - VkPress VkByRole("ROOT") - EXIT SUB -END IF -IF role$ = "SHOW" THEN - VkHide = 0 - VkResetMenu - VkPress VkByRole("ROOT") - EXIT SUB -END IF - -IF role$ = "SAVE" THEN - VkSave - VkResetMenu -END IF - -IF role$ = "FILE" THEN - IF VK(i).locked = 1 THEN - VkResetMenu - ELSE - VkHide = 0 'do not hide keybaord when editing - VkResetMenu - i = VkByRole(role$) - VK(i).locked = 1 - - ox = VK(i).offsetX - oy = 0 - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Save" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "SAVE" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Reset" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "RSET" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Exit" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "EXIT" - VK(i2).w = VkNewKeySize - - END IF - VkReDraw = 1 - EXIT SUB -END IF 'FILE - -IF role$ = "EXIT" THEN - 'remove ALL keys, even root keys - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - VkRemove i3 - END IF - NEXT - VkSelectedKey = 0 - VkExiting=1 - EXIT SUB -END IF - -IF role$ = "RSET" THEN - 'remove all keys - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - IF VK(i3).internal = 0 THEN - VkRemove i3 - END IF - END IF - NEXT - VkSelectedKey = 0 - 'load default layout (if one exists) - VkFile$="" - if _FILEEXISTS(appRootPath$+"virtual_keyboard_layout_default.txt") then VkFile$=appRootPath$+"virtual_keyboard_layout_default.txt" - if VkFile$<>"" then - fh = FREEFILE - OPEN VkFile$ FOR INPUT AS #fh - LINE INPUT #fh, json$ - CLOSE #fh - root = QB_NODESET_deserialize(json$, "json") - DIM oldVkWidthInUnits AS LONG - oldVkWidthInUnits=VkWidthInUnits - VkWidthInUnits=90 - DIM rootValueNode AS LONG - rootValueNode=QB_NODE_withLabel(root, "width") - if rootValueNode then VkWidthInUnits=QB_NODE_valueOfLabel_long(root, "width") - if VkWidthInUnits<>oldVkWidthInUnits then - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - VK(i3).reDraw = 1 - END IF - NEXT - VkReset = 1 - END IF - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(root), "keys")), 0 - QB_NODE_destroy root - end if - VkResetMenu - EXIT SUB -END IF - -IF role$ = "SCUP" THEN - VkWidthInUnits=VkWidthInUnits-6 - if VkWidthInUnits<90-6*7 then VkWidthInUnits=90-6*7 - 'force all keys to be redrawn - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - VK(i3).reDraw = 1 - END IF - NEXT - VkReset = 1 - EXIT SUB -END IF - -IF role$ = "SCDN" THEN - VkWidthInUnits=VkWidthInUnits+6 - if VkWidthInUnits>90+6*20 then VkWidthInUnits=90+6*20 - 'force all keys to be redrawn - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - VK(i3).reDraw = 1 - END IF - NEXT - VkReset = 1 - EXIT SUB -END IF - -IF role$ = "BIGR" THEN - i2 = VkSelectedKey - IF i2 <> 0 THEN - IF VK(i2).event.keydown >= 0 THEN - VK(i2).w = VK(i2).w + 1 - VK(i2).reDraw = 1 - END IF - END IF - EXIT SUB -END IF - -IF role$ = "SMLR" THEN - i2 = VkSelectedKey - IF i2 <> 0 THEN - IF VK(i2).event.keydown >= 0 THEN - VK(i2).w = VK(i2).w - 1 - IF VK(i2).w < 2 THEN VK(i2).w = 2 - VK(i2).reDraw = 1 - END IF - END IF - EXIT SUB -END IF - -IF role$ = "SIZE" THEN - IF VK(i).locked = 1 THEN - VkResetMenu - ELSE - VkHide = 0 'do not hide keybaord when editing - VkResetMenu - i = VkByRole(role$) - VK(i).locked = 1 - - ox = VK(i).offsetX - - oy = 0 - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, chr$(17) + chr$(196) + chr$(196) + chr$(16) - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "BIGR" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, chr$(196) + chr$(16) + chr$(17) + chr$(196) - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "SMLR" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Scale Up" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "SCUP" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Scale Down" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "SCDN" - VK(i2).w = VkNewKeySize - - END IF - VkReDraw = 1 - EXIT SUB -END IF 'SIZE - - - -IF role$ = "ABC." THEN - IF VK(i).locked = 1 THEN - VkResetMenu - ELSE - VkHide = 0 'do not hide keybaord when editing - VkResetMenu - i = VkByRole(role$) - VK(i).locked = 1 - - ox = VK(i).offsetX - - oy = 0 - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Aa..." - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "AA.." - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Aa... ^^" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "^AA." - VK(i2).w = VkNewKeySize - - END IF - VkReDraw = 1 - EXIT SUB -END IF 'ABC. - - -IF role$ = "TYPE" THEN - IF VK(i).locked = 1 THEN - VkResetMenu - ELSE - VkHide = 0 'do not hide keybaord when editing - VkResetMenu - i = VkByRole(role$) - VK(i).locked = 1 - - ox = VK(i).offsetX - - oy = 0 - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Locks" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "LOCK" - VK(i2).w = VkNewKeySize - - oy = oy + 1 - i2 = VkNew - VkReLabel i2, "Waits Press" - VK(i2).parent = VK(i).parent - VK(i2).offsetX = ox - VK(i2).offsetY = -oy * VkUnitStepY - VK(i2).internal = 1 - VK(i2).role = "STKY" - VK(i2).w = VkNewKeySize - - END IF - VkReDraw = 1 - EXIT SUB -END IF 'TYPE - - - -'IF role$ = "IMOD" THEN -' IF VK(i).locked = 1 THEN -' VkResetMenu -' ELSE -' VkResetMenu -' i = VkByRole(role$) -' VK(i).locked = 1 -' ox = VK(i).offsetX -' oy = 0 -' -' oy = oy + 1 -' i2 = VkNew -' VkReLabel i2, "Share Input" -' VK(i2).parent = VK(i).parent -' VK(i2).offsetX = ox -' VK(i2).offsetY = -oy * VkUnitStepY -' VK(i2).internal = 1 -' VK(i2).locks = 1 -' IF VkSharedInputMode <> 0 THEN VK(i2).locked = 1 -' VK(i2).role = "IMSH" -' VK(i2).w = VkNewKeySize -' -' oy = oy + 1 -' i2 = VkNew -' VkReLabel i2, "Excl- usive" -' VK(i2).parent = VK(i).parent -' VK(i2).offsetX = ox -' VK(i2).offsetY = -oy * VkUnitStepY -' VK(i2).internal = 1 -' VK(i2).locks = 1 -' IF VkSharedInputMode = 0 THEN VK(i2).locked = 1 -' VK(i2).role = "IMEX" -' VK(i2).w = VkNewKeySize -' -' END IF -' VkReDraw = 1 -' EXIT SUB -'END IF 'TYPE - -'IF role$ = "IMSH" THEN -' i3 = VkByRole("IMSH") -' VK(i3).locked = 1 -' i3 = VkByRole("IMEX") -' VK(i3).locked = 0 -' VkSharedInputMode = -1 -' VkReDraw = 1 -' DO WHILE func__mouseinput_exclusive: LOOP -' DO WHILE _MOUSEINPUT: LOOP -' mouseinput_mode 0 -' EXIT SUB -'END IF - -'IF role$ = "IMEX" THEN -' i3 = VkByRole("IMSH") -' VK(i3).locked = 0 -' i3 = VkByRole("IMEX") -' VK(i3).locked = 1 -' VkSharedInputMode = 0 -' VkReDraw = 1 -' DO WHILE func__mouseinput_exclusive: LOOP -' DO WHILE _MOUSEINPUT: LOOP -' mouseinput_mode 1 -' EXIT SUB -'END IF - -IF VK(i).role = "NSET" OR VK(i).role = "PSET" THEN - page = VK(i).state - VkSelectKey page - EXIT SUB -END IF - -IF VK(i).role = "USER" THEN - rt = VkByRole("ROOT") - IF VK(rt).locked <> 0 THEN - - 'select key - VkSelectedKey = i - VkReDraw = 1 - EXIT SUB - - END IF - - EXIT SUB -END IF - - -IF VK(i).role = "VALU" THEN - - - i3 = VkByRole("ROOT") - - IF VK(i).event.keydown <= -1000 THEN 'Full KB - 'add parent (handle) key - i2 = VkNew - VK(i2).x = VK(i3).x + VkDefaultWidth * 0 + 1 - VK(i2).y = VK(i3).y - VkDefaultWidth * 1 - VkReLabel i2, CHR$(240) - VK(i2).role = "USER" - VK(i2).h = CINT(VkUnitStepY / 2) - VK(i2).event.keydown = -2 'a "keySet" - END IF - - - IF VK(i).event.keydown = -1004 THEN 'WASD Pad - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qa\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_D\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qw\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_W\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qs\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_S\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 1 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - - - IF VK(i).event.keydown = -1003 THEN 'Arrow Pad - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2192\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2190\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LEFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2193\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2191\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UP\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 1 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - - 'Ins-Home-PageUp Del-End-PageDown - IF VK(i).event.keydown = -1005 THEN 'Ins-Home-PageUp Del-End-PageDown - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qPage Down\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PAGE_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qPage Up\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PAGE_UP\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qEnd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_END\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qHome\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_HOME\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qDel\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DELETE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qIns\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_INSERT\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 2 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - IF VK(i).event.keydown = -1006 THEN 'Num Pad - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_5\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_4\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_3\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_1\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:12,\qheight\q:6,\qlabel\q:\q0\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_0\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_6\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_7\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_8\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q/\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_FORWARD_SLASH\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q*\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_STAR\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:12,\qlabel\q:\q+\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PLUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q-\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_MINUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qBack Space\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACKSPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:12,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_9\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q.\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOT\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 5 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - - - - - IF VK(i).event.keydown = -1002 THEN 'Game Controller - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:70,\qoffsetY\q:18,\qwidth\q:20,\qheight\q:6,\qlabel\q:\qR\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_R\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:20,\qheight\q:6,\qlabel\q:\qL\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_L\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:0,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qB\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_B\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qA\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:12,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qX\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_X\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:70,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qY\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UCASE_Y\q}}},{\qtype\q:\qjoystick\q,\qoffsetX\q:6,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qVirtual Joystick\q,\qevents\q:{\qup\q:{\qkeyCode\q:\qKEY_UP\q},\qdown\q:{\qkeyCode\q:\qKEY_DOWN\q},\qleft\q:{\qkeyCode\q:\qKEY_LEFT\q},\qright\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:33,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qSpace\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 4 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - - IF VK(i).event.keydown = -1001 THEN 'Full KB - 'no shifted characters: - 'json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q`\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_REVERSE_APOSTROPHE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_1\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:9,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qq\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Q\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:15,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qw\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_W\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:21,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qe\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_E\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:27,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qr\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_R\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:33,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qt\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_T\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:39,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qy\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Y\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:45,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qu\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_U\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:51,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qi\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_I\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:57,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qo\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_O\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:63,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qp\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_P\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:69,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q[\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_OPEN_BRACKET_SQUARE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q]\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_CLOSE_BRACKET_SQUARE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:11,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qa\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_A\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:17,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qs\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_S\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:23,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_D\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:29,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qf\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_F\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:35,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qg\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_G\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:41,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qh\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_H\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:47,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qj\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_J\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:53,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qk\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_K\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:59,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\ql\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_L\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:65,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q;\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SEMICOLON\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:71,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q'\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_APOSTROPHE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:81,\qoffsetY\q:18,\qwidth\q:9,\qheight\q:6,\qlabel\q:\q\\\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACK_SLASH\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:77,\qoffsetY\q:12,\qwidth\q:13,\qheight\q:6,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:14,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qz\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Z\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:20,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qx\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_X\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:26,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qc\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_C\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:32,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qv\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_V\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:38,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qb\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_B\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:44,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qn\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_N\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:50,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qm\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_M\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:56,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q,\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_COMMA\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:62,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q.\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:68,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q/\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_FORWARD_SLASH\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:74,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2191\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UP\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2192\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:68,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2190\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LEFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:74,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2193\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qShift\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RSHIFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:59,\qoffsetY\q:0,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qAlt\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RALT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:17,\qoffsetY\q:0,\qwidth\q:8,\qheight\q:6,\qlabel\q:\qAlt\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LALT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:9,\qoffsetY\q:0,\qwidth\q:8,\qheight\q:6,\qlabel\q:\q\u2302\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LSUPER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qCtrl\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCTRL\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:24,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_4\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_3\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:30,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_5\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:36,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_6\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:42,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_7\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_8\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:54,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_9\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:60,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q0\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_0\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:66,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q-\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_MINUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:72,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q=\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_EQUAL\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:84,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qBack Space\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACKSPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:78,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q+\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_PLUS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qTab\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_TAB\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:12,\qwidth\q:11,\qheight\q:6,\qlabel\q:\qCaps Lock\q,\qlocks\q:true,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_CAPSLOCK\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:14,\qheight\q:6,\qlabel\q:\qShift\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LSHIFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:86,\qoffsetY\q:0,\qwidth\q:4,\qheight\q:6,\qlabel\q:\qEsc\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ESCAPE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:25,\qoffsetY\q:0,\qwidth\q:34,\qheight\q:6,\qlabel\q:\q\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SPACE\q}}}]}" - 'with shifted characters: - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q`\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_REVERSE_APOSTROPHE\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_TILDE\q,\qlabel\q:\q~\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_1\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_EXCLAMATION\q,\qlabel\q:\q!\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:9,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qq\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Q\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_Q\q,\qlabel\q:\qQ\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:15,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qw\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_W\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_W\q,\qlabel\q:\qW\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:21,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qe\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_E\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_E\q,\qlabel\q:\qE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:27,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qr\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_R\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_R\q,\qlabel\q:\qR\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:33,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qt\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_T\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_T\q,\qlabel\q:\qT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:39,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qy\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Y\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_Y\q,\qlabel\q:\qY\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:45,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qu\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_U\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_U\q,\qlabel\q:\qU\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:51,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qi\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_I\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_I\q,\qlabel\q:\qI\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:57,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qo\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_O\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_O\q,\qlabel\q:\qO\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:63,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qp\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_P\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_P\q,\qlabel\q:\qP\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:69,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q[\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_OPEN_BRACKET_SQUARE\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_OPEN_BRACKET_CURLY\q,\qlabel\q:\q{\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:75,\qoffsetY\q:18,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q]\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_CLOSE_BRACKET_SQUARE\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_CLOSE_BRACKET_CURLY\q,\qlabel\q:\q}\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_2\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_AT\q,\qlabel\q:\q@\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:11,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qa\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_A\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_A\q,\qlabel\q:\qA\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:17,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qs\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_S\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_S\q,\qlabel\q:\qS\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:23,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qd\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_D\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_D\q,\qlabel\q:\qD\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:29,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qf\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_F\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_F\q,\qlabel\q:\qF\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:35,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qg\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_G\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_G\q,\qlabel\q:\qG\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:41,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qh\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_H\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_H\q,\qlabel\q:\qH\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:47,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qj\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_J\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_J\q,\qlabel\q:\qJ\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:53,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qk\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_K\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_K\q,\qlabel\q:\qK\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:59,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\ql\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_L\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_L\q,\qlabel\q:\qL\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:65,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q;\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SEMICOLON\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_COLON\q,\qlabel\q:\q:\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:71,\qoffsetY\q:12,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q'\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_APOSTROPHE\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_QUOTE\q,\qlabel\q:\q\\q\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:81,\qoffsetY\q:18,\qwidth\q:9,\qheight\q:6,\qlabel\q:\q\\\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACK_SLASH\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_VERTICAL_BAR\q,\qlabel\q:\q|\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:77,\qoffsetY\q:12,\qwidth\q:13,\qheight\q:6,\qlabel\q:\qEnter\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ENTER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:14,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qz\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_Z\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_Z\q,\qlabel\q:\qZ\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:20,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qx\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_X\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_X\q,\qlabel\q:\qX\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:26,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qc\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_C\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_C\q,\qlabel\q:\qC\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:32,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qv\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_V\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_V\q,\qlabel\q:\qV\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:38,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qb\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_B\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_B\q,\qlabel\q:\qB\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:44,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qn\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_N\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_N\q,\qlabel\q:\qN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:50,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qm\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCASE_M\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UCASE_M\q,\qlabel\q:\qM\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:56,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q,\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_COMMA\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_LESS_THAN\q,\qlabel\q:\q<\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:62,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q.\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOT\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_GREATER_THAN\q,\qlabel\q:\q>\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:68,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q/\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_FORWARD_SLASH\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_QUESTION\q,\qlabel\q:\q?\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:74,\qoffsetY\q:6,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2191\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_UP\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2192\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RIGHT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:68,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2190\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LEFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:74,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q\u2193\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_DOWN\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:80,\qoffsetY\q:6,\qwidth\q:10,\qheight\q:6,\qlabel\q:\qShift\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RSHIFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:59,\qoffsetY\q:0,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qAlt\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_RALT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:17,\qoffsetY\q:0,\qwidth\q:8,\qheight\q:6,\qlabel\q:\qAlt\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LALT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:9,\qoffsetY\q:0,\qwidth\q:8,\qheight\q:6,\qlabel\q:\q\u2302\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LSUPER\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qCtrl\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LCTRL\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:24,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_4\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_DOLLAR\q,\qlabel\q:\q$\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_3\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_HASH\q,\qlabel\q:\q#\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:30,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_5\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_PERCENT\q,\qlabel\q:\q%\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:36,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_6\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_CARET\q,\qlabel\q:\q^\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:42,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_7\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_AND\q,\qlabel\q:\q&\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_8\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_STAR\q,\qlabel\q:\q*\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:54,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_9\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_OPEN_BRACKET\q,\qlabel\q:\q(\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:60,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q0\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_0\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_CLOSE_BRACKET\q,\qlabel\q:\q)\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:66,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q-\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_MINUS\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_UNDERSCORE\q,\qlabel\q:\q_\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:72,\qoffsetY\q:24,\qwidth\q:6,\qheight\q:6,\qlabel\q:\q=\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_EQUAL\q},\qkeydownWithShift\q:{\qkeyCode\q:\qKEY_PLUS\q,\qlabel\q:\q+\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:78,\qoffsetY\q:24,\qwidth\q:12,\qheight\q:6,\qlabel\q:\qBack Space\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_BACKSPACE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:18,\qwidth\q:9,\qheight\q:6,\qlabel\q:\qTab\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_TAB\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:12,\qwidth\q:11,\qheight\q:6,\qlabel\q:\qCaps Lock\q,\qlocks\q:true,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_CAPSLOCK\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:6,\qwidth\q:14,\qheight\q:6,\qlabel\q:\qShift\q,\qlocks\q:true,\qlockIsTemporary\q:true,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_LSHIFT\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:86,\qoffsetY\q:0,\qwidth\q:4,\qheight\q:6,\qlabel\q:\qEsc\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_ESCAPE\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:25,\qoffsetY\q:0,\qwidth\q:34,\qheight\q:6,\qlabel\q:\q\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_SPACE\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 5 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - IF VK(i).event.keydown = -1000 THEN 'F1-F12 - json$ = "{\qkeys\q:[{\qtype\q:\qkey\q,\qoffsetX\q:66,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF12\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F12\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:60,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF11\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F11\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:54,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF10\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F10\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:48,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF9\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F9\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:42,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF8\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F8\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:36,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF7\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F7\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:30,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF6\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F6\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:24,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF5\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F5\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:18,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF4\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F4\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:12,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF3\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F3\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:6,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF2\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F2\q}}},{\qtype\q:\qkey\q,\qoffsetX\q:0,\qoffsetY\q:0,\qwidth\q:6,\qheight\q:6,\qlabel\q:\qF1\q,\qlocks\q:false,\qlockIsTemporary\q:false,\qevents\q:{\qkeydown\q:{\qkeyCode\q:\qKEY_F1\q}}}]}" - keyset = QB_NODESET_deserialize(VkGetQuotedString(json$), "json") - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(keyset), "keys")), i2 - FOR i3 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i3).parent = i2 THEN - VK(i3).offsetY = VK(i3).offsetY - VkDefaultWidth * 1 - END IF - END IF - NEXT - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - VkSelectedKey = i2 - EXIT SUB - END IF - - addingNewKey = 0 - IF VkSelectedKey <> 0 THEN - i2 = VkSelectedKey - ELSE - addingNewKey = 1 - i2 = VkNew - VK(i2).x = VK(i3).x + VkDefaultWidth * 0 + 1 - VK(i2).y = VK(i3).y - VkDefaultWidth * 1 - END IF - - - - ' hasShiftedEvent AS LONG - ' shiftedEvent AS VKEY_EVENT 'eg. when shifted or caps lock is on - ' shiftedLabel AS STRING * 100 - 'VkAddShiftedKey - - label$ = RTRIM$(VK(i).label) - IF INSTR(label$, " (") > 1 AND INSTR(label$, ")") > 1 THEN - 'strip meta info - label$ = LEFT$(label$, INSTR(label$, " (") - 1) - END IF - - IF VkAddShiftedKey THEN - VkAddShiftedKey = 0 - VK(i2).hasShiftedEvent = 1 - VkReLabelShifted i2, label$ - VK(i2).shiftedEvent.keydown = VK(i).event.keydown - ELSE - VkReLabel i2, label$ - VK(i2).event.keydown = VK(i).event.keydown - VK(i2).locks = VK(i).locks - VK(i2).lockIsTemporary = VK(i).lockIsTemporary - END IF - - 'for a-z & A-Z automatically add their shifted key codes - IF addingNewKey <> 0 AND VkAddShiftedKey = 0 THEN - keyCode = VK(i).event.keydown - shiftedKeyCode = keyCode - IF keyCode >= 97 AND keyCode <= 122 THEN shiftedKeyCode = keyCode - 32 - IF keyCode >= 65 AND keyCode <= 90 THEN shiftedKeyCode = keyCode + 32 - IF shiftedKeyCode <> keyCode THEN - VK(i2).hasShiftedEvent = 1 - VK(i2).shiftedEvent.keydown = shiftedKeyCode - VK(i2).shiftedLabel = CHR$(shiftedKeyCode) - END IF - END IF - - VK(i2).role = "USER" - - VkPress (VkByRole("ROOT")) - VkPress (VkByRole("ROOT")) - - VkSelectedKey = i2 - EXIT SUB -END IF - -END SUB - -FUNCTION VkNew -VkReDraw = 1 -i2 = 0 -FOR i = 1 TO VkLast - IF VK(i).active = 0 THEN - i2 = i - END IF -NEXT -IF i2 = 0 THEN i2 = i: VkLast = i -i = i2 -VK(i) = VkEmpty -VK(i).active = 1 -VK(i).x = 0 -VK(i).y = 0 -VK(i).w = VkDefaultWidth -VK(i).h = VkUnitStepY -VK(i).role = "UNKN" -VkNew = i -END FUNCTION - -SUB VkRemove (i) -VkReDraw = 1 -VK(i).active = 0 -IF VK(i).image THEN _FREEIMAGE VK(i).image -IF VK(i).subImage THEN _FREEIMAGE VK(i).subImage -IF VK(i).highlightImage THEN _FREEIMAGE VK(i).highlightImage -IF VK(i).selectedImage THEN _FREEIMAGE VK(i).selectedImage -END SUB - -SUB VkRemoveInternal -FOR i = 1 TO VkLast - IF VK(i).active THEN - IF VK(i).internal THEN - IF VK(i).role <> "ROOT" THEN - VkRemove i - END IF - END IF - END IF -NEXT -END SUB - -FUNCTION VkByRole (role$) -FOR i = 1 TO VkLast - IF VK(i).active = 1 THEN - IF VK(i).role = role$ THEN VkByRole = i: EXIT FUNCTION - END IF -NEXT -END FUNCTION - -SUB VkLongPress (i) -'avoid using long press for now because Windows delays MOUSEDOWN to MOUSEUP on touch -VkPress i -END SUB - -SUB VkKeyRepeat (i) -keydown VK(i).keyRepeatKeyCode -VK(i).lastKeydownTime = TIMER -VK(i).keyRepeatCount = VK(i).keyRepeatCount + 1 -END SUB - -SUB VkKeyDown (i) -VkReDraw = 1 -'called whenever user key down -IF VK(i).internal = 0 THEN - rt = VkByRole("ROOT") - IF VK(rt).locked = 0 THEN 'not in edit mode - - - keydownvalue = VK(i).event.keydown - IF VK(i).hasShiftedEvent THEN - IF VkShiftInEffect THEN keydownvalue = VK(i).shiftedEvent.keydown - END IF - - IF keydownvalue <> 0 THEN - - IF VK(i).locks <> 0 OR VK(i).lockIsTemporary <> 0 THEN - - IF VK(i).locked <> 0 THEN - keyup keydownvalue - VK(i).locked = 0 - VK(i).held = 0 - ELSE - keydown keydownvalue - VK(i).locked = 1 - VK(i).held = 1 - END IF - ELSE - VK(i).held = 1 - keydown keydownvalue - VK(i).lastKeydownTime = TIMER - VK(i).keyRepeatKeyCode = keydownvalue - VK(i).keyRepeatCount = 0 - END IF - END IF - END IF - - IF VK(i).locks = 0 THEN - FOR i2 = 1 TO VkLast - IF VK(i2).active THEN - IF VK(i2).internal = 0 THEN - IF i <> i2 THEN - IF VK(i2).locks THEN - IF VK(i2).locked THEN - IF VK(i2).lockIsTemporary THEN - VkKeyDown i2 - END IF - END IF - END IF - END IF - END IF - END IF - NEXT - END IF - -ELSE - VK(i).held = 1 -END IF - - - - - - -END SUB - -SUB VkKeyUp (i) -VkReDraw = 1 -'called whenever user key down -IF VK(i).internal = 0 THEN - rt = VkByRole("ROOT") - IF VK(rt).locked = 0 THEN 'not in edit mode - - - keydownvalue = VK(i).event.keydown - IF VK(i).hasShiftedEvent THEN - IF VkShiftInEffect THEN keydownvalue = VK(i).shiftedEvent.keydown - END IF - - - IF keydownvalue <> 0 THEN - IF VK(i).locks <> 0 OR VK(i).lockIsTemporary <> 0 THEN - 'do nothing - ELSE - keyup keydownvalue - VK(i).held = 0 - END IF - END IF - END IF -ELSE - VK(i).held = 0 -END IF -END SUB - -SUB VkUpdate - -if VkDelay>0 then - VkTimeNow#=TIMER(0.001) - if VkTimeNow#=VkDelayStartTime+VkDelay THEN VkDelay=0 - exit sub -end if - -if vkExited then - DO WHILE _MOUSEINPUT(VkMousePipe) - _MOUSEINPUTPIPE VkMousePipe - LOOP - exit sub -end if - -if VkExiting=1 then VkExiting=2 - -subOldDest = _DEST -subOldSource = _SOURCE - -reDraw = VkReDraw -VkReDraw = 0 - -IF reDraw THEN - 'SOUND 1000, .1 -END IF - -STATIC VkI -STATIC VKoldX -STATIC VKoldY -STATIC VKdragging -STATIC VKstart - -STATIC mDownX -STATIC mDownY -STATIC omb - -STATIC mb, mx, my - -STATIC sx, sy - -STATIC VkInit - -'theme colors -'for user keys: -textCol& = _RGBA32(255, 255, 255, 192) -borderCol& = _RGBA32(32, 32, 32, 192) -borderSelectedCol& = _RGBA32(255, 255, 255, 192) -bgCol& = _RGBA32(96, 96, 96, 128) -bgHighlightCol& = _RGBA32(128, 128, 128, 128) - - -'for customization: -InternalTextCol& = _RGBA32(255, 255, 255, 255) -InternalBorderCol& = _RGBA32(255, 255, 255, 192) -InternalBgCol& = _RGBA32(0, 0, 0, 192) -InternalBgHighlightCol& = _RGBA32(128, 128, 128, 128) - -'Init is done once -IF VkInit = 0 THEN - VkWidthInUnits = 90 'default width in units (may be changed by loading a layout) - VkReset = 1 -END IF - -winX = _SCALEDWIDTH -winY = _SCALEDHEIGHT - -IF winX <> VkWinX OR winY <> VkWinY THEN - 'store new resolution - VkWinX = winX - VkWinY = winY - 'clear overlay image (if one exists yet) - if VkOverlay then - _PUTIMAGE , VkClearTex, VkOverlay - end if - 'beging a delay (wait until screen has fully repositioned) - VkDelayStartTime=TIMER(0.001) - VkDelay=1 - VkDelayedReset=1 - exit sub -END IF - -if VkDelayedReset=1 then - VkDelayedReset=0 - VkReset = 1 -end if - -'Reset occurs whenever the screen size changes -IF VkReset = 1 THEN - VkReset = 0 - - 'get new dimensions - VkWinX = winX - VkWinY = winY - - 'PRINT winX, winY - ' END - - sx = VkWinX: sy = VkWinY 'shortcuts - - 'we need to free the old overlay & backbuffer, but because they might be - 'in use we cannot do it immediately - VkOverlay32 = _NEWIMAGE(VkWinX, VkWinY, 32) - VkOverlay = _COPYIMAGE(VkOverlay32, 33) - VkBackbuffer = _COPYIMAGE(VkOverlay32, 33) - _FREEIMAGE VkOverlay32 - - VkUnitSize = sx / VkWidthInUnits - - h = CINT(VkUnitStepY * VkUnitSize * 0.5) - - - 'VkFont = _LOADFONT("c:\windows\fonts\lucon.ttf", CINT(h)) - 'VkFontSmall = _LOADFONT("c:\windows\fonts\lucon.ttf", CINT(h * 0.5)) - - - 'generic textures - - VkReDraw = 1 - FOR i = 1 TO VkLast - IF VK(i).active THEN - VK(i).reDraw = 1 - END IF - NEXT - -END IF 'reset - -IF VkInit = 0 THEN - - VkClearTex = VkColTex(_RGBA32(0, 0, 0, 0)): _DONTBLEND VkClearTex - - i = VkNew - VK(i).x = 0 'VkDefaultWidth - VK(i).y = VkUnitStepY * 4 '*** do not modify or scaled up keybaord will be off screen*** - VK(i).w = VkDefaultWidth - VK(i).h = VkUnitStepY - VK(i).role = "ROOT" - VK(i).internal = 1 - VK(i).locks = 1 - VkReLabel i, "KB" 'CHR$(15) - - VkLoad - -END IF - -VkInit = 1 - -IF reDraw THEN - - 'clear backbuffer - _DONTBLEND VkBackbuffer - _PUTIMAGE , VkClearTex, VkBackbuffer - _BLEND VkBackbuffer - - 'correct offsets of keys relative to parents - FOR i = 1 TO VkLast - IF VK(i).active THEN - p = VK(i).parent - IF p THEN - VK(i).x = VK(p).x + VK(i).offsetX - VK(i).y = VK(p).y + VK(i).offsetY - END IF - END IF - NEXT - - rt = VkByRole("ROOT") - - shiftInEffect = VkShiftInEffect - 'render keys - FOR internal = 0 TO 1 - FOR i = 1 TO VkLast - IF VK(i).active THEN - IF VK(i).internal = internal AND (VK(i).event.keydown <> -2 OR VK(rt).locked <> 0) and (internal=1 or vkHide=0) THEN - x = VK(i).x * VkUnitSize - y = VK(i).y * VkUnitSize - w = VK(i).w - h = VK(i).h - x1 = INT(x) - x2 = INT(x + VkUnitSize * w) - 1 - y1 = sy - 1 - INT(y) - y2 = sy - 1 - INT(y + VkUnitSize * h) + 1 - w2 = x2 - x1 + 1 'pixel metrics - h2 = y1 - y2 + 1 - - 'get key colors - cText& = textCol& - cBorder& = borderCol& - cBg& = bgCol& - cBgHighlight& = bgHighlightCol& - IF VK(i).internal THEN - cText& = InternalTextCol& - cBorder& = InternalBorderCol& - cBg& = InternalBgCol& - cBgHighlight& = InternalBgHighlightCol& - END IF - - - IF VK(i).event.keydown = -1 AND VK(i).internal = 0 THEN 'D-PAD - - 're-calculate dimensions - x = (VK(i).x - VkDefaultWidth) * VkUnitSize - y = (VK(i).y - VkUnitStepY) * VkUnitSize - w = VK(i).w * 3 - h = VK(i).h * 3 - x1 = INT(x) - x2 = INT(x + VkUnitSize * w) - 1 - y1 = sy - 1 - INT(y) - y2 = sy - 1 - INT(y + VkUnitSize * h) + 1 - w2 = x2 - x1 + 1 'pixel metrics - h2 = y1 - y2 + 1 - - create = 0 - - IF VK(i).image <> 0 AND create = 0 THEN - 'has required size changed? - iw = _WIDTH(VK(i).image) - ih = _HEIGHT(VK(i).image) - IF iw <> w2 OR ih <> h2 THEN - create = 1 - END IF - END IF - - IF VK(i).reDraw THEN VK(i).reDraw = 0: create = 1 - - IF create THEN - 'invalidate - IF VK(i).image <> 0 THEN _FREEIMAGE VK(i).image: VK(i).image = 0 - IF VK(i).subImage <> 0 THEN _FREEIMAGE VK(i).subImage: VK(i).subImage = 0 - END IF - - IF VK(i).image = 0 THEN - 'soft render base - defKey = _NEWIMAGE(w2, h2, 32) - _DEST defKey - _DONTBLEND - dpcx = w2 \ 2: dpcy = h2 \ 2 - dprad = w2 \ 2 - 3 - CIRCLE (dpcx, dpcy), dprad, _RGBA32(255, 255, 255, 255) - PAINT (dpcx, dpcy), cBg&, _RGBA32(255, 255, 255, 255) - 'CIRCLE (dpcx, dpcy), dprad, _RGBA32(_RED32(cBg&), _GREEN32(cBg&), _BLUE32(cBg&), _ALPHA32(cBg&) * 0.75) - a = _ALPHA32(cBg&) - FOR r = dprad TO dprad + 10 STEP 0.15 - a = a - 10 - IF a < 0 THEN EXIT FOR - CIRCLE (dpcx, dpcy), r, _RGBA32(_RED32(cBg&), _GREEN32(cBg&), _BLUE32(cBg&), a) - NEXT - _BLEND - 'conv to hw - VK(i).image = _COPYIMAGE(defKey, 33) - _FREEIMAGE defKey - 'soft render stick - defKey = _NEWIMAGE(w2, h2, 32) - _DEST defKey - _DONTBLEND - dprad = dprad / 2.5 - CIRCLE (dpcx, dpcy), dprad, _RGBA32(255, 255, 255, 255) - PAINT (dpcx, dpcy), _RGBA32(255, 255, 255, 128), _RGBA32(255, 255, 255, 255) - a = 128 - FOR r = dprad TO dprad + 10 STEP 0.15 - a = a - 10 - IF a < 0 THEN EXIT FOR - CIRCLE (dpcx, dpcy), r, _RGBA32(255, 255, 255, a) - NEXT - _BLEND - 'conv to hw - VK(i).subImage = _COPYIMAGE(defKey, 33) - _FREEIMAGE defKey - END IF - - dpadx = VK(i).dpad.x: dpady = VK(i).dpad.y - IF VkHide = 0 OR VK(i).internal <> 0 THEN - _PUTIMAGE (x1, y2), VK(i).image, VkBackbuffer - _PUTIMAGE (x1 + dpadx * VkUnitSize * VkDefaultWidth * 0.89, y2 + dpady * VkUnitSize * VkDefaultWidth * 0.89), VK(i).subImage, VkBackbuffer - END IF - - GOTO special_key - END IF - - - - - 'standard key - create = 0 - - IF VK(i).image <> 0 AND create = 0 THEN - 'has required size changed? - iw = _WIDTH(VK(i).image) - ih = _HEIGHT(VK(i).image) - IF iw <> w2 OR ih <> h2 THEN - create = 1 - END IF - END IF - - IF VK(i).reDraw THEN VK(i).reDraw = 0: create = 1 - - IF create THEN - 'invalidate - IF VK(i).image <> 0 THEN _FREEIMAGE VK(i).image: VK(i).image = 0 - IF VK(i).highlightImage <> 0 THEN _FREEIMAGE VK(i).highlightImage: VK(i).highlightImage = 0 - IF VK(i).selectedImage <> 0 THEN _FREEIMAGE VK(i).selectedImage: VK(i).selectedImage = 0 - END IF - - IF VK(i).image = 0 THEN - 'soft render default key - - FOR shiftedPass = 0 TO 1 - IF shiftedPass = 0 OR (shiftedPass = 1 AND VK(i).hasShiftedEvent <> 0) THEN - FOR pass = 1 TO 3 - defKey = _NEWIMAGE(w2, h2, 32) - _DEST defKey - _DONTBLEND - - IF pass <> 2 THEN LINE (0, 0)-(w2 - 1, h2 - 1), cBg&, BF - IF pass = 2 THEN LINE (0, 0)-(w2 - 1, h2 - 1), cBgHighlight&, BF - - IF pass <> 3 THEN - LINE (0, 0)-(w2 - 1, h2 - 1), cBorder&, B - ELSE - LINE (0, 0)-(w2 - 1, h2 - 1), borderSelectedCol&, B - END IF - - _BLEND - - 'add text - - 'convert label to image - text$ = RTRIM$(VK(i).label) - IF shiftedPass THEN text$ = RTRIM$(VK(i).shiftedLabel) - - text2$ = "" - - IF text$ <> "" THEN - - lines = 1 - IF INSTR(text$, " ") THEN - lines = 2 - text2$ = RIGHT$(text$, LEN(text$) - INSTR(text$, " ")) - text$ = LEFT$(text$, INSTR(text$, " ") - 1) - END IF - - defKeyHeightInPixels = VkUnitStepY * VkUnitSize - '42.6 for screen 0 80x25 - font = VkFindFont(INT(defKeyHeightInPixels / 2)) 'ideally 20 for 80x25 - IF lines = 2 OR LEN(text$) >= 2 AND text$ <> "KB" THEN - font = VkFindFont(INT(defKeyHeightInPixels / 3.5)) 'ideally 12 for 80x25 - END IF - - _FONT font - - cw = _PRINTWIDTH(text$) - IF lines = 2 THEN - cw2 = _PRINTWIDTH(text2$) - IF cw2 > cw THEN cw = cw2 - END IF - ch = _FONTHEIGHT - IF cw <> 0 AND ch <> 0 THEN - - ox = w2 \ 2 - cw \ 2 - oy = h2 \ 2 - (ch * lines) \ 2 - - ' _PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2), ci33, VkBackbuffer - - _PRINTMODE _KEEPBACKGROUND - COLOR cText& - _CONTROLCHR OFF - _PRINTSTRING (ox, oy), text$ - IF text2$ <> "" THEN _PRINTSTRING (ox, oy + ch), text2$ - _CONTROLCHR ON - - - - END IF 'cw <> 0 AND ch <> 0 - END IF 'text$<>"" - - - - ' _FONT font - ' cw = _PRINTWIDTH(text$) - ' IF lines = 2 THEN - ' cw2 = _PRINTWIDTH(text2$) - ' IF cw2 > cw THEN cw = cw2 - ' END IF - ' ch = _FONTHEIGHT - - - - - ' ' GOTO 1 - ' IF cw = 0 OR ch = 0 THEN GOTO 1 - - - - - ' ci = _NEWIMAGE(cw, ch * lines, 32) - ' _DEST ci - ' _FONT font - ' _PRINTMODE _KEEPBACKGROUND - ' COLOR textCol& - ' _CONTROLCHR OFF - ' _PRINTSTRING (0, 0), text$ - ' _PRINTSTRING (0, ch), text2$ - ' _CONTROLCHR ON - - - - 'IF VK(i).held THEN - ' cBg& = cBgHighlight& - 'END IF - - 'bgTex = VkColTex(bgCol&) - 'borderTex = VkColTex(borderCol&) - - ''PRINT x1, y1, x2, y2 - '_PUTIMAGE (x1 + 1, y2 + 1)-(x2 - 1, y1 - 1), bgTex, VkBackbuffer - - '_PUTIMAGE (x1, y2)-(x2, y2), borderTex, VkBackbuffer - '_PUTIMAGE (x1, y2 + 1)-(x1, y1), borderTex, VkBackbuffer - '_PUTIMAGE (x2, y2 + 1)-(x2, y1), borderTex, VkBackbuffer - '_PUTIMAGE (x1 + 1, y1)-(x2 - 1, y1), borderTex, VkBackbuffer - - - ''LINE (x1, y1)-(x2, y2), borderCol&, B - '' _BLEND - '' _BLEND bgTex - - 'IF g = 0 THEN - ' g = 1 - ' ' _PUTIMAGE (0, 0)-(100, 100), bgTex - ' ' _PUTIMAGE (50, 50)-(150, 150), borderTex - 'END IF - '_FREEIMAGE bgTex - '_FREEIMAGE borderTex - - 'conv to hw - IF shiftedPass = 0 THEN - IF pass = 1 THEN VK(i).image = _COPYIMAGE(defKey, 33) - IF pass = 2 THEN VK(i).highlightImage = _COPYIMAGE(defKey, 33) - IF pass = 3 THEN VK(i).selectedImage = _COPYIMAGE(defKey, 33) - ELSE - IF pass = 1 THEN VK(i).shiftedImage = _COPYIMAGE(defKey, 33) - IF pass = 2 THEN VK(i).shiftedHighlightImage = _COPYIMAGE(defKey, 33) - IF pass = 3 THEN VK(i).shiftedSelectedImage = _COPYIMAGE(defKey, 33) - END IF - _FREEIMAGE defKey - NEXT 'pass - END IF - NEXT 'shiftedPass - 'SOUND 1000, 0.1 - END IF - - 'assume shift in effect - shifted = 0 - IF VK(i).hasShiftedEvent THEN - IF shiftInEffect THEN - shifted = 1 - END IF - END IF - - - IF VkHide = 0 OR VK(i).internal <> 0 THEN - IF shifted THEN - IF VkSelectedKey = i AND VK(rt).locked <> 0 THEN - _PUTIMAGE (x1, y2), VK(i).shiftedSelectedImage, VkBackbuffer - ELSE - IF VK(i).locks THEN - IF VK(i).locked THEN - _PUTIMAGE (x1, y2), VK(i).shiftedHighlightImage, VkBackbuffer - ELSE - _PUTIMAGE (x1, y2), VK(i).shiftedImage, VkBackbuffer - END IF - ELSE - IF VK(i).held THEN - _PUTIMAGE (x1, y2), VK(i).shiftedHighlightImage, VkBackbuffer - ELSE - _PUTIMAGE (x1, y2), VK(i).shiftedImage, VkBackbuffer - END IF - END IF - END IF - ELSE - IF VkSelectedKey = i AND VK(rt).locked <> 0 THEN - _PUTIMAGE (x1, y2), VK(i).selectedImage, VkBackbuffer - ELSE - IF VK(i).locks THEN - IF VK(i).locked THEN - _PUTIMAGE (x1, y2), VK(i).highlightImage, VkBackbuffer - ELSE - _PUTIMAGE (x1, y2), VK(i).image, VkBackbuffer - END IF - ELSE - IF VK(i).held THEN - _PUTIMAGE (x1, y2), VK(i).highlightImage, VkBackbuffer - ELSE - _PUTIMAGE (x1, y2), VK(i).image, VkBackbuffer - END IF - END IF - END IF - END IF - END IF - ''convert label to image - 'text$ = RTRIM$(VK(i).label) - 'IF text$ <> "" THEN - ' lines = 1 - ' IF INSTR(text$, " ") THEN - ' lines = 2 - ' text2$ = RIGHT$(text$, LEN(text$) - INSTR(text$, " ")) - ' text$ = LEFT$(text$, INSTR(text$, " ") - 1) - ' END IF - - - ' font = VkFont - - - - - ' IF lines = 2 OR LEN(text$) > 1 THEN - ' font = VkFontSmall - ' END IF - - - - ' STATIC dummy32 - ' IF dummy32 = 0 THEN - ' dummy32 = _NEWIMAGE(1, 1, 32) - ' END IF - - - ' olddest = _DEST - ' _DEST dummy32 - ' _FONT font - ' cw = _PRINTWIDTH(text$) - ' IF lines = 2 THEN - ' cw2 = _PRINTWIDTH(text2$) - ' IF cw2 > cw THEN cw = cw2 - ' END IF - ' ch = _FONTHEIGHT - - - - - ' ' GOTO 1 - ' IF cw = 0 OR ch = 0 THEN GOTO 1 - - - - - ' ci = _NEWIMAGE(cw, ch * lines, 32) - ' _DEST ci - ' _FONT font - ' _PRINTMODE _KEEPBACKGROUND - ' COLOR textCol& - ' _CONTROLCHR OFF - ' _PRINTSTRING (0, 0), text$ - ' _PRINTSTRING (0, ch), text2$ - ' _CONTROLCHR ON - - ' ch = ch * lines - ' ci33 = _COPYIMAGE(ci, 33) - ' _FREEIMAGE ci - - ' 'IF VkFontScale = 1 THEN - ' _PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2), ci33, VkBackbuffer - ' 'ELSE - ' 'cw = cw / VkFontScale - ' 'ch = ch / VkFontScale - ' '_PUTIMAGE ((x1 + x2) / 2 - cw / 2, (y1 + y2) / 2 - ch / 2)-((x1 + x2) / 2 + cw / 2 - 1, (y1 + y2) / 2 + ch / 2 - 1), ci33, VkBackbuffer, , _SMOOTH - ' 'END IF - ' _FREEIMAGE ci33 - - ' 1 - ' _DEST olddest - - special_key: - ' _DEST olddest - ' END IF - - END IF - END IF - NEXT - NEXT - - - - - - '_PUTIMAGE (mx, my)-(mx + 100, my + 100), borderTex, VkBackbuffer - - '_PUTIMAGE , VkBackbuffer, VkOverlay - _DONTBLEND VkBackbuffer - _PUTIMAGE , VkBackbuffer, VkOverlay - '_PUTIMAGE (0, 0)-(639, 399), VkOverlay - requestKeyboardOverlayImage VkOverlay - _BLEND VkBackbuffer - -END IF 'reDraw - - -'key repeat -timeNow! = TIMER -FOR i = 1 TO VkLast - IF VK(i).active THEN - IF VK(i).internal = 0 THEN - IF VK(i).lastKeydownTime <> 0 THEN 'only keys which can repeat will have this set - IF VK(i).held THEN - IF VK(i).keyRepeatCount = 0 THEN - IF ABS(VK(i).lastKeydownTime - timeNow!) > VkDelayUntilFirstRepeat THEN - VkKeyRepeat i - END IF - ELSE - IF ABS(VK(i).lastKeydownTime - timeNow!) > VkDelayUntilFollowingRepeats THEN - VkKeyRepeat i - END IF - END IF - END IF - END IF - END IF - END IF -NEXT - -DO - - mDown = 0 - mUp = 0 - mEvent = 0 - -if VkMousePipe=0 then - VkMousePipe=_MOUSEPIPEOPEN 'create new pipe -end if - -' IF VkSharedInputMode THEN -' VkGetMouse VkSharedMouseMx, VkSharedMouseMy, VkSharedMouseMb -' mb = VkSharedMouseMb -' mb = mb AND 1 -' IF mb <> 0 THEN mb = -1 -' mx = VkSharedMouseMx -' my = VkSharedMouseMy -' 'CALL INTERRUPT is a problem... -' 'if ((display_page->compatible_mode==1)||(display_page->compatible_mode==7)||(display_page->compatible_mode==13)) cpu.cx*=2; -' 'if (display_page->text){ -' ' //note: a range from 0 to columns*8-1 is returned regardless of the number of actual pixels -' ' cpu.cx=(mx-0.5)*8.0; -' ' if (cpu.cx>=(display_page->width*8)) cpu.cx=(display_page->width*8)-1; -' ' //note: a range from 0 to rows*8-1 is returned regardless of the number of actual pixels -' ' //obselete line of code: cpu.dx=(((float)cpu.dx)/((float)(display_page->height*fontheight[display_page->font])))*((float)(display_page->height*8));//(mouse_y/height_in_pixels)*(rows*8) -' ' cpu.dx=(my-0.5)*8.0; -' ' if (cpu.dx>=(display_page->height*8)) cpu.dx=(display_page->height*8)-1; -' '} -' 'reverse adjustments made by CALL INTERRUPT -' IF _PIXELSIZE = 1 THEN 'legacy modes adjustment -' mx = mx \ 2 -' END IF -' IF _PIXELSIZE = 0 THEN 'screen 0 adjustment -' mx = (mx / 8) + 0.5 -' my = (my / 8) + 0.5 -' END IF -' 'apply new adjustments -' IF _PIXELSIZE = 0 THEN 'screen 0 adjustment -' mx = mx * 8 - 4 -' my = my * 16 - 8 -' END IF -' IF mb = -1 AND omb = 0 THEN mDown = -1: mEvent = 1 -' IF mb = 0 AND omb = -1 THEN mUp = -1: mEvent = 1 -' omb = mb -' ELSE - - DO WHILE _MOUSEINPUT(VkMousePipe) - mb = _MOUSEBUTTON(1, VkMousePipe) - - mx = _MOUSEX(VkMousePipe) - my = _MOUSEY(VkMousePipe) - - sw=_width(0) - sh=_height(0) - - IF _PIXELSIZE = 0 THEN 'screen 0 adjustment - mx = mx * 8 - 4 - my = my * 16 - 8 - sw=sw*8 - sh=sh*16 - END IF - - mx = CINT(mx*(_SCALEDWIDTH/sw)) - my = CINT(my*(_SCALEDHEIGHT/sh)) - - IF mb = -1 AND omb = 0 THEN mDown = -1: mEvent = 1: EXIT DO - - if VkMousePipeCapture=0 then - _MOUSEINPUTPIPE VkMousePipe - end if - - IF mb = 0 AND omb = -1 THEN - VkMousePipeCapture=0 - mUp = -1 - mEvent = 1 - EXIT DO - end if - - LOOP - omb = mb -' END IF - - rootId = VkByRole("ROOT") - editMode = VK(rootId).locked - - IF mDown THEN - mDownX = mx - mDownY = my - i2 = 0 - - FOR internal = 1 TO 0 STEP -1 - FOR i = VkLast TO 1 STEP -1 - IF VK(i).active THEN - IF VK(i).internal = internal THEN - if internal=1 or VkHide=0 then - x = VK(i).x * VkUnitSize - y = VK(i).y * VkUnitSize - w = VK(i).w - h = VK(i).h - x1 = INT(x) - x2 = INT(x + VkUnitSize * w) - 1 - y1 = sy - 1 - INT(y) - y2 = sy - 1 - INT(y + VkUnitSize * h) + 1 - IF mx >= x1 AND mx <= x2 AND my >= y2 AND my <= y1 THEN - i2 = i - EXIT FOR - END IF - end if - END IF - END IF - NEXT - IF i2 THEN EXIT FOR - NEXT - IF i2 THEN - VkI = i2 - VKoldX = VK(i2).x - VKoldY = VK(i2).y - VKdragging = 0 - VKstart = TIMER(0.001) - 'VK(i2).held = -1 - VkKeyDown i2 - VkMousePipeCapture=1 - END IF - if VkMousePipeCapture=0 then _MOUSEINPUTPIPE VkMousePipe - END IF - - IF mUp THEN - IF VkI THEN - - IF VK(VkI).event.keydown = -1 THEN - IF editMode = 0 THEN - VkUpdateDPAD VkI, 0, 0 - END IF - END IF - - VkKeyUp VkI - IF VKdragging = 0 THEN - VKend = TIMER(0.001) - duration = VKend - VKstart - IF duration > 0.5 THEN - VkLongPress (VkI) - ELSE - VkPress (VkI) - END IF - END IF - 'VK(VKi).held = 0 - VkI = 0 - END IF - END IF - rt = VkByRole("ROOT") - IF mb THEN - IF VkI THEN - - canMove = 0 - IF VK(rt).locked <> 0 OR VK(VkI).internal = 1 THEN canMove = 1 - - IF canMove = 1 THEN - 'calculate distance in units from mouse down location to current location - nx = VKoldX + CINT((mx - mDownX) / VkUnitSize) - ny = VKoldY - CINT((my - mDownY) / VkUnitSize / VkUnitStepY) * VkUnitStepY - - distX = ABS(VKoldX - nx) - distY = ABS(VKoldY - ny) - IF distY > distX THEN dist = distY ELSE dist = distX - - IF dist >= VkUnitStepY THEN - - IF VK(rt).locked <> 0 OR VK(VkI).internal = 1 THEN - - VKdragging = -1 - 'VK(VKi).held = 0 - IF VK(VkI).parent <> 0 AND VK(VkI).internal <> 0 THEN - p = VK(VkI).parent - mDownX = mDownX + (VK(VkI).x - VK(p).x) * VkUnitSize - mDownY = mDownY + (VK(p).y - VK(VkI).y) * VkUnitSize - VkI = p - END IF - END IF - END IF - END IF 'canmove=1 - - 'dpad - IF canMove = 0 THEN - IF VK(rt).locked = 0 AND VK(VkI).event.keydown = -1 THEN - 'dpad - VKdragging = -1 - END IF - END IF - - IF VKdragging THEN - IF VK(rt).locked = 0 AND VK(VkI).event.keydown = -1 THEN - dpadx = mx - mDownX '(VK(VkI).x * VkUnitSize + VkUnitSize / 2) - dpady = my - mDownY ' (sy - VK(VkI).y * VkUnitSize - VkUnitSize / 2) - dpadx = dpadx / (VkUnitSize * VkDefaultWidth * 0.9) - dpady = dpady / (VkUnitSize * VkDefaultWidth * 0.9) - 'normalize if greater than 1 unit - l = SQR(dpadx * dpadx + dpady * dpady) - IF l > 1 THEN - dpadx = dpadx / l - dpady = dpady / l - END IF - VkUpdateDPAD VkI, dpadx, dpady - 'convert dpad value relative to 1/0 - - - - - ELSE - 'prevent off-screen drag - IF nx < 0 THEN nx = 0 - IF ny < 0 THEN ny = 0 - 'prevent covering of other (non-internal) keys - ox = VK(VkI).x - oy = VK(VkI).y - oldOffsetX = VK(VkI).offsetX - oldOffsetY = VK(VkI).offsetY - IF ox <> nx OR oy <> ny THEN - sgnx = SGN(nx - ox): IF sgnx = 0 THEN sgnx = 1 - sgny = SGN(ny - oy) * VkUnitStepY: IF sgny = 0 THEN sgny = VkUnitStepY - bestDist = 10000 - FOR ix = ox TO nx STEP sgnx - FOR iy = oy TO ny STEP sgny - blocked = 0 - IF VK(VkI).event.keydown <> -2 AND VK(VkI).internal = 0 THEN - nw = VK(VkI).w - FOR i = 1 TO VkLast - IF VK(i).internal = 0 AND VK(i).active AND i <> VkI AND VK(i).event.keydown <> -2 THEN - y = VK(i).y: x = VK(i).x: w = VK(i).w - IF iy = y THEN 'same row - ok = 0 - IF ix >= x + w THEN ok = 1 - IF ix + nw <= x THEN ok = 1 - IF ok = 0 THEN blocked = 1 - END IF - END IF - NEXT - END IF - IF blocked = 0 THEN - dist = ABS(nx - ix) + ABS(ny - iy) - IF dist < bestDist THEN - bestDist = dist - IF VK(VkI).parent THEN - VK(VkI).offsetX = oldOffsetX + (ix - ox) - VK(VkI).offsetY = oldOffsetY + (iy - oy) - END IF - VK(VkI).x = ix - VK(VkI).y = iy - VkReDraw = 1 - END IF - END IF - NEXT - NEXT - END IF - END IF - END IF - END IF - END IF - -LOOP UNTIL mEvent = 0 - - - -'_DISPLAY -'_LIMIT 30 -'k$ = inkey$ -'k$ = "" - -_DEST subOldDest -_SOURCE subOldSource - -if VkExiting=2 then - VkExiting=0 - VkExited=1 -end if - -END SUB - - - - - -FUNCTION VkColTex& (col&) -i& = _NEWIMAGE(1, 1, 32) -oldDest& = _DEST -_DEST i& -_DONTBLEND -CLS , col& -_BLEND -_DEST oldDest& -VkColTex& = _COPYIMAGE(i&, 33) -_FREEIMAGE i& -END FUNCTION - -SUB VkUpdateDPAD (i, x, y) -VkReDraw = 1 -ox = VK(i).dpad.x -oy = VK(i).dpad.y -minDist = 0.35 'diagonal max. dist is ~7 -odx = VK(i).dpad.dx -ody = VK(i).dpad.dy -dx = 0 -IF x <= -minDist THEN dx = -1 -IF x >= minDist THEN dx = 1 -dy = 0 -IF y <= -minDist THEN dy = -1 -IF y >= minDist THEN dy = 1 -'hardcoded dpad keys -VK(i).dpad.left.keydown = VK_KEY_LEFT -VK(i).dpad.right.keydown = VK_KEY_RIGHT -VK(i).dpad.up.keydown = VK_KEY_UP -VK(i).dpad.down.keydown = VK_KEY_DOWN -IF dx <> odx THEN - IF odx = -1 THEN keyup VK(i).dpad.left.keydown - IF odx = 1 THEN keyup VK(i).dpad.right.keydown - IF dx = -1 THEN keydown VK(i).dpad.left.keydown: VK(i).dpad.lastKeyDx = dx: VK(i).dpad.lastKeyDy = 0 - IF dx = 1 THEN keydown VK(i).dpad.right.keydown: VK(i).dpad.lastKeyDx = dx: VK(i).dpad.lastKeyDy = 0 -END IF -IF dy <> ody THEN - IF ody = -1 THEN keyup VK(i).dpad.up.keydown - IF ody = 1 THEN keyup VK(i).dpad.down.keydown - IF dy = -1 THEN keydown VK(i).dpad.up.keydown: VK(i).dpad.lastKeyDy = dy: VK(i).dpad.lastKeyDx = 0 - IF dy = 1 THEN keydown VK(i).dpad.down.keydown: VK(i).dpad.lastKeyDy = dy: VK(i).dpad.lastKeyDx = 0 -END IF -'strongest direction must have been represented by last known keydown event fired by dpad -IF dx <> 0 OR dy <> 0 THEN 'has direction - bestDx = 0: bestDy = 0 - IF ABS(x) > ABS(y) THEN - bestDx = SGN(x) - ELSE - bestDy = SGN(y) - END IF - IF bestDx <> VK(i).dpad.lastKeyDx AND bestDx <> 0 THEN - dx = bestDx - IF dx = -1 THEN keydown VK(i).dpad.left.keydown: VK(i).dpad.lastKeyDx = dx: VK(i).dpad.lastKeyDy = 0 - IF dx = 1 THEN keydown VK(i).dpad.right.keydown: VK(i).dpad.lastKeyDx = dx: VK(i).dpad.lastKeyDy = 0 - - ELSE - IF bestDy <> VK(i).dpad.lastKeyDy AND bestDy <> 0 THEN - dy = bestDy - IF dy = -1 THEN keydown VK(i).dpad.up.keydown: VK(i).dpad.lastKeyDy = dy: VK(i).dpad.lastKeyDx = 0 - IF dy = 1 THEN keydown VK(i).dpad.down.keydown: VK(i).dpad.lastKeyDy = dy: VK(i).dpad.lastKeyDx = 0 - - END IF - END IF -END IF -VK(i).dpad.dx = dx -VK(i).dpad.dy = dy -VK(i).dpad.x = x -VK(i).dpad.y = y -END SUB - -SUB VkReLabel (i, label$) -VkReDraw = 1 -VK(i).label = label$ -VK(i).reDraw = 1 -END SUB - -SUB VkReLabelShifted (i, label$) -VkReDraw = 1 -VK(i).shiftedLabel = label$ -VK(i).reDraw = 1 -END SUB - - -SUB VkAddKeyName (keyName AS STRING, keyCode AS LONG) -value = QB_NODE_new(QB_NODE_TYPE_VALUE, 0) -QB_NODE_setLabel_format value, QB_STR_new(keyName), QB_NODE_FORMAT_STR -QB_NODE_setValue_format value, keyCode, QB_NODE_FORMAT_LONG -QB_NODE_assign VkKeyCodeLookup, value -value = QB_NODE_new(QB_NODE_TYPE_VALUE, 0) -QB_NODE_setLabel_format value, keyCode, QB_NODE_FORMAT_LONG -QB_NODE_setValue_format value, QB_STR_new(keyName), QB_NODE_FORMAT_STR -QB_NODE_assign VkKeyNameLookup, value -END SUB - -SUB VkAddKeyNames - -VkKeyNameLookup = QB_NODE_newDictionary -VkKeyCodeLookup = QB_NODE_newDictionary - -VkAddKeyName "KEY_PAUSE", 100019 -VkAddKeyName "KEY_NUMLOCK", 100300 -VkAddKeyName "KEY_CAPSLOCK", 100301 -VkAddKeyName "KEY_SCROLLOCK", 100302 -VkAddKeyName "KEY_RSHIFT", 100303 -VkAddKeyName "KEY_LSHIFT", 100304 -VkAddKeyName "KEY_RCTRL", 100305 -VkAddKeyName "KEY_LCTRL", 100306 -VkAddKeyName "KEY_RALT", 100307 -VkAddKeyName "KEY_LALT", 100308 -VkAddKeyName "KEY_RMETA", 100309 -VkAddKeyName "KEY_LMETA", 100310 -VkAddKeyName "KEY_LSUPER", 100311 -VkAddKeyName "KEY_RSUPER", 100312 -VkAddKeyName "KEY_MODE", 100313 -VkAddKeyName "KEY_COMPOSE", 100314 -VkAddKeyName "KEY_HELP", 100315 -VkAddKeyName "KEY_PRINT", 100316 -VkAddKeyName "KEY_SYSREQ", 100317 -VkAddKeyName "KEY_BREAK", 100318 -VkAddKeyName "KEY_MENU", 100319 -VkAddKeyName "KEY_POWER", 100320 -VkAddKeyName "KEY_EURO", 100321 -VkAddKeyName "KEY_UNDO", 100322 -VkAddKeyName "KEY_KP0", 100256 -VkAddKeyName "KEY_KP1", 100257 -VkAddKeyName "KEY_KP2", 100258 -VkAddKeyName "KEY_KP3", 100259 -VkAddKeyName "KEY_KP4", 100260 -VkAddKeyName "KEY_KP5", 100261 -VkAddKeyName "KEY_KP6", 100262 -VkAddKeyName "KEY_KP7", 100263 -VkAddKeyName "KEY_KP8", 100264 -VkAddKeyName "KEY_KP9", 100265 -VkAddKeyName "KEY_KP_PERIOD", 100266 -VkAddKeyName "KEY_KP_DIVIDE", 100267 -VkAddKeyName "KEY_KP_MULTIPLY", 100268 -VkAddKeyName "KEY_KP_MINUS", 100269 -VkAddKeyName "KEY_KP_PLUS", 100270 -VkAddKeyName "KEY_KP_ENTER", 100271 -VkAddKeyName "KEY_KP_INSERT", 200000 -VkAddKeyName "KEY_KP_END", 200001 -VkAddKeyName "KEY_KP_DOWN", 200002 -VkAddKeyName "KEY_KP_PAGE_DOWN", 200003 -VkAddKeyName "KEY_KP_LEFT", 200004 -VkAddKeyName "KEY_KP_MIDDLE", 200005 -VkAddKeyName "KEY_KP_RIGHT", 200006 -VkAddKeyName "KEY_KP_HOME", 200007 -VkAddKeyName "KEY_KP_UP", 200008 -VkAddKeyName "KEY_KP_PAGE_UP", 200009 -VkAddKeyName "KEY_KP_DELETE", 200010 -VkAddKeyName "KEY_SCROLL_LOCK_MODE", 200011 -VkAddKeyName "KEY_INSERT_MODE", 200012 - -VkAddKeyName "KEY_F1", 15104 -VkAddKeyName "KEY_F2", 15360 -VkAddKeyName "KEY_F3", 15616 -VkAddKeyName "KEY_F4", 15872 -VkAddKeyName "KEY_F5", 16128 -VkAddKeyName "KEY_F6", 16384 -VkAddKeyName "KEY_F7", 16640 -VkAddKeyName "KEY_F8", 16896 -VkAddKeyName "KEY_F9", 17152 -VkAddKeyName "KEY_F10", 17408 -VkAddKeyName "KEY_F11", 34048 -VkAddKeyName "KEY_F12", 34304 - -VkAddKeyName "KEY_INSERT", 20992 -VkAddKeyName "KEY_DELETE", 21248 -VkAddKeyName "KEY_HOME", 18176 -VkAddKeyName "KEY_END", 20224 -VkAddKeyName "KEY_PAGE_UP", 18688 -VkAddKeyName "KEY_PAGE_DOWN", 20736 - -VkAddKeyName "KEY_UP", 18432 -VkAddKeyName "KEY_DOWN", 20480 -VkAddKeyName "KEY_LEFT", 19200 -VkAddKeyName "KEY_RIGHT", 19712 - -VkAddKeyName "KEY_BACKSPACE", 8 -VkAddKeyName "KEY_TAB", 9 - -VkAddKeyName "KEY_ENTER", 13 -VkAddKeyName "KEY_ESCAPE", 27 - -VkAddKeyName "KEY_SPACE", 32 -VkAddKeyName "KEY_EXCLAMATION", 33 -VkAddKeyName "KEY_QUOTE", 34 -VkAddKeyName "KEY_HASH", 35 -VkAddKeyName "KEY_DOLLAR", 36 -VkAddKeyName "KEY_PERCENT", 37 -VkAddKeyName "KEY_AND", 38 -VkAddKeyName "KEY_APOSTROPHE", 39 -VkAddKeyName "KEY_OPEN_BRACKET", 40 -VkAddKeyName "KEY_CLOSE_BRACKET", 41 -VkAddKeyName "KEY_STAR", 42 -VkAddKeyName "KEY_PLUS", 43 -VkAddKeyName "KEY_COMMA", 44 -VkAddKeyName "KEY_MINUS", 45 -VkAddKeyName "KEY_DOT", 46 -VkAddKeyName "KEY_FORWARD_SLASH", 47 -VkAddKeyName "KEY_0", 48 -VkAddKeyName "KEY_1", 49 -VkAddKeyName "KEY_2", 50 -VkAddKeyName "KEY_3", 51 -VkAddKeyName "KEY_4", 52 -VkAddKeyName "KEY_5", 53 -VkAddKeyName "KEY_6", 54 -VkAddKeyName "KEY_7", 55 -VkAddKeyName "KEY_8", 56 -VkAddKeyName "KEY_9", 57 -VkAddKeyName "KEY_COLON", 58 -VkAddKeyName "KEY_SEMICOLON", 59 -VkAddKeyName "KEY_LESS_THAN", 60 -VkAddKeyName "KEY_EQUAL", 61 -VkAddKeyName "KEY_GREATER_THAN", 62 -VkAddKeyName "KEY_QUESTION", 63 -VkAddKeyName "KEY_AT", 64 -VkAddKeyName "KEY_A", 65 -VkAddKeyName "KEY_B", 66 -VkAddKeyName "KEY_C", 67 -VkAddKeyName "KEY_D", 68 -VkAddKeyName "KEY_E", 69 -VkAddKeyName "KEY_F", 70 -VkAddKeyName "KEY_G", 71 -VkAddKeyName "KEY_H", 72 -VkAddKeyName "KEY_I", 73 -VkAddKeyName "KEY_J", 74 -VkAddKeyName "KEY_K", 75 -VkAddKeyName "KEY_L", 76 -VkAddKeyName "KEY_M", 77 -VkAddKeyName "KEY_N", 78 -VkAddKeyName "KEY_O", 79 -VkAddKeyName "KEY_P", 80 -VkAddKeyName "KEY_Q", 81 -VkAddKeyName "KEY_R", 82 -VkAddKeyName "KEY_S", 83 -VkAddKeyName "KEY_T", 84 -VkAddKeyName "KEY_U", 85 -VkAddKeyName "KEY_V", 86 -VkAddKeyName "KEY_W", 87 -VkAddKeyName "KEY_X", 88 -VkAddKeyName "KEY_Y", 89 -VkAddKeyName "KEY_Z", 90 -VkAddKeyName "KEY_UCASE_A", 65 -VkAddKeyName "KEY_UCASE_B", 66 -VkAddKeyName "KEY_UCASE_C", 67 -VkAddKeyName "KEY_UCASE_D", 68 -VkAddKeyName "KEY_UCASE_E", 69 -VkAddKeyName "KEY_UCASE_F", 70 -VkAddKeyName "KEY_UCASE_G", 71 -VkAddKeyName "KEY_UCASE_H", 72 -VkAddKeyName "KEY_UCASE_I", 73 -VkAddKeyName "KEY_UCASE_J", 74 -VkAddKeyName "KEY_UCASE_K", 75 -VkAddKeyName "KEY_UCASE_L", 76 -VkAddKeyName "KEY_UCASE_M", 77 -VkAddKeyName "KEY_UCASE_N", 78 -VkAddKeyName "KEY_UCASE_O", 79 -VkAddKeyName "KEY_UCASE_P", 80 -VkAddKeyName "KEY_UCASE_Q", 81 -VkAddKeyName "KEY_UCASE_R", 82 -VkAddKeyName "KEY_UCASE_S", 83 -VkAddKeyName "KEY_UCASE_T", 84 -VkAddKeyName "KEY_UCASE_U", 85 -VkAddKeyName "KEY_UCASE_V", 86 -VkAddKeyName "KEY_UCASE_W", 87 -VkAddKeyName "KEY_UCASE_X", 88 -VkAddKeyName "KEY_UCASE_Y", 89 -VkAddKeyName "KEY_UCASE_Z", 90 -VkAddKeyName "KEY_OPEN_BRACKET_SQUARE", 91 -VkAddKeyName "KEY_BACK_SLASH", 92 -VkAddKeyName "KEY_CLOSE_BRACKET_SQUARE", 93 -VkAddKeyName "KEY_CARET", 94 -VkAddKeyName "KEY_UNDERSCORE", 95 -VkAddKeyName "KEY_REVERSE_APOSTROPHE", 96 -VkAddKeyName "KEY_LCASE_A", 97 -VkAddKeyName "KEY_LCASE_B", 98 -VkAddKeyName "KEY_LCASE_C", 99 -VkAddKeyName "KEY_LCASE_D", 100 -VkAddKeyName "KEY_LCASE_E", 101 -VkAddKeyName "KEY_LCASE_F", 102 -VkAddKeyName "KEY_LCASE_G", 103 -VkAddKeyName "KEY_LCASE_H", 104 -VkAddKeyName "KEY_LCASE_I", 105 -VkAddKeyName "KEY_LCASE_J", 106 -VkAddKeyName "KEY_LCASE_K", 107 -VkAddKeyName "KEY_LCASE_L", 108 -VkAddKeyName "KEY_LCASE_M", 109 -VkAddKeyName "KEY_LCASE_N", 110 -VkAddKeyName "KEY_LCASE_O", 111 -VkAddKeyName "KEY_LCASE_P", 112 -VkAddKeyName "KEY_LCASE_Q", 113 -VkAddKeyName "KEY_LCASE_R", 114 -VkAddKeyName "KEY_LCASE_S", 115 -VkAddKeyName "KEY_LCASE_T", 116 -VkAddKeyName "KEY_LCASE_U", 117 -VkAddKeyName "KEY_LCASE_V", 118 -VkAddKeyName "KEY_LCASE_W", 119 -VkAddKeyName "KEY_LCASE_X", 120 -VkAddKeyName "KEY_LCASE_Y", 121 -VkAddKeyName "KEY_LCASE_Z", 122 -VkAddKeyName "KEY_OPEN_BRACKET_CURLY", 123 -VkAddKeyName "KEY_VERTICAL_BAR", 124 -VkAddKeyName "KEY_CLOSE_BRACKET_CURLY", 125 -VkAddKeyName "KEY_TILDE", 126 -VkAddKeyName "KEY_BACKSPACE_ALTERNATE", 127 -END SUB - -FUNCTION VkGetKeyName$ (keyCode AS LONG) -VkGetKeyName$ = QB_STR_long(keyCode) -DIM VkChild AS LONG -DIM VkI AS LONG -DO WHILE QB_NODE_eachWithLabel_format(VkChild, VkKeyNameLookup, keyCode, QB_NODE_FORMAT_LONG, VkI) - VkGetKeyName$ = QB_NODE_value(VkChild) - EXIT FUNCTION -LOOP -END FUNCTION - -FUNCTION VkGetKeyCode& (keyName AS STRING) -DIM i AS LONG -i = QB_NODE_withLabel(VkKeyCodeLookup, keyName) -IF i THEN - VkGetKeyCode& = VAL(QB_NODE_value(i)) -ELSE - VkGetKeyCode& = VAL(keyName) -END IF -END FUNCTION - - -SUB VkSaveKeys (parentNode AS LONG, parentKey AS LONG) -FOR i = 1 TO VkLast - IF VK(i).internal = 0 AND VK(i).active <> 0 AND VK(i).parent = parentKey THEN - - thisKey = QB_NODE_newDictionary - QB_NODE_assign parentNode, thisKey - - 'get type - keyType$ = "key" - IF VK(i).event.keydown = -1 THEN - keyType$ = "joystick" - END IF - IF VK(i).event.keydown = -2 THEN - keyType$ = "keySet" - END IF - - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel("type", keyType$) - - IF parentKey = 0 THEN - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("x", VK(i).x) - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("y", VK(i).y) - ELSE - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("offsetX", VK(i).offsetX) - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("offsetY", VK(i).offsetY) - END IF - - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("width", VK(i).w) - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_long("height", VK(i).h) - - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel("label", RTRIM$(VK(i).label)) - - events = QB_NODE_newDictionary: QB_NODE_setLabel events, "events" - IF keyType$ = "key" THEN - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_bool("locks", VK(i).locks) - QB_NODE_assign thisKey, QB_NODE_newValueWithLabel_bool("lockIsTemporary", VK(i).lockIsTemporary) - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "keydown": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).event.keydown)) - IF VK(i).hasShiftedEvent THEN - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "keydownWithShift": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).shiftedEvent.keydown)) - QB_NODE_assign event, QB_NODE_newValueWithLabel("label", RTRIM$(VK(i).shiftedLabel)) - END IF - END IF - IF keyType$ = "joystick" THEN - 'hardcode keys - VK(i).dpad.left.keydown = VK_KEY_LEFT - VK(i).dpad.right.keydown = VK_KEY_RIGHT - VK(i).dpad.up.keydown = VK_KEY_UP - VK(i).dpad.down.keydown = VK_KEY_DOWN - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "up": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).dpad.up.keydown)) - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "down": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).dpad.down.keydown)) - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "left": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).dpad.left.keydown)) - event = QB_NODE_newDictionary: QB_NODE_setLabel event, "right": QB_NODE_assign events, event - QB_NODE_assign event, QB_NODE_newValueWithLabel("keyCode", VkGetKeyName(VK(i).dpad.right.keydown)) - END IF - IF keyType$ = "keySet" THEN - END IF - IF QB_NODE_count(events) > 0 THEN - QB_NODE_assign thisKey, events - ELSE - QB_NODE_destroy events - END IF - - childKeys = QB_NODE_newList: QB_NODE_setLabel childKeys, "childKeys" - VkSaveKeys childKeys, i - IF QB_NODE_count(childKeys) > 0 THEN - QB_NODE_assign thisKey, childKeys - ELSE - QB_NODE_destroy childKeys - END IF - END IF -NEXT -END SUB - -SUB VkSave -root = QB_NODE_newDictionary -QB_NODE_assign root, QB_NODE_newValueWithLabel_long("width", VkWidthInUnits) -keys = QB_NODE_newList: QB_NODE_setLabel keys, "keys": QB_NODE_assign root, keys -VkSaveKeys keys, 0 -json$ = QB_NODESET_serialize(root, "json") -QB_NODE_destroy root -fh = FREEFILE -OPEN appRootPath$+"virtual_keyboard_layout_current.txt" FOR OUTPUT AS #fh -PRINT #fh, json$ -CLOSE #fh -END SUB - -SUB VkLoadKeys (parentNode AS LONG, parentKey AS LONG) -DIM iterator AS LONG -DIM keyNode AS LONG -DO WHILE QB_NODE_each(keyNode, parentNode, iterator) - DIM events AS LONG - DIM event AS LONG - events = QB_NODE_withLabel(keyNode, "events") - keyType$ = QB_NODE_valueOfLabel(keyNode, "type") - i = VkNew - VK(i).role = "USER" - VK(i).parent = parentKey - IF parentKey THEN - VK(i).offsetX = QB_NODE_valueOfLabel_long(keyNode, "offsetX") - VK(i).offsetY = QB_NODE_valueOfLabel_long(keyNode, "offsetY") - ELSE - VK(i).x = QB_NODE_valueOfLabel_long(keyNode, "x") - VK(i).y = QB_NODE_valueOfLabel_long(keyNode, "y") - END IF - VK(i).w = QB_NODE_valueOfLabel_long(keyNode, "width") - VK(i).h = QB_NODE_valueOfLabel_long(keyNode, "height") - VK(i).label = QB_NODE_valueOfLabel(keyNode, "label") - IF keyType$ = "key" THEN - VK(i).locks = QB_NODE_valueOfLabel_bool(keyNode, "locks") - VK(i).lockIsTemporary = QB_NODE_valueOfLabel_bool(keyNode, "lockIsTemporary") - VK(i).event.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(QB_NODE_withLabel(events, "keydown"), "keyCode")) - shiftedEvent = QB_NODE_withLabel(events, "keydownWithShift") - IF shiftedEvent THEN - VK(i).hasShiftedEvent = 1 - VK(i).shiftedEvent.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(shiftedEvent, "keyCode")) - VK(i).shiftedLabel = QB_NODE_valueOfLabel(shiftedEvent, "label") - END IF - END IF - IF keyType$ = "keySet" THEN - VK(i).event.keydown = -2 - VkLoadKeys QB_NODE_withLabel(keyNode, "childKeys"), i - END IF - IF keyType$ = "joystick" THEN - VK(i).event.keydown = -1 - VK(i).dpad.left.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(QB_NODE_withLabel(events, "left"), "keyCode")) - VK(i).dpad.right.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(QB_NODE_withLabel(events, "right"), "keyCode")) - VK(i).dpad.up.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(QB_NODE_withLabel(events, "up"), "keyCode")) - VK(i).dpad.down.keydown = VkGetKeyCode&(QB_NODE_valueOfLabel(QB_NODE_withLabel(events, "down"), "keyCode")) - END IF -LOOP -END SUB - -FUNCTION VkGetQuotedString$ (a$) -a2$ = SPACE$(LEN(a$)) -i2 = 0 -FOR i = 1 TO LEN(a$) - a2 = a - a = ASC(a$, i) - IF a2 = 92 AND a = 113 THEN - ASC(a2$, i2) = 34 - ELSE - i2 = i2 + 1 - ASC(a2$, i2) = a - END IF -NEXT -a2$ = LEFT$(a2$, i2) -VkGetQuotedString$ = a2$ -END FUNCTION - -SUB VkLoad -VkFile$="" -if _FILEEXISTS(appRootPath$+"virtual_keyboard_layout_default.txt") then VkFile$=appRootPath$+"virtual_keyboard_layout_default.txt" -if _FILEEXISTS(appRootPath$+"virtual_keyboard_layout_current.txt") then VkFile$=appRootPath$+"virtual_keyboard_layout_current.txt" -if VkFile$<>"" then - fh = FREEFILE - OPEN VkFile$ FOR INPUT AS #fh - LINE INPUT #fh, json$ - CLOSE #fh - root = QB_NODESET_deserialize(json$, "json") - DIM oldVkWidthInUnits AS LONG - oldVkWidthInUnits=VkWidthInUnits - VkWidthInUnits=90 - DIM rootValueNode AS LONG - rootValueNode=QB_NODE_withLabel(root, "width") - if rootValueNode then VkWidthInUnits=QB_NODE_valueOfLabel_long(root, "width") - if VkWidthInUnits<>oldVkWidthInUnits then - FOR i3 = 1 TO VkLast - IF VK(i3).active THEN - VK(i3).reDraw = 1 - END IF - NEXT - VkReset = 1 - END IF - VkLoadKeys QB_NODESET_node(QB_NODESET_label_equal(QB_NODESET_children(root), "keys")), 0 - QB_NODE_destroy root -end if -END SUB - -FUNCTION VkShiftInEffect -shiftInEffect = 0 -'IF _KEYDOWN(VK_KEY_LSHIFT) OR _KEYDOWN(VK_KEY_RSHIFT) THEN -' shiftInEffect = 1 -'END IF -shiftLockInEffect = 0 -FOR i = 1 TO VkLast - IF VK(i).active THEN - IF VK(i).internal = 0 THEN - 'is this a caps lock or shift key? - 'is it active? - IF VK(i).event.keydown = VK_KEY_CAPSLOCK THEN - IF VK(i).held <> 0 THEN - shiftLockInEffect = 1 - END IF - END IF - END IF - END IF -NEXT -shiftKeyHeld = 0 -FOR i = 1 TO VkLast - IF VK(i).active THEN - IF VK(i).internal = 0 THEN - 'is this a caps lock or shift key? - 'is it active? - IF VK(i).event.keydown = VK_KEY_LSHIFT OR VK(i).event.keydown = VK_KEY_RSHIFT THEN - IF VK(i).held <> 0 THEN - shiftKeyHeld = 1 - END IF - END IF - END IF - END IF -NEXT -IF shiftLockInEffect + shiftKeyHeld = 1 THEN shiftInEffect = 1 -IF VkAddShiftedKey = 1 THEN shiftInEffect = 1 -VkShiftInEffect = shiftInEffect -END FUNCTION - -SUB VkGetMouse (mx AS LONG, my AS LONG, mb AS LONG) -'DIM SHARED VkReg AS VkRegTypeX -VkReg.ax = 3 -CALL INTERRUPT(&H33, VkReg, VkReg) -mb = VkReg.bx AND 1 -mx = VkReg.cx -my = VkReg.dx -END SUB - -FUNCTION VkFindFont& (idealSize AS LONG) -FOR diff = 0 TO 1000 - FOR negative = 0 TO 1 - IF negative THEN - size = idealSize - diff - ELSE - size = idealSize + diff \ 2 'increase of size is less desirable that decrease of size - END IF - IF size >= 0 AND size <= UBOUND(vkfontAllow) THEN - IF vkFontAllow(size) THEN - if vkFonts(size)=0 then vkFonts(size)=_LOADFONT(appRootPath$+"cyberbit.ttf", size) - if vkFonts(size)=0 then 'font failed to load, so use inbuilt font instead - vkFonts(size)=16 - if size<16 then vkFonts(size)=8 - end if - VkFindFont& = vkFonts(size) - EXIT FUNCTION - END IF - END IF - NEXT -NEXT -END FUNCTION