aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/gg/gg.c.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/gg/gg.c.v')
-rw-r--r--v_windows/v/vlib/gg/gg.c.v278
1 files changed, 278 insertions, 0 deletions
diff --git a/v_windows/v/vlib/gg/gg.c.v b/v_windows/v/vlib/gg/gg.c.v
new file mode 100644
index 0000000..f6956e6
--- /dev/null
+++ b/v_windows/v/vlib/gg/gg.c.v
@@ -0,0 +1,278 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// 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
+import sokol
+import sokol.sapp
+import sokol.sgl
+import sokol.gfx
+import math
+
+pub struct Event {
+pub mut:
+ frame_count u64
+ typ sapp.EventType
+ key_code KeyCode
+ char_code u32
+ key_repeat bool
+ modifiers u32
+ mouse_button MouseButton
+ mouse_x f32
+ mouse_y f32
+ mouse_dx f32
+ mouse_dy f32
+ scroll_x f32
+ scroll_y f32
+ num_touches int
+ touches [8]C.sapp_touchpoint
+ window_width int
+ window_height int
+ framebuffer_width int
+ framebuffer_height int
+}
+
+[heap]
+pub struct Context {
+mut:
+ render_text bool = true
+ // a cache with all images created by the user. used for sokol image init and to save space
+ // (so that the user can store image ids, not entire Image objects)
+ image_cache []Image
+ needs_refresh bool = true
+ ticks int // for ui mode only
+pub:
+ native_rendering bool
+pub mut:
+ scale f32 = 1.0
+ // will get set to 2.0 for retina, will remain 1.0 for normal
+ width int
+ height int
+ clear_pass C.sg_pass_action
+ window C.sapp_desc
+ timage_pip C.sgl_pipeline
+ config Config
+ ft &FT
+ font_inited bool
+ ui_mode bool // do not redraw everything 60 times/second, but only when the user requests
+ frame u64 // the current frame counted from the start of the application; always increasing
+ //
+ mbtn_mask byte
+ mouse_buttons MouseButtons // typed version of mbtn_mask; easier to use for user programs
+ 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
+}
+
+fn gg_init_sokol_window(user_data voidptr) {
+ mut g := unsafe { &Context(user_data) }
+ desc := sapp.create_desc()
+ /*
+ desc := C.sg_desc{
+ mtl_device: sapp.metal_get_device()
+ mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor
+ mtl_drawable_cb: sapp.metal_get_drawable
+ d3d11_device: sapp.d3d11_get_device()
+ d3d11_device_context: sapp.d3d11_get_device_context()
+ d3d11_render_target_view_cb: sapp.d3d11_get_render_target_view
+ d3d11_depth_stencil_view_cb: sapp.d3d11_get_depth_stencil_view
+ }
+ */
+ gfx.setup(&desc)
+ sgl_desc := C.sgl_desc_t{}
+ sgl.setup(&sgl_desc)
+ g.scale = dpi_scale()
+ // is_high_dpi := sapp.high_dpi()
+ // fb_w := sapp.width()
+ // fb_h := sapp.height()
+ // println('g.scale=$g.scale is_high_dpi=$is_high_dpi fb_w=$fb_w fb_h=$fb_h')
+ // if g.config.init_text {
+ // `os.is_file()` won't work on Android if the font file is embedded into the APK
+ exists := $if !android { os.is_file(g.config.font_path) } $else { true }
+ if g.config.font_path != '' && !exists {
+ g.render_text = false
+ } else if g.config.font_path != '' && exists {
+ // t := time.ticks()
+ g.ft = new_ft(
+ font_path: g.config.font_path
+ custom_bold_font_path: g.config.custom_bold_font_path
+ scale: dpi_scale()
+ ) or { panic(err) }
+ // println('FT took ${time.ticks()-t} ms')
+ g.font_inited = true
+ } else {
+ if g.config.font_bytes_normal.len > 0 {
+ g.ft = new_ft(
+ bytes_normal: g.config.font_bytes_normal
+ bytes_bold: g.config.font_bytes_bold
+ bytes_mono: g.config.font_bytes_mono
+ bytes_italic: g.config.font_bytes_italic
+ scale: sapp.dpi_scale()
+ ) or { panic(err) }
+ g.font_inited = true
+ } else {
+ sfont := system_font_path()
+ if g.config.font_path != '' {
+ eprintln('font file "$g.config.font_path" does not exist, the system font ($sfont) was used instead.')
+ }
+
+ g.ft = new_ft(
+ font_path: sfont
+ custom_bold_font_path: g.config.custom_bold_font_path
+ scale: sapp.dpi_scale()
+ ) or { panic(err) }
+ g.font_inited = true
+ }
+ }
+ //
+ mut pipdesc := C.sg_pipeline_desc{
+ label: c'alpha_image'
+ }
+ unsafe { vmemset(&pipdesc, 0, int(sizeof(pipdesc))) }
+
+ color_state := C.sg_color_state{
+ blend: C.sg_blend_state{
+ enabled: true
+ src_factor_rgb: gfx.BlendFactor(C.SG_BLENDFACTOR_SRC_ALPHA)
+ dst_factor_rgb: gfx.BlendFactor(C.SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA)
+ }
+ }
+ pipdesc.colors[0] = color_state
+
+ g.timage_pip = sgl.make_pipeline(&pipdesc)
+ //
+ if g.config.init_fn != voidptr(0) {
+ g.config.init_fn(g.config.user_data)
+ }
+ // Create images now that we can do that after sg is inited
+ if g.native_rendering {
+ return
+ }
+
+ for i in 0 .. g.image_cache.len {
+ if g.image_cache[i].simg.id == 0 {
+ g.image_cache[i].init_sokol_image()
+ }
+ }
+}
+
+//
+pub fn new_context(cfg Config) &Context {
+ mut g := &Context{
+ width: cfg.width
+ height: cfg.height
+ config: cfg
+ ft: 0
+ ui_mode: cfg.ui_mode
+ native_rendering: cfg.native_rendering
+ }
+ g.set_bg_color(cfg.bg_color)
+ // C.printf('new_context() %p\n', cfg.user_data)
+ window := C.sapp_desc{
+ user_data: g
+ init_userdata_cb: gg_init_sokol_window
+ frame_userdata_cb: gg_frame_fn
+ event_userdata_cb: gg_event_fn
+ fail_userdata_cb: gg_fail_fn
+ cleanup_userdata_cb: gg_cleanup_fn
+ window_title: &char(cfg.window_title.str)
+ html5_canvas_name: &char(cfg.window_title.str)
+ width: cfg.width
+ height: cfg.height
+ sample_count: cfg.sample_count
+ high_dpi: true
+ fullscreen: cfg.fullscreen
+ __v_native_render: cfg.native_rendering
+ }
+ g.window = window
+ return g
+}
+
+pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.Color) {
+ $if macos {
+ if ctx.native_rendering {
+ C.darwin_draw_circle(x - r + 1, ctx.height - (y + r + 3), r, c)
+ return
+ }
+ }
+ if c.a != 255 {
+ sgl.load_pipeline(ctx.timage_pip)
+ }
+ sgl.c4b(c.r, c.g, c.b, c.a)
+ nx := x * ctx.scale
+ ny := y * ctx.scale
+ nr := r * ctx.scale
+ mut theta := f32(0)
+ mut xx := f32(0)
+ mut yy := f32(0)
+ sgl.begin_line_strip()
+ for i := 0; i < segments + 1; i++ {
+ theta = 2.0 * f32(math.pi) * f32(i) / f32(segments)
+ xx = nr * math.cosf(theta)
+ yy = nr * math.sinf(theta)
+ sgl.v2f(xx + nx, yy + ny)
+ }
+ sgl.end()
+}
+
+pub fn high_dpi() bool {
+ return C.sapp_high_dpi()
+}
+
+pub fn screen_size() Size {
+ $if macos {
+ return C.gg_get_screen_size()
+ }
+ // TODO windows, linux, etc
+ return Size{}
+}
+
+fn C.WaitMessage()
+
+/*
+pub fn wait_events() {
+ unsafe {
+ $if macos {
+ #NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny
+ #untilDate:[NSDate distantFuture]
+ #inMode:NSDefaultRunLoopMode
+ #dequeue:YES];
+ #[NSApp sendEvent:event];
+ }
+ $if windows {
+ C.WaitMessage()
+ }
+ }
+}
+*/
+
+// TODO: Fix alpha
+pub fn (ctx &Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
+ $if macos {
+ if ctx.native_rendering {
+ C.darwin_draw_rect(x, ctx.height - (y + h), w, h, c)
+ return
+ }
+ }
+ if c.a != 255 {
+ sgl.load_pipeline(ctx.timage_pip)
+ }
+ sgl.c4b(c.r, c.g, c.b, c.a)
+ sgl.begin_quads()
+ sgl.v2f(x * ctx.scale, y * ctx.scale)
+ sgl.v2f((x + w) * ctx.scale, y * ctx.scale)
+ sgl.v2f((x + w) * ctx.scale, (y + h) * ctx.scale)
+ sgl.v2f(x * ctx.scale, (y + h) * ctx.scale)
+ sgl.end()
+}