js,gg: more work on porting gg to JS backend (#12903)
parent
f81654e3a7
commit
5f0160bf11
|
@ -34,6 +34,63 @@ pub mut:
|
|||
framebuffer_height int
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub:
|
||||
width int
|
||||
height int
|
||||
use_ortho bool // unused, still here just for backwards compatibility
|
||||
retina bool
|
||||
resizable bool
|
||||
user_data voidptr
|
||||
font_size int
|
||||
create_window bool
|
||||
// window_user_ptr voidptr
|
||||
window_title string
|
||||
borderless_window bool
|
||||
always_on_top bool
|
||||
bg_color gx.Color
|
||||
init_fn FNCb = voidptr(0)
|
||||
frame_fn FNCb = voidptr(0)
|
||||
native_frame_fn FNCb = voidptr(0)
|
||||
cleanup_fn FNCb = voidptr(0)
|
||||
fail_fn FNFail = voidptr(0)
|
||||
//
|
||||
event_fn FNEvent = voidptr(0)
|
||||
quit_fn FNEvent = voidptr(0)
|
||||
//
|
||||
keydown_fn FNKeyDown = voidptr(0)
|
||||
keyup_fn FNKeyUp = voidptr(0)
|
||||
char_fn FNChar = voidptr(0)
|
||||
//
|
||||
move_fn FNMove = voidptr(0)
|
||||
click_fn FNClick = voidptr(0)
|
||||
unclick_fn FNUnClick = voidptr(0)
|
||||
leave_fn FNEvent = voidptr(0)
|
||||
enter_fn FNEvent = voidptr(0)
|
||||
resized_fn FNEvent = voidptr(0)
|
||||
scroll_fn FNEvent = voidptr(0)
|
||||
// wait_events bool // set this to true for UIs, to save power
|
||||
fullscreen bool
|
||||
scale f32 = 1.0
|
||||
sample_count int
|
||||
swap_interval int = 1 // 1 = 60fps, 2 = 30fps etc. The preferred swap interval (ignored on some platforms)
|
||||
// ved needs this
|
||||
// init_text bool
|
||||
font_path string
|
||||
custom_bold_font_path string
|
||||
ui_mode bool // refreshes only on events to save CPU usage
|
||||
// font bytes for embedding
|
||||
font_bytes_normal []byte
|
||||
font_bytes_bold []byte
|
||||
font_bytes_mono []byte
|
||||
font_bytes_italic []byte
|
||||
native_rendering bool // Cocoa on macOS/iOS, GDI+ on Windows
|
||||
// drag&drop
|
||||
enable_dragndrop bool // enable file dropping (drag'n'drop), default is false
|
||||
max_dropped_files int = 1 // max number of dropped files to process (default: 1)
|
||||
max_dropped_file_path_length int = 2048 // max length in bytes of a dropped UTF-8 file path (default: 2048)
|
||||
}
|
||||
|
||||
[heap]
|
||||
pub struct Context {
|
||||
mut:
|
||||
|
|
181
vlib/gg/gg.js.v
181
vlib/gg/gg.js.v
|
@ -1,5 +1,6 @@
|
|||
module gg
|
||||
|
||||
import gx
|
||||
import js.dom
|
||||
|
||||
pub enum DOMEventType {
|
||||
|
@ -55,37 +56,6 @@ pub mut:
|
|||
framebuffer_height int
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
mut:
|
||||
render_text bool = true
|
||||
image_cache []Image
|
||||
needs_refresh bool = true
|
||||
ticks int
|
||||
pub mut:
|
||||
scale f32 = 1.0
|
||||
width int
|
||||
height int
|
||||
window JS.Window
|
||||
config Config
|
||||
user_data voidptr
|
||||
ui_mode bool
|
||||
frame u64
|
||||
mbtn_mask byte
|
||||
mouse_buttons MouseButtons
|
||||
mouse_pos_x int
|
||||
mouse_pos_y int
|
||||
mouse_dx int
|
||||
mouse_dy int
|
||||
scroll_x int
|
||||
scroll_y int
|
||||
//
|
||||
key_modifiers Modifier // the current key modifiers
|
||||
key_repeat bool // whether the pressed key was an autorepeated one
|
||||
pressed_keys [key_code_max]bool // an array representing all currently pressed keys
|
||||
pressed_keys_edge [key_code_max]bool // true when the previous state of pressed_keys,
|
||||
// *before* the current event was different
|
||||
}
|
||||
|
||||
pub enum DOMMouseButton {
|
||||
invalid = -1
|
||||
left = 0
|
||||
|
@ -226,3 +196,152 @@ pub enum DOMKeyCode {
|
|||
right_super = 347
|
||||
menu = 348
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub:
|
||||
width int
|
||||
height int
|
||||
use_ortho bool // unused, still here just for backwards compatibility
|
||||
retina bool
|
||||
resizable bool
|
||||
user_data voidptr
|
||||
font_size int
|
||||
create_window bool
|
||||
// window_user_ptr voidptr
|
||||
window_title string
|
||||
borderless_window bool
|
||||
always_on_top bool
|
||||
bg_color gx.Color
|
||||
init_fn FNCb = voidptr(0)
|
||||
frame_fn FNCb = voidptr(0)
|
||||
native_frame_fn FNCb = voidptr(0)
|
||||
cleanup_fn FNCb = voidptr(0)
|
||||
fail_fn FNFail = voidptr(0)
|
||||
//
|
||||
event_fn FNEvent = voidptr(0)
|
||||
quit_fn FNEvent = voidptr(0)
|
||||
//
|
||||
keydown_fn FNKeyDown = voidptr(0)
|
||||
keyup_fn FNKeyUp = voidptr(0)
|
||||
char_fn FNChar = voidptr(0)
|
||||
//
|
||||
move_fn FNMove = voidptr(0)
|
||||
click_fn FNClick = voidptr(0)
|
||||
unclick_fn FNUnClick = voidptr(0)
|
||||
leave_fn FNEvent = voidptr(0)
|
||||
enter_fn FNEvent = voidptr(0)
|
||||
resized_fn FNEvent = voidptr(0)
|
||||
scroll_fn FNEvent = voidptr(0)
|
||||
// wait_events bool // set this to true for UIs, to save power
|
||||
fullscreen bool
|
||||
scale f32 = 1.0
|
||||
sample_count int
|
||||
swap_interval int = 1 // 1 = 60fps, 2 = 30fps etc. The preferred swap interval (ignored on some platforms)
|
||||
// ved needs this
|
||||
// init_text bool
|
||||
font_path string
|
||||
custom_bold_font_path string
|
||||
ui_mode bool // refreshes only on events to save CPU usage
|
||||
// font bytes for embedding
|
||||
font_bytes_normal []byte
|
||||
font_bytes_bold []byte
|
||||
font_bytes_mono []byte
|
||||
font_bytes_italic []byte
|
||||
native_rendering bool // Cocoa on macOS/iOS, GDI+ on Windows
|
||||
// drag&drop
|
||||
enable_dragndrop bool // enable file dropping (drag'n'drop), default is false
|
||||
max_dropped_files int = 1 // max number of dropped files to process (default: 1)
|
||||
max_dropped_file_path_length int = 2048 // max length in bytes of a dropped UTF-8 file path (default: 2048)
|
||||
context JS.CanvasRenderingContext2D
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
mut:
|
||||
render_text bool = true
|
||||
image_cache []Image
|
||||
needs_refresh bool = true
|
||||
ticks int
|
||||
pub mut:
|
||||
scale f32 = 1.0
|
||||
width int
|
||||
height int
|
||||
window JS.Window [noinit]
|
||||
config Config
|
||||
user_data voidptr
|
||||
ui_mode bool
|
||||
frame u64
|
||||
mbtn_mask byte
|
||||
mouse_buttons MouseButtons
|
||||
mouse_pos_x int
|
||||
mouse_pos_y int
|
||||
mouse_dx int
|
||||
mouse_dy int
|
||||
scroll_x int
|
||||
scroll_y int
|
||||
//
|
||||
key_modifiers Modifier // the current key modifiers
|
||||
key_repeat bool // whether the pressed key was an autorepeated one
|
||||
pressed_keys [key_code_max]bool // an array representing all currently pressed keys
|
||||
pressed_keys_edge [key_code_max]bool // true when the previous state of pressed_keys,
|
||||
canvas JS.CanvasRenderingContext2D [noinit]
|
||||
// *before* the current event was different
|
||||
}
|
||||
|
||||
pub fn new_context(cfg Config) &Context {
|
||||
mut g := &Context{}
|
||||
g.user_data = cfg.user_data
|
||||
g.width = cfg.width
|
||||
g.height = cfg.height
|
||||
g.ui_mode = cfg.ui_mode
|
||||
g.config = cfg
|
||||
if isnil(cfg.user_data) {
|
||||
g.user_data = g
|
||||
}
|
||||
g.window = dom.window()
|
||||
g.canvas = cfg.context
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) run() {
|
||||
gg_animation_frame_fn(mut ctx)
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) begin() {
|
||||
// ctx.canvas.beginPath()
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) end() {
|
||||
// ctx.canvas.closePath()
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c gx.Color) {
|
||||
ctx.canvas.beginPath()
|
||||
ctx.canvas.strokeStyle = c.to_css_string().str
|
||||
ctx.canvas.moveTo(x1, y1)
|
||||
ctx.canvas.lineTo(x2, y2)
|
||||
ctx.canvas.stroke()
|
||||
ctx.canvas.closePath()
|
||||
}
|
||||
|
||||
pub fn (mut ctx Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
|
||||
ctx.canvas.beginPath()
|
||||
ctx.canvas.fillStyle = c.to_css_string().str
|
||||
ctx.canvas.fillRect(x, y, w, h)
|
||||
ctx.canvas.closePath()
|
||||
}
|
||||
|
||||
fn gg_animation_frame_fn(mut g Context) {
|
||||
g.frame++
|
||||
g.canvas.clearRect(0, 0, g.config.width, g.config.height)
|
||||
// todo(playXE): handle events
|
||||
if !isnil(g.config.frame_fn) {
|
||||
f := g.config.frame_fn
|
||||
f(g.user_data)
|
||||
g.needs_refresh = false
|
||||
}
|
||||
|
||||
g.window.requestAnimationFrame(fn [mut g] (time JS.Number) {
|
||||
gg_animation_frame_fn(mut g)
|
||||
})
|
||||
}
|
||||
|
|
57
vlib/gg/gg.v
57
vlib/gg/gg.v
|
@ -23,63 +23,6 @@ pub type FNUnClick = fn (x f32, y f32, button MouseButton, data voidptr)
|
|||
|
||||
pub type FNChar = fn (c u32, data voidptr)
|
||||
|
||||
pub struct Config {
|
||||
pub:
|
||||
width int
|
||||
height int
|
||||
use_ortho bool // unused, still here just for backwards compatibility
|
||||
retina bool
|
||||
resizable bool
|
||||
user_data voidptr
|
||||
font_size int
|
||||
create_window bool
|
||||
// window_user_ptr voidptr
|
||||
window_title string
|
||||
borderless_window bool
|
||||
always_on_top bool
|
||||
bg_color gx.Color
|
||||
init_fn FNCb = voidptr(0)
|
||||
frame_fn FNCb = voidptr(0)
|
||||
native_frame_fn FNCb = voidptr(0)
|
||||
cleanup_fn FNCb = voidptr(0)
|
||||
fail_fn FNFail = voidptr(0)
|
||||
//
|
||||
event_fn FNEvent = voidptr(0)
|
||||
quit_fn FNEvent = voidptr(0)
|
||||
//
|
||||
keydown_fn FNKeyDown = voidptr(0)
|
||||
keyup_fn FNKeyUp = voidptr(0)
|
||||
char_fn FNChar = voidptr(0)
|
||||
//
|
||||
move_fn FNMove = voidptr(0)
|
||||
click_fn FNClick = voidptr(0)
|
||||
unclick_fn FNUnClick = voidptr(0)
|
||||
leave_fn FNEvent = voidptr(0)
|
||||
enter_fn FNEvent = voidptr(0)
|
||||
resized_fn FNEvent = voidptr(0)
|
||||
scroll_fn FNEvent = voidptr(0)
|
||||
// wait_events bool // set this to true for UIs, to save power
|
||||
fullscreen bool
|
||||
scale f32 = 1.0
|
||||
sample_count int
|
||||
swap_interval int = 1 // 1 = 60fps, 2 = 30fps etc. The preferred swap interval (ignored on some platforms)
|
||||
// ved needs this
|
||||
// init_text bool
|
||||
font_path string
|
||||
custom_bold_font_path string
|
||||
ui_mode bool // refreshes only on events to save CPU usage
|
||||
// font bytes for embedding
|
||||
font_bytes_normal []byte
|
||||
font_bytes_bold []byte
|
||||
font_bytes_mono []byte
|
||||
font_bytes_italic []byte
|
||||
native_rendering bool // Cocoa on macOS/iOS, GDI+ on Windows
|
||||
// drag&drop
|
||||
enable_dragndrop bool // enable file dropping (drag'n'drop), default is false
|
||||
max_dropped_files int = 1 // max number of dropped files to process (default: 1)
|
||||
max_dropped_file_path_length int = 2048 // max length in bytes of a dropped UTF-8 file path (default: 2048)
|
||||
}
|
||||
|
||||
pub struct PenConfig {
|
||||
color gx.Color
|
||||
line_type PenLineType = .solid
|
||||
|
|
|
@ -228,3 +228,113 @@ pub fn (ctx &Context) text_size(s string) (int, int) {
|
|||
ctx.ft.fons.text_bounds(0, 0, s, &buf[0])
|
||||
return int((buf[2] - buf[0]) / ctx.scale), int((buf[3] - buf[1]) / ctx.scale)
|
||||
}
|
||||
|
||||
pub fn system_font_path() string {
|
||||
env_font := os.getenv('VUI_FONT')
|
||||
if env_font != '' && os.exists(env_font) {
|
||||
return env_font
|
||||
}
|
||||
$if windows {
|
||||
debug_font_println('Using font "C:\\Windows\\Fonts\\arial.ttf"')
|
||||
return 'C:\\Windows\\Fonts\\arial.ttf'
|
||||
}
|
||||
$if macos {
|
||||
fonts := ['/System/Library/Fonts/SFNS.ttf', '/System/Library/Fonts/SFNSText.ttf',
|
||||
'/Library/Fonts/Arial.ttf']
|
||||
for font in fonts {
|
||||
if os.is_file(font) {
|
||||
debug_font_println('Using font "$font"')
|
||||
return font
|
||||
}
|
||||
}
|
||||
}
|
||||
$if android {
|
||||
xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml',
|
||||
'/etc/system_fonts.xml', '/etc/fonts.xml', '/data/fonts/fonts.xml',
|
||||
'/etc/fallback_fonts.xml']
|
||||
font_locations := ['/system/fonts', '/data/fonts']
|
||||
for xml_file in xml_files {
|
||||
if os.is_file(xml_file) && os.is_readable(xml_file) {
|
||||
xml := os.read_file(xml_file) or { continue }
|
||||
lines := xml.split('\n')
|
||||
mut candidate_font := ''
|
||||
for line in lines {
|
||||
if line.contains('<font') {
|
||||
candidate_font = line.all_after('>').all_before('<').trim(' \n\t\r')
|
||||
if candidate_font.contains('.ttf') {
|
||||
for location in font_locations {
|
||||
candidate_path := os.join_path(location, candidate_font)
|
||||
if os.is_file(candidate_path) && os.is_readable(candidate_path) {
|
||||
debug_font_println('Using font "$candidate_path"')
|
||||
return candidate_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mut fm := os.execute("fc-match --format='%{file}\n' -s")
|
||||
if fm.exit_code == 0 {
|
||||
lines := fm.output.split('\n')
|
||||
for l in lines {
|
||||
if !l.contains('.ttc') {
|
||||
debug_font_println('Using font "$l"')
|
||||
return l
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic('fc-match failed to fetch system font')
|
||||
}
|
||||
panic('failed to init the font')
|
||||
}
|
||||
|
||||
fn get_font_path_variant(font_path string, variant FontVariant) string {
|
||||
// TODO: find some way to make this shorter and more eye-pleasant
|
||||
// NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work
|
||||
mut file := os.file_name(font_path)
|
||||
mut fpath := font_path.replace(file, '')
|
||||
file = file.replace('.ttf', '')
|
||||
|
||||
match variant {
|
||||
.normal {}
|
||||
.bold {
|
||||
if fpath.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', '-Bold')
|
||||
} else if file.starts_with('DejaVuSans') {
|
||||
file += '-Bold'
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
file += 'bd'
|
||||
} else {
|
||||
file += '-bold'
|
||||
}
|
||||
$if macos {
|
||||
if os.exists('SFNS-bold') {
|
||||
file = 'SFNS-bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
.italic {
|
||||
if file.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', '-Italic')
|
||||
} else if file.starts_with('DejaVuSans') {
|
||||
file += '-Oblique'
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
file += 'i'
|
||||
} else {
|
||||
file += 'Italic'
|
||||
}
|
||||
}
|
||||
.mono {
|
||||
if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', 'Mono-Regular')
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
// Arial has no mono variant
|
||||
} else {
|
||||
file += 'Mono'
|
||||
}
|
||||
}
|
||||
}
|
||||
return fpath + file + '.ttf'
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
|
||||
module gg
|
||||
|
||||
import os
|
||||
import gx
|
||||
|
||||
enum FontVariant {
|
||||
|
@ -30,116 +29,6 @@ struct StringToRender {
|
|||
cfg gx.TextCfg
|
||||
}
|
||||
|
||||
pub fn system_font_path() string {
|
||||
env_font := os.getenv('VUI_FONT')
|
||||
if env_font != '' && os.exists(env_font) {
|
||||
return env_font
|
||||
}
|
||||
$if windows {
|
||||
debug_font_println('Using font "C:\\Windows\\Fonts\\arial.ttf"')
|
||||
return 'C:\\Windows\\Fonts\\arial.ttf'
|
||||
}
|
||||
$if macos {
|
||||
fonts := ['/System/Library/Fonts/SFNS.ttf', '/System/Library/Fonts/SFNSText.ttf',
|
||||
'/Library/Fonts/Arial.ttf']
|
||||
for font in fonts {
|
||||
if os.is_file(font) {
|
||||
debug_font_println('Using font "$font"')
|
||||
return font
|
||||
}
|
||||
}
|
||||
}
|
||||
$if android {
|
||||
xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml',
|
||||
'/etc/system_fonts.xml', '/etc/fonts.xml', '/data/fonts/fonts.xml',
|
||||
'/etc/fallback_fonts.xml']
|
||||
font_locations := ['/system/fonts', '/data/fonts']
|
||||
for xml_file in xml_files {
|
||||
if os.is_file(xml_file) && os.is_readable(xml_file) {
|
||||
xml := os.read_file(xml_file) or { continue }
|
||||
lines := xml.split('\n')
|
||||
mut candidate_font := ''
|
||||
for line in lines {
|
||||
if line.contains('<font') {
|
||||
candidate_font = line.all_after('>').all_before('<').trim(' \n\t\r')
|
||||
if candidate_font.contains('.ttf') {
|
||||
for location in font_locations {
|
||||
candidate_path := os.join_path(location, candidate_font)
|
||||
if os.is_file(candidate_path) && os.is_readable(candidate_path) {
|
||||
debug_font_println('Using font "$candidate_path"')
|
||||
return candidate_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mut fm := os.execute("fc-match --format='%{file}\n' -s")
|
||||
if fm.exit_code == 0 {
|
||||
lines := fm.output.split('\n')
|
||||
for l in lines {
|
||||
if !l.contains('.ttc') {
|
||||
debug_font_println('Using font "$l"')
|
||||
return l
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic('fc-match failed to fetch system font')
|
||||
}
|
||||
panic('failed to init the font')
|
||||
}
|
||||
|
||||
fn get_font_path_variant(font_path string, variant FontVariant) string {
|
||||
// TODO: find some way to make this shorter and more eye-pleasant
|
||||
// NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work
|
||||
mut file := os.file_name(font_path)
|
||||
mut fpath := font_path.replace(file, '')
|
||||
file = file.replace('.ttf', '')
|
||||
|
||||
match variant {
|
||||
.normal {}
|
||||
.bold {
|
||||
if fpath.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', '-Bold')
|
||||
} else if file.starts_with('DejaVuSans') {
|
||||
file += '-Bold'
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
file += 'bd'
|
||||
} else {
|
||||
file += '-bold'
|
||||
}
|
||||
$if macos {
|
||||
if os.exists('SFNS-bold') {
|
||||
file = 'SFNS-bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
.italic {
|
||||
if file.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', '-Italic')
|
||||
} else if file.starts_with('DejaVuSans') {
|
||||
file += '-Oblique'
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
file += 'i'
|
||||
} else {
|
||||
file += 'Italic'
|
||||
}
|
||||
}
|
||||
.mono {
|
||||
if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') {
|
||||
file = file.replace('-Regular', 'Mono-Regular')
|
||||
} else if file.to_lower().starts_with('arial') {
|
||||
// Arial has no mono variant
|
||||
} else {
|
||||
file += 'Mono'
|
||||
}
|
||||
}
|
||||
}
|
||||
return fpath + file + '.ttf'
|
||||
}
|
||||
|
||||
[if debug_font ?]
|
||||
fn debug_font_println(s string) {
|
||||
println(s)
|
||||
|
|
|
@ -232,3 +232,7 @@ const (
|
|||
pub fn color_from_string(s string) Color {
|
||||
return gx.string_colors[s]
|
||||
}
|
||||
|
||||
pub fn (c Color) to_css_string() string {
|
||||
return 'rgb($c.r,$c.g,$c.b)'
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module gx
|
||||
|
||||
pub enum HorizontalAlign {
|
||||
left
|
||||
center
|
||||
right
|
||||
}
|
||||
|
||||
pub enum VerticalAlign {
|
||||
top
|
||||
middle
|
||||
bottom
|
||||
baseline
|
||||
}
|
|
@ -451,7 +451,7 @@ pub interface JS.CanvasRenderingContext2D {
|
|||
getLineDash() JS.Array
|
||||
setLineDash(segments JS.Array)
|
||||
clearRect(x JS.Number, y JS.Number, w JS.Number, h JS.Number)
|
||||
fillRect(x JS.Number, y JS.Number, w JS.null, h JS.Number)
|
||||
fillRect(x JS.Number, y JS.Number, w JS.Number, h JS.Number)
|
||||
strokeRect(x JS.Number, y JS.Number, w JS.Number, h JS.Number)
|
||||
getTransformt() JS.DOMMatrix
|
||||
resetTransform()
|
||||
|
|
|
@ -3,6 +3,7 @@ module os
|
|||
$if js_node {
|
||||
#global.$ENV = $process.env
|
||||
} $else {
|
||||
#const global = $global;
|
||||
#global.$ENV = {}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@ pub mut:
|
|||
is_opened bool
|
||||
}
|
||||
|
||||
#const $buffer = require('buffer');
|
||||
|
||||
$if !js_browser {
|
||||
#const $buffer = require('buffer');
|
||||
}
|
||||
// todo(playX): __as_cast is broken here
|
||||
/*
|
||||
pub struct ErrFileNotOpened {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
module os
|
||||
|
||||
#const $fs = require('fs');
|
||||
#const $path = require('path');
|
||||
#const tty = require('tty')
|
||||
$if js_node {
|
||||
#const $fs = require('fs');
|
||||
#const $path = require('path');
|
||||
#const tty = require('tty')
|
||||
}
|
||||
|
||||
pub const (
|
||||
path_delimiter = '/'
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
module os
|
||||
|
||||
#const $child_process = require('child_process')
|
||||
$if js_node {
|
||||
#const $child_process = require('child_process')
|
||||
}
|
||||
|
||||
// new_process - create a new process descriptor
|
||||
// NB: new does NOT start the new process.
|
||||
|
|
|
@ -827,7 +827,14 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
}
|
||||
// Do not allow empty uninitialized interfaces
|
||||
sym := c.table.sym(field.typ)
|
||||
if sym.kind == .interface_ {
|
||||
mut has_noinit := false
|
||||
for attr in field.attrs {
|
||||
if attr.name == 'noinit' {
|
||||
has_noinit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if sym.kind == .interface_ && (!has_noinit && sym.language != .js) {
|
||||
// TODO: should be an error instead, but first `ui` needs updating.
|
||||
c.note('interface field `${type_sym.name}.$field.name` must be initialized',
|
||||
node.pos)
|
||||
|
|
|
@ -461,10 +461,11 @@ pub fn (mut g JsGen) init() {
|
|||
g.definitions.writeln('const \$process = {')
|
||||
g.definitions.writeln(' arch: "js",')
|
||||
if g.pref.backend == .js_freestanding {
|
||||
g.definitions.writeln(' platform: "freestanding"')
|
||||
g.definitions.writeln(' platform: "freestanding",')
|
||||
} else {
|
||||
g.definitions.writeln(' platform: "browser"')
|
||||
g.definitions.writeln(' platform: "browser",')
|
||||
}
|
||||
g.definitions.writeln(' cwd: function() { return "" }')
|
||||
g.definitions.writeln('}')
|
||||
|
||||
g.definitions.writeln('const \$os = {')
|
||||
|
@ -3263,12 +3264,8 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
|
|||
g.writeln('return tmp')
|
||||
g.dec_indent()
|
||||
g.writeln('})()')
|
||||
} else {
|
||||
if type_sym.kind == .struct_ && type_sym.language == .js {
|
||||
g.writeln('{')
|
||||
} else {
|
||||
g.writeln('new ${g.js_name(name)}({')
|
||||
}
|
||||
} else if type_sym.kind == .struct_ && type_sym.language == .js {
|
||||
g.writeln('{')
|
||||
g.inc_indent()
|
||||
for i, field in it.fields {
|
||||
if field.name.len != 0 {
|
||||
|
@ -3281,11 +3278,26 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
|
|||
g.writeln('')
|
||||
}
|
||||
g.dec_indent()
|
||||
if type_sym.kind == .struct_ && type_sym.language == .js {
|
||||
g.writeln('}')
|
||||
} else {
|
||||
g.writeln('})')
|
||||
|
||||
g.writeln('}')
|
||||
} else {
|
||||
g.writeln('(function() {')
|
||||
g.inc_indent()
|
||||
tmp := g.new_tmp_var()
|
||||
g.writeln('let $tmp = new ${g.js_name(name)}({});')
|
||||
|
||||
for field in it.fields {
|
||||
if field.name.len != 0 {
|
||||
g.write('${tmp}.$field.name = ')
|
||||
g.expr(field.expr)
|
||||
}
|
||||
g.write(';')
|
||||
|
||||
g.writeln('')
|
||||
}
|
||||
g.writeln('return $tmp;')
|
||||
g.dec_indent()
|
||||
g.writeln('})()')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3385,6 +3397,18 @@ fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) {
|
|||
return
|
||||
}
|
||||
|
||||
if (from_type_sym.name == 'Any' && from_type_sym.language == .js)
|
||||
|| from_type_sym.name == 'JS.Any' {
|
||||
if it.typ.is_ptr() {
|
||||
g.write('new \$ref(')
|
||||
}
|
||||
g.expr(it.expr)
|
||||
if it.typ.is_ptr() {
|
||||
g.write(')')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Skip cast if type is the same as the parrent caster
|
||||
tsym := to_type_sym
|
||||
if tsym.kind == .sum_type {
|
||||
|
|
Loading…
Reference in New Issue