gg, gx: deprecate gx and replace all occurences with gg (which now contains all the functionality of gx) (#24966)
Some checks failed
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
Workflow Lint / lint-yml-workflows (push) Has been cancelled

This commit is contained in:
Eliyaan (Nopana) 2025-08-14 18:53:56 +02:00 committed by GitHub
parent 64ad7c73e8
commit bbb61ab368
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 1061 additions and 881 deletions

View file

@ -1,5 +1,4 @@
import gg
import gx
import math
import math.easing
import os.asset
@ -52,76 +51,76 @@ mut:
}
struct Theme {
bg_color gx.Color
padding_color gx.Color
text_color gx.Color
game_over_color gx.Color
victory_color gx.Color
tile_colors []gx.Color
bg_color gg.Color
padding_color gg.Color
text_color gg.Color
game_over_color gg.Color
victory_color gg.Color
tile_colors []gg.Color
}
const themes = [
&Theme{
bg_color: gx.rgb(250, 248, 239)
padding_color: gx.rgb(143, 130, 119)
victory_color: gx.rgb(100, 160, 100)
game_over_color: gx.rgb(190, 50, 50)
text_color: gx.black
bg_color: gg.rgb(250, 248, 239)
padding_color: gg.rgb(143, 130, 119)
victory_color: gg.rgb(100, 160, 100)
game_over_color: gg.rgb(190, 50, 50)
text_color: gg.black
tile_colors: [
gx.rgb(205, 193, 180), // Empty / 0 tile
gx.rgb(238, 228, 218), // 2
gx.rgb(237, 224, 200), // 4
gx.rgb(242, 177, 121), // 8
gx.rgb(245, 149, 99), // 16
gx.rgb(246, 124, 95), // 32
gx.rgb(246, 94, 59), // 64
gx.rgb(237, 207, 114), // 128
gx.rgb(237, 204, 97), // 256
gx.rgb(237, 200, 80), // 512
gx.rgb(237, 197, 63), // 1024
gx.rgb(237, 194, 46),
gg.rgb(205, 193, 180), // Empty / 0 tile
gg.rgb(238, 228, 218), // 2
gg.rgb(237, 224, 200), // 4
gg.rgb(242, 177, 121), // 8
gg.rgb(245, 149, 99), // 16
gg.rgb(246, 124, 95), // 32
gg.rgb(246, 94, 59), // 64
gg.rgb(237, 207, 114), // 128
gg.rgb(237, 204, 97), // 256
gg.rgb(237, 200, 80), // 512
gg.rgb(237, 197, 63), // 1024
gg.rgb(237, 194, 46),
]
},
&Theme{
bg_color: gx.rgb(55, 55, 55)
padding_color: gx.rgb(68, 60, 59)
victory_color: gx.rgb(100, 160, 100)
game_over_color: gx.rgb(190, 50, 50)
text_color: gx.white
bg_color: gg.rgb(55, 55, 55)
padding_color: gg.rgb(68, 60, 59)
victory_color: gg.rgb(100, 160, 100)
game_over_color: gg.rgb(190, 50, 50)
text_color: gg.white
tile_colors: [
gx.rgb(123, 115, 108),
gx.rgb(142, 136, 130),
gx.rgb(142, 134, 120),
gx.rgb(145, 106, 72),
gx.rgb(147, 89, 59),
gx.rgb(147, 74, 57),
gx.rgb(147, 56, 35),
gx.rgb(142, 124, 68),
gx.rgb(142, 122, 58),
gx.rgb(142, 120, 48),
gx.rgb(142, 118, 37),
gx.rgb(142, 116, 27),
gg.rgb(123, 115, 108),
gg.rgb(142, 136, 130),
gg.rgb(142, 134, 120),
gg.rgb(145, 106, 72),
gg.rgb(147, 89, 59),
gg.rgb(147, 74, 57),
gg.rgb(147, 56, 35),
gg.rgb(142, 124, 68),
gg.rgb(142, 122, 58),
gg.rgb(142, 120, 48),
gg.rgb(142, 118, 37),
gg.rgb(142, 116, 27),
]
},
&Theme{
bg_color: gx.rgb(38, 38, 66)
padding_color: gx.rgb(58, 50, 74)
victory_color: gx.rgb(100, 160, 100)
game_over_color: gx.rgb(190, 50, 50)
text_color: gx.white
bg_color: gg.rgb(38, 38, 66)
padding_color: gg.rgb(58, 50, 74)
victory_color: gg.rgb(100, 160, 100)
game_over_color: gg.rgb(190, 50, 50)
text_color: gg.white
tile_colors: [
gx.rgb(92, 86, 140),
gx.rgb(106, 99, 169),
gx.rgb(106, 97, 156),
gx.rgb(108, 79, 93),
gx.rgb(110, 66, 76),
gx.rgb(110, 55, 74),
gx.rgb(110, 42, 45),
gx.rgb(106, 93, 88),
gx.rgb(106, 91, 75),
gx.rgb(106, 90, 62),
gx.rgb(106, 88, 48),
gx.rgb(106, 87, 35),
gg.rgb(92, 86, 140),
gg.rgb(106, 99, 169),
gg.rgb(106, 97, 156),
gg.rgb(108, 79, 93),
gg.rgb(110, 66, 76),
gg.rgb(110, 55, 74),
gg.rgb(110, 42, 45),
gg.rgb(106, 93, 88),
gg.rgb(106, 91, 75),
gg.rgb(106, 90, 62),
gg.rgb(106, 88, 48),
gg.rgb(106, 87, 35),
]
},
]
@ -518,32 +517,32 @@ fn (mut app App) ai_move() {
app.move(bestprediction.move)
}
fn (app &App) label_format(kind LabelKind) gx.TextCfg {
fn (app &App) label_format(kind LabelKind) gg.TextCfg {
match kind {
.keys {
return gx.TextCfg{
color: gx.Color{150, 150, 255, 200}
return gg.TextCfg{
color: gg.Color{150, 150, 255, 200}
align: .center
vertical_align: .bottom
size: app.ui.font_size / 4
}
}
.points {
return gx.TextCfg{
color: if app.state in [.over, .victory] { gx.white } else { app.theme.text_color }
return gg.TextCfg{
color: if app.state in [.over, .victory] { gg.white } else { app.theme.text_color }
align: .left
size: app.ui.font_size / 2
}
}
.moves {
return gx.TextCfg{
color: if app.state in [.over, .victory] { gx.white } else { app.theme.text_color }
return gg.TextCfg{
color: if app.state in [.over, .victory] { gg.white } else { app.theme.text_color }
align: .right
size: app.ui.font_size / 2
}
}
.tile {
return gx.TextCfg{
return gg.TextCfg{
color: app.theme.text_color
align: .center
vertical_align: .middle
@ -551,7 +550,7 @@ fn (app &App) label_format(kind LabelKind) gx.TextCfg {
}
}
.victory {
return gx.TextCfg{
return gg.TextCfg{
color: app.theme.victory_color
align: .center
vertical_align: .middle
@ -559,7 +558,7 @@ fn (app &App) label_format(kind LabelKind) gx.TextCfg {
}
}
.game_over {
return gx.TextCfg{
return gg.TextCfg{
color: app.theme.game_over_color
align: .center
vertical_align: .middle
@ -567,8 +566,8 @@ fn (app &App) label_format(kind LabelKind) gx.TextCfg {
}
}
.score_end {
return gx.TextCfg{
color: gx.white
return gg.TextCfg{
color: gg.white
align: .center
vertical_align: .middle
size: app.ui.font_size * 3 / 4
@ -623,18 +622,18 @@ fn (app &App) draw() {
app.draw_tiles()
// TODO: Make transparency work in `gg`
if app.state == .over {
app.gg.draw_rect_filled(0, 0, ww, wh, gx.rgba(10, 0, 0, 180))
app.gg.draw_rect_filled(0, 0, ww, wh, gg.rgba(10, 0, 0, 180))
app.gg.draw_text(ww / 2, (m * 4 / 10) + ypad, 'Game Over', app.label_format(.game_over))
f := app.label_format(.tile)
msg := $if android { 'Tap to restart' } $else { 'Press `r` to restart' }
app.gg.draw_text(ww / 2, (m * 6 / 10) + ypad, msg, gx.TextCfg{
app.gg.draw_text(ww / 2, (m * 6 / 10) + ypad, msg, gg.TextCfg{
...f
color: gx.white
color: gg.white
size: f.size * 3 / 4
})
}
if app.state == .victory {
app.gg.draw_rect_filled(0, 0, ww, wh, gx.rgba(0, 10, 0, 180))
app.gg.draw_rect_filled(0, 0, ww, wh, gg.rgba(0, 10, 0, 180))
app.gg.draw_text(ww / 2, (m * 4 / 10) + ypad, 'Victory!', app.label_format(.victory))
// f := app.label_format(.tile)
msg1 := $if android { 'Tap to continue' } $else { 'Press `space` to continue' }
@ -726,7 +725,7 @@ fn (app &App) draw_one_tile(x int, y int, tidx int) {
xpos := xoffset + tw / 2
ypos := yoffset + th / 2
mut fmt := app.label_format(.tile)
fmt = gx.TextCfg{
fmt = gg.TextCfg{
...fmt
size: int(anim_size * (fmt.size - 1))
}
@ -741,15 +740,15 @@ fn (app &App) draw_one_tile(x int, y int, tidx int) {
app.gg.draw_text(xpos, ypos, '2', fmt)
fs2 := int(f32(fmt.size) * 0.67)
app.gg.draw_text(xpos + app.ui.tile_size / 10, ypos - app.ui.tile_size / 8,
'${tidx}', gx.TextCfg{
'${tidx}', gg.TextCfg{
...fmt
size: fs2
align: gx.HorizontalAlign.left
align: gg.HorizontalAlign.left
})
}
.shifts {
fs2 := int(f32(fmt.size) * 0.6)
app.gg.draw_text(xpos, ypos, '2<<${tidx - 1}', gx.TextCfg{
app.gg.draw_text(xpos, ypos, '2<<${tidx - 1}', gg.TextCfg{
...fmt
size: fs2
})
@ -757,7 +756,7 @@ fn (app &App) draw_one_tile(x int, y int, tidx int) {
.none {} // Don't draw any text here, colors only
.end {} // Should never get here
}
// oidx_fmt := gx.TextCfg{...fmt,size: 14}
// oidx_fmt := gg.TextCfg{...fmt,size: 14}
// app.gg.draw_text(xoffset + 50, yoffset + 15, 'y:${oidx >> 16}|x:${oidx & 0xFFFF}|m:${app.mtickers[y][x]:5.3f}', oidx_fmt)
// app.gg.draw_text(xoffset + 52, yoffset + 30, 'ox:${ox}|oy:${oy}', oidx_fmt)
// app.gg.draw_text(xoffset + 52, yoffset + 85, 'dx:${dx}|dy:${dy}', oidx_fmt)

View file

@ -4,7 +4,6 @@
module main
import gg
import gx
import math
import rand
import os.asset
@ -86,8 +85,8 @@ mut:
frames int
text string
size int = 40
color gx.Color
align gx.HorizontalAlign = .center
color gg.Color
align gg.HorizontalAlign = .center
}
fn (mut a Asteroid) setup() {
@ -172,7 +171,7 @@ fn (mut game Game) update() {
game.split_asteroid(a, p.vel.mul_scalar(0.5))
game.player.reset(game.screen)
game.score += 50
game.show_message(text: 'Your ship was destroyed.', color: gx.red, frames: 90)
game.show_message(text: 'Your ship was destroyed.', color: gg.red, frames: 90)
game.ships--
if game.ships <= 0 {
game.ships = 5
@ -210,7 +209,7 @@ fn (mut game Game) update() {
game.ships++
game.player.reset(game.screen)
game.add_asteroids(10)
game.show_message(text: 'YOU WIN', color: gx.green, frames: 90)
game.show_message(text: 'YOU WIN', color: gg.green, frames: 90)
}
game.highscore = int_max(game.score, game.highscore)
}
@ -247,21 +246,21 @@ fn (mut game Game) split_asteroid(a &Asteroid, vel V2) {
fn (mut game Game) draw() {
ws := gg.window_size()
game.screen = V2{ws.width, ws.height}
game.gg.draw_rect_filled(0, 0, game.screen.x, game.screen.y, gx.rgba(20, 20, 20, 255))
game.gg.draw_rect_filled(0, 0, game.screen.x, game.screen.y, gg.rgba(20, 20, 20, 255))
game.draw_ship()
for b in game.bullets {
game.gg.draw_circle_filled(b.pos.x, b.pos.y, 3, gx.yellow)
game.gg.draw_circle_filled(b.pos.x, b.pos.y, 3, gg.yellow)
}
for mut a in game.asteroids {
game.draw_asteroid(mut a)
}
scenter := game.screen.div_scalar(2)
label1 := 'Level: ${game.level} Ships: ${game.ships}'
game.gg.draw_text(5, 10, label1, size: 20, color: gx.white, align: .left)
game.gg.draw_text(5, 10, label1, size: 20, color: gg.white, align: .left)
label2 := 'B: ${game.player.bullets:02} F: ${game.player.fuel:04}'
game.gg.draw_text(int(scenter.x), 10, label2, size: 20, color: gx.green, align: .center)
game.gg.draw_text(int(scenter.x), 10, label2, size: 20, color: gg.green, align: .center)
label3 := 'Score: ${game.score} Highscore: ${game.highscore}'
game.gg.draw_text(int(game.screen.x) - 5, 10, label3, size: 20, color: gx.white, align: .right)
game.gg.draw_text(int(game.screen.x) - 5, 10, label3, size: 20, color: gg.white, align: .right)
if game.msg.frames > 0 {
game.gg.draw_text(int(scenter.x), int(scenter.y / 2), game.msg.text,
size: game.msg.size
@ -272,7 +271,7 @@ fn (mut game Game) draw() {
label4 := 'Use arrows + space to control your ship. Use Escape to end the game.'
game.gg.draw_text(int(game.screen.x - 5), int(game.screen.y - 20), label4,
size: 16
color: gx.gray
color: gg.gray
align: .right
)
}
@ -295,10 +294,10 @@ fn (game &Game) draw_ship() {
p.points[5] = p3.y
p.points[6] = p4.x
p.points[7] = p4.y
game.gg.draw_convex_poly(p.points, gx.white)
game.gg.draw_convex_poly(p.points, gg.white)
if p.is_engine_on {
engine := p.pos.offset(angle + math.pi, 0.7 * p.radius)
game.gg.draw_circle_filled(engine.x, engine.y, 6, gx.yellow)
game.gg.draw_circle_filled(engine.x, engine.y, 6, gg.yellow)
}
}
@ -306,13 +305,13 @@ fn (mut game Game) draw_asteroid(mut a Asteroid) {
if !a.active {
return
}
game.gg.draw_circle_filled(a.pos.x, a.pos.y, a.radius, gx.rgba(235, 235, 255, 215))
game.gg.draw_circle_filled(a.pos.x, a.pos.y, a.radius, gg.rgba(235, 235, 255, 215))
for i in 0 .. a.segments {
angle := rads(a.rotation + f32(i) * 360 / a.segments)
p := a.pos.offset(angle, a.offsets[i])
a.points[i * 2], a.points[i * 2 + 1] = p.x, p.y
}
game.gg.draw_convex_poly(a.points, gx.rgba(155, 155, 148, 245))
game.gg.draw_convex_poly(a.points, gg.rgba(155, 155, 148, 245))
}
fn (mut game Game) add_bullet() {

View file

@ -1,5 +1,4 @@
import gg
import gx
import math
import rand
import sokol.audio
@ -11,8 +10,8 @@ const designed_height = 800
const brick_width = 53
const brick_height = 20
const bevel_size = int(brick_height * 0.18)
const highlight_color = gx.rgba(255, 255, 255, 65)
const shade_color = gx.rgba(0, 0, 0, 65)
const highlight_color = gg.rgba(255, 255, 255, 65)
const shade_color = gg.rgba(0, 0, 0, 65)
struct Brick {
mut:
@ -108,7 +107,7 @@ fn (mut g Game) init_bricks() {
g.bricks << Brick{
x: col * (brick_width + 1) + xoffset
y: row * (brick_height + 1) + yoffset
c: gx.rgb(0x40 | rand.u8(), 0x40 | rand.u8(), 0x40 | rand.u8())
c: gg.rgb(0x40 | rand.u8(), 0x40 | rand.u8(), 0x40 | rand.u8())
value: 10 - row
}
g.nbricks++
@ -139,15 +138,15 @@ fn (mut g Game) draw() {
}
label1 := 'Level: ${g.nlevels:02} Points: ${g.npoints:06}'
label2 := 'Bricks: ${g.nbricks:03} Paddles: ${g.npaddles:02}'
g.ctx.draw_text(5, 3, label1, size: 24, color: gx.rgb(255, 255, 255))
g.ctx.draw_text(320, 3, label2, size: 24, color: gx.rgb(255, 255, 255))
g.ctx.draw_text(5, 3, label1, size: 24, color: gg.rgb(255, 255, 255))
g.ctx.draw_text(320, 3, label2, size: 24, color: gg.rgb(255, 255, 255))
sgl.pop_matrix()
g.ctx.end()
}
fn (g &Game) draw_ball() {
g.ctx.draw_circle_filled(g.ball_x, g.ball_y, g.ball_r, gx.red)
g.ctx.draw_circle_filled(g.ball_x, g.ball_y, g.ball_r, gg.red)
mut ball_r_less := g.ball_r
for _ in 0 .. 3 {
ball_r_less *= 0.8
@ -158,10 +157,10 @@ fn (g &Game) draw_ball() {
fn (g &Game) draw_paddle() {
roffset, rradius := -5, 18
g.ctx.draw_circle_filled(g.paddle_x - roffset, g.height, rradius, gx.blue)
g.ctx.draw_circle_filled(g.paddle_x + g.paddle_w + roffset, g.height, rradius, gx.blue)
g.ctx.draw_circle_filled(g.paddle_x - roffset, g.height, rradius, gg.blue)
g.ctx.draw_circle_filled(g.paddle_x + g.paddle_w + roffset, g.height, rradius, gg.blue)
g.ctx.draw_rect_filled(g.paddle_x, g.height - g.paddle_h + 2, g.paddle_w, g.paddle_h,
gx.blue)
gg.blue)
g.ctx.draw_rect_filled(g.paddle_x, g.height - g.paddle_h + 2, g.paddle_w, bevel_size,
highlight_color)
}

View file

@ -3,7 +3,6 @@
// Written by Stefan Schroeder in 2021 for the v project examples.
// See LICENSE for license information.
import gg
import gx
import math
import time
@ -19,13 +18,13 @@ const th = 25
// Padding of tic-mark to window border
const tp = 10
const tic_color = gx.Color{
const tic_color = gg.Color{
r: 50
g: 50
b: 50
}
const hand_color = gx.black
const second_hand_color = gx.red
const hand_color = gg.black
const second_hand_color = gg.red
struct App {
minutes_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw,
@ -85,7 +84,7 @@ fn on_frame(mut app App) {
// Rotate a polygon round the centerpoint
@[manualfree]
fn draw_convex_poly_rotate(mut ctx gg.Context, dpi_scale f32, points []f32, c gx.Color, angle f32) {
fn draw_convex_poly_rotate(mut ctx gg.Context, dpi_scale f32, points []f32, c gg.Color, angle f32) {
sa := math.sin(math.pi * angle / 180.0)
ca := math.cos(math.pi * angle / 180.0)
@ -151,7 +150,7 @@ fn main() {
width: design_size
height: design_size
window_title: 'Clock!'
bg_color: gx.white
bg_color: gg.white
user_data: app
frame_fn: on_frame
event_fn: on_event

View file

@ -1,6 +1,5 @@
import objects
import gg
import gx
import rand
struct App {
@ -99,7 +98,7 @@ fn main() {
width: app.ui.width
height: app.ui.height
window_title: 'Fireworks!'
bg_color: gx.black
bg_color: gg.black
user_data: app
frame_fn: on_frame
event_fn: on_event

View file

@ -1,10 +1,10 @@
module objects
import gx
import gg
import rand
pub fn random_color() gx.Color {
return gx.Color{
pub fn random_color() gg.Color {
return gg.Color{
r: rand.u8()
g: rand.u8()
b: rand.u8()

View file

@ -1,11 +1,10 @@
module objects
import gg
import gx
pub struct Particle {
pub mut:
color gx.Color
color gg.Color
pos Vector
vel Vector
accel Vector

View file

@ -1,12 +1,11 @@
module objects
import gg
import gx
import rand
pub struct Rocket {
pub mut:
color gx.Color
color gg.Color
pos Vector
vel Vector
accel Vector

View file

@ -1,12 +1,11 @@
module main
import gg
import gx
import automaton
const screen_width = 800
const screen_height = 600
const filled_color = gx.blue
const filled_color = gg.blue
@[live]
fn print_automaton(app &App) {
@ -40,14 +39,14 @@ fn main() {
a: automaton.gun()
}
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
frame_fn: frame
user_data: &app
width: screen_width
height: screen_height
create_window: true
resizable: false
window_title: 'v life (with gg, gx)'
window_title: 'v life (with gg)'
)
app.gg.run()
}

View file

@ -2,7 +2,6 @@ module main
import os
import gg
import gx
import math
@[heap]
@ -42,7 +41,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: myconfig.img_rect.x + f32(math.sin(f32(window.ctx.frame) / 10.0) * 60)
y: myconfig.img_rect.y + f32(math.cos(f32(window.ctx.frame) / 10.0) * 60)
}
color: gx.Color{255, 0, 0, 255}
color: gg.Color{255, 0, 0, 255}
effect: .add
})
@ -54,7 +53,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: myconfig.img_rect.x + f32(math.sin(f32(window.ctx.frame) / 10.0) * 80)
y: myconfig.img_rect.y + f32(math.cos(f32(window.ctx.frame) / 10.0) * 80)
}
color: gx.Color{0, 255, 0, 255}
color: gg.Color{0, 255, 0, 255}
effect: .add
})
@ -66,7 +65,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: myconfig.img_rect.x + f32(math.sin(f32(window.ctx.frame) / 10.0) * 100)
y: myconfig.img_rect.y + f32(math.cos(f32(window.ctx.frame) / 10.0) * 100)
}
color: gx.Color{0, 0, 255, 255}
color: gg.Color{0, 0, 255, 255}
effect: .add
})
@ -78,7 +77,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: 50
y: 0
}
color: gx.Color{255, 0, 0, 255}
color: gg.Color{255, 0, 0, 255}
effect: .add
})
@ -89,7 +88,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: 50
y: 50
}
color: gx.Color{0, 255, 0, 255}
color: gg.Color{0, 255, 0, 255}
effect: .add
})
@ -100,7 +99,7 @@ pub fn (mut window Window) draw(_ voidptr) {
x: 50
y: 100
}
color: gx.Color{0, 0, 255, 255}
color: gg.Color{0, 0, 255, 255}
effect: .add
})
@ -115,7 +114,7 @@ fn main() {
width: 800
height: 600
user_data: window
bg_color: gx.gray
bg_color: gg.gray
// FNs
init_fn: window.init
frame_fn: window.draw

View file

@ -1,16 +1,15 @@
module main
import gg
import gx
import math
const win_width = 700
const win_height = 800
const bg_color = gx.white
const bg_color = gg.white
// A transparent color is used to aid in verifying that
// rendering is precise on each of the arc types (e.g. no overlapping or double rendered slices)
const colour = gx.rgba(100, 100, 0, 100)
const colour = gg.rgba(100, 100, 0, 100)
enum Selection {
segs = 0

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
const points = [f32(200.0), 200.0, 200.0, 100.0, 400.0, 100.0, 400.0, 300.0]
@ -14,7 +13,7 @@ mut:
fn main() {
mut app := &App{}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Cubic Bézier curve'
@ -31,8 +30,8 @@ fn (mut app App) change(delta int) {
fn frame(mut app App) {
app.gg.begin()
app.gg.draw_cubic_bezier_in_steps(points, u32(app.steps), gx.blue)
app.gg.draw_cubic_bezier_recursive(points, gx.rgba(255, 50, 50, 150))
app.gg.draw_cubic_bezier_in_steps(points, u32(app.steps), gg.blue)
app.gg.draw_cubic_bezier_recursive(points, gg.rgba(255, 50, 50, 150))
app.gg.end()
if app.gg.pressed_keys[int(gg.KeyCode.down)] {
app.change(-1)

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
const rate = f32(1) / 60 * 10
@ -34,7 +33,7 @@ fn main() {
anim: &Anim{}
}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Animated cubic Bézier curve'
@ -61,7 +60,7 @@ fn frame(mut app App) {
points := [p1_x, p1_y, ctrl_p1_x, ctrl_p1_y, ctrl_p2_x, ctrl_p2_y, p2_x, p2_y]
app.gg.begin()
app.gg.draw_cubic_bezier(points, gx.blue)
app.gg.draw_cubic_bezier(points, gg.blue)
app.gg.end()
app.anim.advance()
}

View file

@ -1,12 +1,11 @@
module main
import gg
import gx
import sokol.sapp
fn main() {
mut ctx := gg.new_context(
bg_color: gx.white
bg_color: gg.white
window_title: 'Cursor'
frame_fn: frame
init_fn: init

View file

@ -2,7 +2,6 @@
module main
import gg
import gx
import rand
import time
@ -37,7 +36,7 @@ fn main() {
fn rain(mut app App) {
app.ctx = gg.new_context(
bg_color: gx.rgb(0, 0, 0)
bg_color: gg.rgb(0, 0, 0)
width: app.screen_size.width
height: app.screen_size.height
user_data: app
@ -84,7 +83,7 @@ fn frame(mut app App) {
draw_rain_column(rc, app)
}
app.ctx.draw_text(app.screen_size.width / 2 - 190, app.screen_size.height - 15, 'press `f` to toggle fullscreen, Up/Down arrows to change speed',
color: gx.gray
color: gg.gray
)
app.ctx.end()
vprintln('frame: ${app.ctx.frame} | app.cols: ${app.cols} | app.rows: ${app.rows} | app.rain_columns.len: ${app.rain_columns.len} | app.delay: ${app.delay}')
@ -98,9 +97,9 @@ fn vprintln(msg string) {
fn calc_sizes(mut app App) {
app.screen_size = gg.window_size()
app.ctx.set_text_cfg(gx.TextCfg{
app.ctx.set_text_cfg(gg.TextCfg{
size: font_size
color: gx.green
color: gg.green
mono: true
})
// figure out how big character is in pixels
@ -138,7 +137,7 @@ fn draw_rain_column(rc RainColumn, app App) {
else { u8(255) }
}
at_head := i == rc.head - 1
cfg := gx.TextCfg{
cfg := gg.TextCfg{
size: font_size
color: gg.Color{
r: if at_head { u8(255) } else { 0 }

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
import sokol.sapp
const max_files = 12
@ -16,7 +15,7 @@ mut:
fn main() {
mut app := &App{}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Drag and drop'
@ -45,8 +44,8 @@ fn my_event_manager(mut ev gg.Event, mut app App) {
fn frame(mut app App) {
app.gg.begin()
mut txt_conf := gx.TextCfg{
color: gx.black
mut txt_conf := gg.TextCfg{
color: gg.black
align: .left
size: int(text_size * app.gg.scale + 0.5)
}

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
struct App {
mut:
@ -28,7 +27,7 @@ fn main() {
pixels: pixels
}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 100
height: 100
window_title: 'Set Pixels'
@ -42,12 +41,12 @@ fn frame(mut app App) {
app.gg.begin()
// Draw a blue pixel near each corner. (Find your magnifying glass)
app.gg.draw_pixel(2, 2, gx.blue)
app.gg.draw_pixel(app.gg.width - 2, 2, gx.blue)
app.gg.draw_pixel(app.gg.width - 2, app.gg.height - 2, gx.blue)
app.gg.draw_pixel(2, app.gg.height - 2, gx.blue)
app.gg.draw_pixel(2, 2, gg.blue)
app.gg.draw_pixel(app.gg.width - 2, 2, gg.blue)
app.gg.draw_pixel(app.gg.width - 2, app.gg.height - 2, gg.blue)
app.gg.draw_pixel(2, app.gg.height - 2, gg.blue)
// Draw pixels in a grid-like pattern.
app.gg.draw_pixels(app.pixels, gx.red)
app.gg.draw_pixels(app.pixels, gg.red)
app.gg.end()
}

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
import math.easing
const all = {
@ -60,8 +59,8 @@ mut:
fn (mut app App) draw_circle(label string, f easing.EasingFN) {
offset := 30
app.gg.draw_text_def(int(app.x) - 30, 5, label)
app.gg.draw_line(f32(app.x), offset, f32(app.x), f32(app.h + offset), gx.gray)
app.gg.draw_circle_filled(f32(app.x), f32(offset + f(app.t) * app.h), 10, gx.rgb(0,
app.gg.draw_line(f32(app.x), offset, f32(app.x), f32(app.h + offset), gg.gray)
app.gg.draw_circle_filled(f32(app.x), f32(offset + f(app.t) * app.h), 10, gg.rgb(0,
0, 255))
app.x += 120
}
@ -73,7 +72,7 @@ fn (mut app App) frame() {
app.x = 80
app.h = size.height - 100
app.gg.begin()
app.gg.draw_line(0, f32(app.h + 30), size.width, f32(app.h + 30), gx.gray)
app.gg.draw_line(0, f32(app.h + 30), size.width, f32(app.h + 30), gg.gray)
current_map := unsafe { all[app.kind].clone() }
for k, e in current_map {
app.draw_circle(k, e)
@ -100,7 +99,7 @@ fn (mut app App) on_event(ev &gg.Event, x voidptr) {
mut app := &App{}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 1350
height: 800
window_title: 'Easing functions'

View file

@ -1,6 +1,5 @@
// Use `v -d show_fps run examples/gg/fire.v` to show a fire effect with an FPS counter.
import gg
import gx
import rand
const win_width = 800
@ -9,43 +8,43 @@ const width = 100
const height = 140
const scale = 4
const palette = [
gx.rgb(0x07, 0x07, 0x07),
gx.rgb(0x1f, 0x07, 0x07),
gx.rgb(0x2f, 0x0f, 0x07),
gx.rgb(0x47, 0x0f, 0x07),
gx.rgb(0x57, 0x17, 0x07),
gx.rgb(0x67, 0x1f, 0x07),
gx.rgb(0x77, 0x1f, 0x07),
gx.rgb(0x8f, 0x27, 0x07),
gx.rgb(0x9f, 0x2f, 0x07),
gx.rgb(0xaf, 0x3f, 0x07),
gx.rgb(0xbf, 0x47, 0x07),
gx.rgb(0xc7, 0x47, 0x07),
gx.rgb(0xdf, 0x4f, 0x07),
gx.rgb(0xdf, 0x57, 0x07),
gx.rgb(0xdf, 0x57, 0x07),
gx.rgb(0xd7, 0x5f, 0x07),
gx.rgb(0xd7, 0x5f, 0x07),
gx.rgb(0xd7, 0x67, 0x0f),
gx.rgb(0xcf, 0x6f, 0x0f),
gx.rgb(0xcf, 0x77, 0x0f),
gx.rgb(0xcf, 0x7f, 0x0f),
gx.rgb(0xcf, 0x87, 0x17),
gx.rgb(0xc7, 0x87, 0x17),
gx.rgb(0xc7, 0x8f, 0x17),
gx.rgb(0xc7, 0x97, 0x1f),
gx.rgb(0xbf, 0x9f, 0x1f),
gx.rgb(0xbf, 0x9f, 0x1f),
gx.rgb(0xbf, 0xa7, 0x27),
gx.rgb(0xbf, 0xa7, 0x27),
gx.rgb(0xbf, 0xaf, 0x2f),
gx.rgb(0xb7, 0xaf, 0x2f),
gx.rgb(0xb7, 0xb7, 0x2f),
gx.rgb(0xb7, 0xb7, 0x37),
gx.rgb(0xcf, 0xcf, 0x6f),
gx.rgb(0xdf, 0xdf, 0x9f),
gx.rgb(0xef, 0xef, 0xc7),
gx.rgb(0xff, 0xff, 0xff),
gg.rgb(0x07, 0x07, 0x07),
gg.rgb(0x1f, 0x07, 0x07),
gg.rgb(0x2f, 0x0f, 0x07),
gg.rgb(0x47, 0x0f, 0x07),
gg.rgb(0x57, 0x17, 0x07),
gg.rgb(0x67, 0x1f, 0x07),
gg.rgb(0x77, 0x1f, 0x07),
gg.rgb(0x8f, 0x27, 0x07),
gg.rgb(0x9f, 0x2f, 0x07),
gg.rgb(0xaf, 0x3f, 0x07),
gg.rgb(0xbf, 0x47, 0x07),
gg.rgb(0xc7, 0x47, 0x07),
gg.rgb(0xdf, 0x4f, 0x07),
gg.rgb(0xdf, 0x57, 0x07),
gg.rgb(0xdf, 0x57, 0x07),
gg.rgb(0xd7, 0x5f, 0x07),
gg.rgb(0xd7, 0x5f, 0x07),
gg.rgb(0xd7, 0x67, 0x0f),
gg.rgb(0xcf, 0x6f, 0x0f),
gg.rgb(0xcf, 0x77, 0x0f),
gg.rgb(0xcf, 0x7f, 0x0f),
gg.rgb(0xcf, 0x87, 0x17),
gg.rgb(0xc7, 0x87, 0x17),
gg.rgb(0xc7, 0x8f, 0x17),
gg.rgb(0xc7, 0x97, 0x1f),
gg.rgb(0xbf, 0x9f, 0x1f),
gg.rgb(0xbf, 0x9f, 0x1f),
gg.rgb(0xbf, 0xa7, 0x27),
gg.rgb(0xbf, 0xa7, 0x27),
gg.rgb(0xbf, 0xaf, 0x2f),
gg.rgb(0xb7, 0xaf, 0x2f),
gg.rgb(0xb7, 0xb7, 0x2f),
gg.rgb(0xb7, 0xb7, 0x37),
gg.rgb(0xcf, 0xcf, 0x6f),
gg.rgb(0xdf, 0xdf, 0x9f),
gg.rgb(0xef, 0xef, 0xc7),
gg.rgb(0xff, 0xff, 0xff),
]!
struct App {

View file

@ -1,5 +1,4 @@
import gg
import gx
import runtime
import time
@ -40,8 +39,8 @@ mut:
ntasks int = runtime.nr_jobs()
}
const colors = [gx.black, gx.blue, gx.red, gx.green, gx.yellow, gx.orange, gx.purple, gx.white,
gx.indigo, gx.violet, gx.black, gx.blue, gx.orange, gx.yellow, gx.green].map(u32(it.abgr8()))
const colors = [gg.black, gg.blue, gg.red, gg.green, gg.yellow, gg.orange, gg.purple, gg.white,
gg.indigo, gg.violet, gg.black, gg.blue, gg.orange, gg.yellow, gg.green].map(u32(it.abgr8()))
struct MandelChunk {
cview ViewRect

View file

@ -1,13 +1,12 @@
module main
import gg
import gx
import rand
const max_circles_per_pass = 1000
// prepare some random colors ahead of time
const colors = []gx.Color{len: max_circles_per_pass, init: gx.Color{
const colors = []gg.Color{len: max_circles_per_pass, init: gg.Color{
r: u8(index * 0 + rand.u8())
g: u8(index * 0 + rand.u8())
b: u8(index * 0 + rand.u8())
@ -47,7 +46,7 @@ fn frame(mut ctx gg.Context) {
fn main() {
mut ctx := gg.new_context(
window_title: 'Many Thousands of Circles'
bg_color: gx.black
bg_color: gg.black
width: 600
height: 400
frame_fn: frame

View file

@ -1,11 +1,10 @@
module main
import gg
import gx
import rand
import time
const cover = gx.rgba(85, 200, 85, 255)
const cover = gg.rgba(85, 200, 85, 255)
const csize = 120 // cell size in pixels
const letters = 'AABBOOCCVVXXYYZZMMKKHHTT'.split('')
const header_size = 30
@ -45,9 +44,9 @@ fn (mut g Game) draw_cell(i int, cell Cell) {
rect_x, rect_y := x * csize, header_size + y * csize
if g.cells[i].is_open || g.sw.elapsed().milliseconds() <= 1000 {
lsize := 96
g.ctx.draw_rect_empty(rect_x + 6, rect_y + 6, csize - 10, csize - 10, gx.light_gray)
g.ctx.draw_rect_empty(rect_x + 6, rect_y + 6, csize - 10, csize - 10, gg.light_gray)
g.ctx.draw_text(rect_x + csize / 2 - lsize / 3, rect_y + csize / 2 - lsize / 2,
g.cells[i].letter, color: gx.yellow, size: lsize)
g.cells[i].letter, color: gg.yellow, size: lsize)
} else {
g.ctx.draw_rect_filled(rect_x + 6, rect_y + 6, csize - 10, csize - 10, cover)
}
@ -57,7 +56,7 @@ fn on_frame(mut g Game) {
ws := gg.window_size()
g.ctx.begin()
message := '(r)estart (esc)ape | remaining: ${g.remaining:02} | time: ${f64(g.sw.elapsed().milliseconds()) / 1000.0:06.1f}s'
g.ctx.draw_text(ws.width / 2, 7, message, color: gx.light_gray, size: 22, align: .center)
g.ctx.draw_text(ws.width / 2, 7, message, color: gg.light_gray, size: 22, align: .center)
for i, cell in g.cells {
g.draw_cell(i, cell)
}
@ -123,7 +122,7 @@ mut g := &Game{
}
g.restart()
g.ctx = gg.new_context(
bg_color: gx.black
bg_color: gg.black
width: g.size * csize
height: header_size + g.size * csize
window_title: 'V Memory ${g.size} x ${g.size}'

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
import rand
import os.asset
@ -172,23 +171,23 @@ fn (mut g Game) draw_cell(y int, x int) {
rect_x, rect_y := x * g.csize, y * g.csize
if g.revealed[y][x] {
if g.grid[y][x] == .mine {
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gx.red)
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, '*', color: gx.black)
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gg.red)
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, '*', color: gg.black)
} else if int(g.grid[y][x]) > 0 {
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gx.light_gray)
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gg.light_gray)
n := int(g.grid[y][x]).str()
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, n, color: gx.black)
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, n, color: gg.black)
} else {
c := gx.rgb(240, 240, 240)
c := gg.rgb(240, 240, 240)
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, c)
}
} else if g.flags[y][x] {
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gx.gray)
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, 'F', color: gx.white)
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gg.gray)
g.ctx.draw_text(rect_x + 10, o + rect_y + 5, 'F', color: gg.white)
} else {
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gx.gray)
g.ctx.draw_rect_filled(rect_x, o + rect_y, g.csize, g.csize, gg.gray)
}
g.ctx.draw_rect_empty(rect_x, o + rect_y, g.csize, g.csize, gx.black)
g.ctx.draw_rect_empty(rect_x, o + rect_y, g.csize, g.csize, gg.black)
}
fn on_frame(mut g Game) {
@ -199,7 +198,7 @@ fn on_frame(mut g Game) {
}
}
message := 'Flagged: ${g.mines_flagged:02}/${g.mines:02} (r)estart (ESC)ape'
g.ctx.draw_text(5, 7, message, color: gx.green)
g.ctx.draw_text(5, 7, message, color: gg.green)
g.ctx.end()
}
@ -207,7 +206,7 @@ fn main() {
mut g := &Game{}
g.restart()
g.ctx = gg.new_context(
bg_color: gx.black
bg_color: gg.black
width: g.size * g.csize
height: header_size + g.size * g.csize
window_title: 'V Minesweeper'

View file

@ -1,7 +1,6 @@
module main
import gg // actual graphics lib
import gx // lib have some constants like colors
import math // for math related function
const window_width = 800
@ -48,7 +47,7 @@ mut:
col int
width int
pos Point
color gx.Color
color gg.Color
flag int // 0->empty, 1-> closed, 2-> open, 3-> barrier, 4-> start, 5-> end, 6-> path
neighbors []Point
}
@ -76,7 +75,7 @@ fn main() {
// setting values of app
app.gg = gg.new_context(
bg_color: gx.black // background color
bg_color: gg.black // background color
width: window_width // window width
height: window_height // window height
create_window: true // this will create a different window
@ -217,9 +216,9 @@ fn draw_gridlines(mut app App) {
dy := window_height / nrows
for i := 0; i < nrows; i++ {
// horizontal lines
app.gg.draw_line(0, i * dy, window_width, i * dy, gx.black)
app.gg.draw_line(0, i * dy, window_width, i * dy, gg.black)
// vertical lines
app.gg.draw_line(i * dx, 0, dx * i, window_height, gx.black)
app.gg.draw_line(i * dx, 0, dx * i, window_height, gg.black)
}
}
@ -251,7 +250,7 @@ fn initialise_grid() [][]Cell {
x: j * gap
y: i * gap
}
color: gx.white
color: gg.white
flag: 0
}
}
@ -378,31 +377,31 @@ fn astar_path_finding(mut app App, mut grid [][]Cell, start Point, end Point) {
fn set_cell_type(mut grid [][]Cell, row int, col int, typ string) {
match typ {
'reset' {
grid[row][col].color = gx.white
grid[row][col].color = gg.white
grid[row][col].flag = 0
}
'close' {
grid[row][col].color = gx.red
grid[row][col].color = gg.red
grid[row][col].flag = 1
}
'open' {
grid[row][col].color = gx.green
grid[row][col].color = gg.green
grid[row][col].flag = 2
}
'barrier' {
grid[row][col].color = gx.black
grid[row][col].color = gg.black
grid[row][col].flag = 3
}
'start' {
grid[row][col].color = gx.orange
grid[row][col].color = gg.orange
grid[row][col].flag = 4
}
'end' {
grid[row][col].color = gx.blue
grid[row][col].color = gg.blue
grid[row][col].flag = 5
}
'path' {
grid[row][col].color = gx.pink
grid[row][col].color = gg.pink
grid[row][col].flag = 6
}
else {}

View file

@ -1,11 +1,10 @@
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Polygons'
@ -17,8 +16,8 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0, 300.0],
gx.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gx.red)
gg.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gg.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gg.red)
ctx.end()
}

View file

@ -1,13 +1,12 @@
module main
import gg
import gx
import os.asset
import math
const win_width = 600
const win_height = 700
const bg_color = gx.white
const bg_color = gg.white
const text = '
Once upon a midnight dreary, while I pondered, weak and weary,
@ -84,7 +83,7 @@ fn frame(mut app App) {
if scale_factor <= 0 {
scale_factor = 1
}
text_cfg := gx.TextCfg{
text_cfg := gg.TextCfg{
size: 16 * int(scale_factor)
}
mut y := 10

View file

@ -12,7 +12,6 @@
// learn more on how this code works. There are some silly
// digressons in the video but the tech content is spot on.
import gg
import gx
import math
const player_size = 8
@ -59,7 +58,7 @@ fn main() {
window_title: 'Raycaster Demo'
width: 1024
height: 512
bg_color: gx.gray
bg_color: gg.gray
frame_fn: draw
event_fn: handle_events
)
@ -79,7 +78,7 @@ fn draw(mut app App) {
fn draw_map_2d(app App) {
for y := 0; y < map_y_size; y++ {
for x := 0; x < map_x_size; x++ {
color := if app.map[y * map_x_size + x] == 1 { gx.white } else { gx.black }
color := if app.map[y * map_x_size + x] == 1 { gg.white } else { gg.black }
app.ctx.draw_rect_filled(x * map_square, y * map_square, map_square - 1, map_square - 1,
color)
}
@ -87,10 +86,10 @@ fn draw_map_2d(app App) {
}
fn draw_player(app App) {
app.ctx.draw_rect_filled(app.player_x, app.player_y, player_size, player_size, gx.yellow)
app.ctx.draw_rect_filled(app.player_x, app.player_y, player_size, player_size, gg.yellow)
cx := app.player_x + player_size / 2
cy := app.player_y + player_size / 2
app.ctx.draw_line(cx, cy, cx + app.player_dx * 5, cy + app.player_dy * 5, gx.yellow)
app.ctx.draw_line(cx, cy, cx + app.player_dx * 5, cy + app.player_dy * 5, gg.yellow)
}
fn draw_rays_and_walls(app App) {
@ -109,7 +108,7 @@ fn draw_rays_and_walls(app App) {
mut map_x := 0
mut map_y := 0
mut map_pos := 0
mut color := gx.red
mut color := gg.red
mut ray_angle := clamp_ray_angle(app.player_angle - degree_radian * field_of_view / 2)
// each step = 1/2 degree
@ -196,17 +195,17 @@ fn draw_rays_and_walls(app App) {
ray_x = vx
ray_y = vy
distance = vd
color = gx.rgb(0, 100, 0)
color = gg.rgb(0, 100, 0)
} else if hd < vd {
ray_x = hx
ray_y = hy
distance = hd
color = gx.rgb(0, 120, 0)
color = gg.rgb(0, 120, 0)
}
// draw ray
cx := app.player_x + player_size / 2
cy := app.player_y + player_size / 2
app.ctx.draw_line(cx, cy, ray_x, ray_y, gx.green)
app.ctx.draw_line(cx, cy, ray_x, ray_y, gg.green)
// draw wall section
mut ca := clamp_ray_angle(app.player_angle - ray_angle)
distance *= math.cosf(ca) // remove fish eye

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
import os.asset
const win_width = 600
@ -16,7 +15,7 @@ mut:
fn main() {
mut app := &App{}
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
width: win_width
height: win_height
create_window: true
@ -38,7 +37,7 @@ fn frame(app &App) {
fn (app &App) draw() {
// app.gg.draw_text_def(200,20, 'hello world!')
// app.gg.draw_text_def(300,300, 'привет')
app.gg.draw_rect_filled(10, 10, 100, 30, gx.blue)
app.gg.draw_rect_empty(110, 150, 80, 40, gx.black)
app.gg.draw_rect_filled(10, 10, 100, 30, gg.blue)
app.gg.draw_rect_empty(110, 150, 80, 40, gg.black)
app.gg.draw_image_by_id(230, 30, 200, 200, app.image)
}

View file

@ -1,5 +1,4 @@
import gg
import gx
import os.asset
import sokol.sgl
@ -45,7 +44,7 @@ fn main() {
mut window := &Window{}
window.ctx = gg.new_context(
window_title: 'Rotating V logo'
bg_color: gx.light_green
bg_color: gg.light_green
width: 500
height: 500
user_data: window

View file

@ -1,24 +1,23 @@
module main
import gg
import gx
import os
fn main() {
scount := os.args[1] or { '2' }.int()
println('> sample count: ${scount}')
mut ctx := gg.new_context(
bg_color: gx.white
bg_color: gg.white
window_title: 'sample_count: ${scount}'
width: 320
height: 240
sample_count: scount
frame_fn: fn (mut ctx gg.Context) {
ctx.begin()
ctx.draw_rounded_rect_empty(110, 70, 100, 100, 10, gx.blue)
ctx.draw_circle_empty(160, 120, 100, gx.red)
ctx.draw_triangle_empty(160, 93, 186, 138, 132, 138, gx.green)
ctx.draw_rect_filled(159, 119, 2, 2, gx.black)
ctx.draw_rounded_rect_empty(110, 70, 100, 100, 10, gg.blue)
ctx.draw_circle_empty(160, 120, 100, gg.red)
ctx.draw_triangle_empty(160, 93, 186, 138, 132, 138, gg.green)
ctx.draw_rect_filled(159, 119, 2, 2, gg.black)
ctx.end()
}
)

View file

@ -2,7 +2,6 @@ module main
import os.asset
import gg
import gx
import rand
import sokol.sgl
@ -47,7 +46,7 @@ fn main() {
v_letters: []VLetter{len: max_v_letters}
}
app.gg = gg.new_context(
bg_color: gx.black
bg_color: gg.black
width: win_width
height: win_height
create_window: true

View file

@ -5,14 +5,13 @@ module main
// Example of how to send a value through a channel from a worker thread to the main/rendering thread.
// This can be useful to do long running computations while keeping your framerate high (60 fps in this example).
import gg
import gx
import math
import time
const win_width = 600
const win_height = 700
const bg_color = gx.white
const count_color = gx.black
const bg_color = gg.white
const count_color = gg.black
struct App {
mut:
@ -62,7 +61,7 @@ fn frame(mut app App) {
if scale_factor <= 0 {
scale_factor = 1
}
text_cfg := gx.TextCfg{
text_cfg := gg.TextCfg{
size: 64 * int(scale_factor)
}

View file

@ -2,7 +2,6 @@
// v -live bounce.v
module main
import gx
import gg
import time
@ -38,7 +37,7 @@ fn main() {
window_title: 'Hot code reloading demo'
create_window: true
frame_fn: frame
bg_color: gx.white
bg_color: gg.white
)
// window.onkeydown(key_down)
println('Starting the game loop...')
@ -52,10 +51,10 @@ fn main() {
fn frame(mut game Game) {
game.gg.begin()
game.gg.draw_text_def(10, 5, 'Modify examples/hot_reload/bounce.v to get instant updates')
game.gg.draw_rect_filled(game.x, game.y, width, width, gx.blue)
game.gg.draw_rect_filled(game.x, game.y, width, width, gg.blue)
game.gg.draw_rect_filled(window_width - width - game.x + 10, 200 - game.y + width,
width, width, gx.rgb(228, 10, 55))
game.gg.draw_rect_filled(game.x - 25, 250 - game.y, width, width, gx.rgb(28, 240,
width, width, gg.rgb(228, 10, 55))
game.gg.draw_rect_filled(game.x - 25, 250 - game.y, width, width, gg.rgb(28, 240,
55))
game.gg.end()
}

View file

@ -1,6 +1,5 @@
module main
import gx
import gg
import time
import math
@ -24,7 +23,7 @@ fn main() {
create_window: true
frame_fn: frame
resizable: true
bg_color: gx.white
bg_color: gg.white
)
context.gg.run()
}
@ -44,17 +43,17 @@ fn (ctx &Context) draw() {
w /= 2
h /= 2
}
ctx.gg.draw_line(0, h / 2, w, h / 2, gx.gray) // x axis
ctx.gg.draw_line(w / 2, 0, w / 2, h, gx.gray) // y axis
ctx.gg.draw_line(0, h / 2, w, h / 2, gg.gray) // x axis
ctx.gg.draw_line(w / 2, 0, w / 2, h, gg.gray) // y axis
atime := f64(time.ticks() / 10)
stime := math.sin(2.0 * math.pi * f64(time.ticks() % 6000) / 6000)
mut y := 0.0
blue := gx.Color{
blue := gg.Color{
r: 100
g: 100
b: 200
}
red := gx.Color{
red := gg.Color{
r: 200
g: 100
b: 100

View file

@ -1,16 +1,15 @@
module anim
import gg
import gx
import sim
import sim.args as simargs
const bg_color = gx.white
const bg_color = gg.white
struct Pixel {
x f32
y f32
color gx.Color
color gg.Color
}
pub struct App {

View file

@ -1,6 +1,6 @@
module img
import gx
import gg
import os
import sim
@ -53,7 +53,7 @@ pub fn (mut writer PPMWriter) start_for_file(fname string, settings ImageSetting
writer.file.writeln('P6 ${settings.width} ${settings.height} 255')!
}
pub fn (mut writer PPMWriter) handle_pixel(p gx.Color) ! {
pub fn (mut writer PPMWriter) handle_pixel(p gg.Color) ! {
if writer.cache.len >= writer.cache_size {
writer.write()!
writer.flush()!

View file

@ -1,10 +1,10 @@
module img
import gx
import gg
import sim
pub struct ValidColor {
gx.Color
gg.Color
pub mut:
valid bool
}
@ -52,17 +52,17 @@ pub fn (mut iw ImageWriter) handle(result sim.SimResult) !int {
return iw.current_index
}
pub fn compute_pixel(result sim.SimResult) gx.Color {
pub fn compute_pixel(result sim.SimResult) gg.Color {
closest_to_m1 := result.magnet1_distance < result.magnet2_distance
&& result.magnet1_distance < result.magnet3_distance
closest_to_m2 := result.magnet2_distance < result.magnet1_distance
&& result.magnet2_distance < result.magnet3_distance
if closest_to_m1 {
return gx.red
return gg.red
} else if closest_to_m2 {
return gx.green
return gg.green
} else {
return gx.blue
return gg.blue
}
}

View file

@ -2,7 +2,6 @@ module main
import datatypes
import gg
import gx
import time
import math
import rand
@ -11,12 +10,12 @@ const win_width = 1340
const win_height = 640
const timer_period = 40 * time.millisecond // defaulted at 25 fps
const font_small = gx.TextCfg{
color: gx.black
const font_small = gg.TextCfg{
color: gg.black
size: 20
}
const font_large = gx.TextCfg{
color: gx.black
const font_large = gg.TextCfg{
color: gg.black
size: 40
}
@ -114,7 +113,7 @@ fn main() {
gg: unsafe { nil }
}
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
width: win_width
height: win_height
create_window: true
@ -159,19 +158,19 @@ fn frame(app &App) {
fn (app &App) display() {
for player in app.players {
app.gg.draw_rect_filled(f32(player.x), f32(player.y), f32(player.width), f32(player.height),
gx.black)
gg.black)
}
for particle in app.particles {
app.gg.draw_rect_empty(f32(particle.pmt.x), f32(particle.pmt.y), f32(particle.pmt.width),
f32(particle.pmt.height), gx.blue)
f32(particle.pmt.height), gg.blue)
}
for node in app.nodes {
app.gg.draw_rect_empty(f32(node.perimeter.x), f32(node.perimeter.y), f32(node.perimeter.width),
f32(node.perimeter.height), gx.red)
f32(node.perimeter.height), gg.red)
}
for retrieved in app.retrieveds {
app.gg.draw_rect_filled(f32(retrieved.x + 1), f32(retrieved.y + 1), f32(retrieved.width - 2),
f32(retrieved.height - 2), gx.green)
f32(retrieved.height - 2), gg.green)
}
app.gg.draw_text(1200, 25, 'Nodes: ${app.nodes.len}', font_small)
app.gg.draw_text(1200, 50, 'Particles: ${app.particles.len}', font_small)

View file

@ -1,5 +1,4 @@
import gg
import gx
// import sokol.sapp
import time
import rand
@ -142,17 +141,17 @@ fn on_frame(mut app App) {
// drawing snake
for pos in app.snake {
app.gg.draw_rect(tile_size * pos.x, tile_size * pos.y + top_height, tile_size,
tile_size, gx.blue)
tile_size, gg.blue)
}
// drawing food
app.gg.draw_rect(tile_size * app.food.x, tile_size * app.food.y + top_height, tile_size,
tile_size, gx.red)
tile_size, gg.red)
// drawing top
app.gg.draw_rect(0, 0, canvas_size, top_height, gx.black)
app.gg.draw_text(350, top_height / 2, 'Score: ${app.score}', gx.TextCfg{
color: gx.white
app.gg.draw_rect(0, 0, canvas_size, top_height, gg.black)
app.gg.draw_text(350, top_height / 2, 'Score: ${app.score}', gg.TextCfg{
color: gg.white
align: .center
vertical_align: .middle
size: 80
@ -179,7 +178,7 @@ fn main() {
app.reset_game()
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
frame_fn: on_frame
keydown_fn: on_keydown
user_data: &app

View file

@ -1,5 +1,4 @@
import gg
import gx
import os
import rand
import time
@ -77,35 +76,35 @@ fn on_frame(mut app App) {
app.gg.begin()
// draw food
app.gg.draw_rect_filled(tile_size * app.food.x, tile_size * app.food.y + top_height,
tile_size, tile_size, gx.red)
tile_size, tile_size, gg.red)
// draw snake
for pos in app.snake[..app.snake.len - 1] {
app.gg.draw_rect_filled(tile_size * pos.x, tile_size * pos.y + top_height, tile_size,
tile_size, gx.blue)
tile_size, gg.blue)
}
// draw partial head
head := app.snake[0]
app.gg.draw_rect_filled(tile_size * (head.x + app.dir.x * progress), tile_size * (head.y +
app.dir.y * progress) + top_height, tile_size, tile_size, gx.blue)
app.dir.y * progress) + top_height, tile_size, tile_size, gg.blue)
// draw partial tail
tail := app.snake.last()
tail_dir := app.snake[app.snake.len - 2] - tail
app.gg.draw_rect_filled(tile_size * (tail.x + tail_dir.x * progress), tile_size * (tail.y +
tail_dir.y * progress) + top_height, tile_size, tile_size, gx.blue)
tail_dir.y * progress) + top_height, tile_size, tile_size, gg.blue)
// draw score bar
app.gg.draw_rect_filled(0, 0, canvas_size, top_height, gx.black)
app.gg.draw_text(150, top_height / 2, 'Score: ${app.score}', gx.TextCfg{
color: gx.white
app.gg.draw_rect_filled(0, 0, canvas_size, top_height, gg.black)
app.gg.draw_text(150, top_height / 2, 'Score: ${app.score}', gg.TextCfg{
color: gg.white
align: .center
vertical_align: .middle
size: 65
})
app.gg.draw_text(canvas_size - 150, top_height / 2, 'Best: ${app.best}', gx.TextCfg{
color: gx.white
app.gg.draw_text(canvas_size - 150, top_height / 2, 'Best: ${app.best}', gg.TextCfg{
color: gg.white
align: .center
vertical_align: .middle
size: 65
@ -170,7 +169,7 @@ app.best.load()
mut font_copy := font
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
frame_fn: on_frame
keydown_fn: on_keydown
user_data: &app

View file

@ -1,7 +1,6 @@
import os
import os.asset
import gg
import gx
const csize = 32
@ -204,7 +203,7 @@ fn (mut g Game) key_down(key gg.KeyCode, _ gg.Modifier, _ voidptr) {
g.win = g.boxes.all(g.warehouse[it.y][it.x] == `@`)
}
fn (g &Game) ctext(ws gg.Size, oy int, message string, size int, color gx.Color) {
fn (g &Game) ctext(ws gg.Size, oy int, message string, size int, color gg.Color) {
g.ctx.draw_text(ws.width / 2, ws.height + oy, message,
color: color
size: size
@ -229,20 +228,20 @@ fn (g &Game) draw_frame(_ voidptr) {
g.ctx.draw_image_by_id(ox + x * csize, oy + y * csize, 32, 32, iid)
}
}
g.ctx.draw_rect_filled(0, ws.height - 70, ws.width, 70, gx.black)
g.ctx.draw_rect_filled(0, ws.height - 70, ws.width, 70, gg.black)
if g.win {
g.ctext(ws, -50, 'You win!!!', 60, gx.yellow)
g.ctext(ws, -15, 'Press `space` to continue.', 20, gx.gray)
g.ctext(ws, -50, 'You win!!!', 60, gg.yellow)
g.ctext(ws, -15, 'Press `space` to continue.', 20, gg.gray)
} else {
for idx, title in g.titles {
g.ctext(ws, -65 + (idx * 20), title, 22, gx.white)
g.ctext(ws, -65 + (idx * 20), title, 22, gg.white)
}
g.ctext(ws, -65 + (g.titles.len * 20), 'Boxes: ${g.boxes.len:04}', 16, gx.gray)
g.ctext(ws, -65 + (g.titles.len * 20), 'Boxes: ${g.boxes.len:04}', 16, gg.gray)
}
g.ctx.draw_rect_filled(0, 0, ws.width, 40, gx.black)
g.ctx.draw_text(30, 0, 'Level: ${g.level + 1:02}', color: gx.green, size: 40)
g.ctx.draw_text(ws.width - 225, 0, 'Moves: ${g.moves:04}', color: gx.green, size: 40)
g.ctx.draw_text(ws.width / 2 - 110, 0, 'Pushes: ${g.pushes:04}', color: gx.green, size: 40)
g.ctx.draw_rect_filled(0, 0, ws.width, 40, gg.black)
g.ctx.draw_text(30, 0, 'Level: ${g.level + 1:02}', color: gg.green, size: 40)
g.ctx.draw_text(ws.width - 225, 0, 'Moves: ${g.moves:04}', color: gg.green, size: 40)
g.ctx.draw_text(ws.width / 2 - 110, 0, 'Pushes: ${g.pushes:04}', color: gg.green, size: 40)
g.ctx.end()
}

View file

@ -8,7 +8,6 @@
* - add an example with shaders
**********************************************************************/
import gg
import gx
import math
import sokol.sapp
import sokol.gfx
@ -16,7 +15,7 @@ import sokol.sgl
const win_width = 800
const win_height = 800
const bg_color = gx.white
const bg_color = gg.white
struct App {
mut:

View file

@ -15,7 +15,6 @@
* - add instancing
**********************************************************************/
import gg
import gx
// import math
import sokol.sapp
import sokol.gfx
@ -30,7 +29,7 @@ fn C.cube_shader_desc(gfx.Backend) &gfx.ShaderDesc
const win_width = 800
const win_height = 800
const bg_color = gx.white
const bg_color = gg.white
struct App {
mut:

View file

@ -16,7 +16,6 @@
**********************************************************************/
import gg
import gg.m4
import gx
// import math
import sokol.sapp
import sokol.gfx
@ -31,7 +30,7 @@ fn C.rt_shader_desc(gfx.Backend) &gfx.ShaderDesc
const win_width = 800
const win_height = 800
const bg_color = gx.white
const bg_color = gg.white
struct App {
mut:

View file

@ -16,7 +16,6 @@
**********************************************************************/
import gg
import gg.m4
import gx
import math
import sokol.gfx
// import sokol.sgl
@ -24,7 +23,7 @@ import time
const win_width = 800
const win_height = 800
const bg_color = gx.white
const bg_color = gg.white
const num_inst = 16384
struct App {

View file

@ -22,7 +22,6 @@
**********************************************************************/
import gg
import gg.m4
import gx
import math
import sokol.sapp
import sokol.gfx
@ -39,7 +38,7 @@ fn C.gouraud_shader_desc(gfx.Backend) &gfx.ShaderDesc
const win_width = 600
const win_height = 600
const bg_color = gx.white
const bg_color = gg.white
struct App {
mut:

View file

@ -5,7 +5,6 @@ module main
import rand
import time
import gx
import gg
// import sokol.sapp
@ -22,15 +21,15 @@ const timer_period = 250 // ms
const text_size = 24
const limit_thickness = 3
const text_cfg = gx.TextCfg{
const text_cfg = gg.TextCfg{
align: .left
size: text_size
color: gx.rgb(0, 0, 0)
color: gg.rgb(0, 0, 0)
}
const over_cfg = gx.TextCfg{
const over_cfg = gg.TextCfg{
align: .left
size: text_size
color: gx.white
color: gg.white
}
// Tetros' 4 possible states are encoded in binaries
@ -50,18 +49,18 @@ const b_tetros = [
]
// Each tetro has its unique color
const colors = [
gx.rgb(0, 0, 0), // unused ?
gx.rgb(255, 242, 0), // yellow quad
gx.rgb(174, 0, 255), // purple triple
gx.rgb(60, 255, 0), // green short topright
gx.rgb(255, 0, 0), // red short topleft
gx.rgb(255, 180, 31), // orange long topleft
gx.rgb(33, 66, 255), // blue long topright
gx.rgb(74, 198, 255), // lightblue longest
gx.rgb(0, 170, 170),
gg.rgb(0, 0, 0), // unused ?
gg.rgb(255, 242, 0), // yellow quad
gg.rgb(174, 0, 255), // purple triple
gg.rgb(60, 255, 0), // green short topright
gg.rgb(255, 0, 0), // red short topleft
gg.rgb(255, 180, 31), // orange long topleft
gg.rgb(33, 66, 255), // blue long topright
gg.rgb(74, 198, 255), // lightblue longest
gg.rgb(0, 170, 170),
]
const background_color = gx.white
const ui_color = gx.rgba(255, 0, 0, 210)
const background_color = gg.white
const ui_color = gg.rgba(255, 0, 0, 210)
// TODO: type Tetro [tetro_size]struct{ x, y int }
struct Block {
@ -160,7 +159,7 @@ fn main() {
}
game.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
width: win_width
height: win_height
create_window: true
@ -217,7 +216,7 @@ fn (mut g Game) draw_ghost() {
pos_y := g.move_ghost()
for i in 0 .. tetro_size {
tetro := g.tetro[i]
g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gx.rgba(125, 125, 225,
g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225,
40))
}
}
@ -346,18 +345,18 @@ fn (mut g Game) draw_next_tetro() {
pos_x := field_width / 2 - tetro_size / 2
for i in 0 .. tetro_size {
block := next_tetro[i]
g.draw_block_color(pos_y + block.y, pos_x + block.x, gx.rgb(220, 220, 220))
g.draw_block_color(pos_y + block.y, pos_x + block.x, gg.rgb(220, 220, 220))
}
}
}
fn (mut g Game) draw_block_color(i int, j int, color gx.Color) {
fn (mut g Game) draw_block_color(i int, j int, color gg.Color) {
g.gg.draw_rect(f32((j - 1) * g.block_size) + g.margin, f32((i - 1) * g.block_size),
f32(g.block_size - 1), f32(g.block_size - 1), color)
}
fn (mut g Game) draw_block(i int, j int, color_idx int) {
color := if g.state == .gameover { gx.gray } else { colors[color_idx] }
color := if g.state == .gameover { gg.gray } else { colors[color_idx] }
g.draw_block_color(i, j, color)
}

View file

@ -6,7 +6,6 @@ module main
import os.asset
import rand
import time
import gx
import gg
// import sokol.sapp
@ -23,15 +22,15 @@ const timer_period = 250 // ms
const text_size = 24
const limit_thickness = 3
const text_cfg = gx.TextCfg{
const text_cfg = gg.TextCfg{
align: .left
size: text_size
color: gx.rgb(0, 0, 0)
color: gg.rgb(0, 0, 0)
}
const over_cfg = gx.TextCfg{
const over_cfg = gg.TextCfg{
align: .left
size: text_size
color: gx.white
color: gg.white
}
// Tetros' 4 possible states are encoded in binaries
@ -51,18 +50,18 @@ const b_tetros = [
]
// Each tetro has its unique color
const colors = [
gx.rgb(0, 0, 0), // unused ?
gx.rgb(255, 242, 0), // yellow quad
gx.rgb(174, 0, 255), // purple triple
gx.rgb(60, 255, 0), // green short topright
gx.rgb(255, 0, 0), // red short topleft
gx.rgb(255, 180, 31), // orange long topleft
gx.rgb(33, 66, 255), // blue long topright
gx.rgb(74, 198, 255), // lightblue longest
gx.rgb(0, 170, 170),
gg.rgb(0, 0, 0), // unused ?
gg.rgb(255, 242, 0), // yellow quad
gg.rgb(174, 0, 255), // purple triple
gg.rgb(60, 255, 0), // green short topright
gg.rgb(255, 0, 0), // red short topleft
gg.rgb(255, 180, 31), // orange long topleft
gg.rgb(33, 66, 255), // blue long topright
gg.rgb(74, 198, 255), // lightblue longest
gg.rgb(0, 170, 170),
]
const background_color = gx.white
const ui_color = gx.rgba(255, 0, 0, 210)
const background_color = gg.white
const ui_color = gg.rgba(255, 0, 0, 210)
// TODO: type Tetro [tetro_size]struct{ x, y int }
struct Block {
@ -159,7 +158,7 @@ fn frame(mut game Game) {
fn main() {
mut game := &Game{}
game.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
width: win_width
height: win_height
create_window: true
@ -217,7 +216,7 @@ fn (g &Game) draw_ghost() {
pos_y := g.move_ghost()
for i in 0 .. tetro_size {
tetro := g.tetro[i]
g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gx.rgba(125, 125, 225,
g.draw_block_color(pos_y + tetro.y, g.pos_x + tetro.x, gg.rgba(125, 125, 225,
40))
}
}
@ -340,18 +339,18 @@ fn (g &Game) draw_next_tetro() {
pos_x := field_width / 2 - tetro_size / 2
for i in 0 .. tetro_size {
block := next_tetro[i]
g.draw_block_color(pos_y + block.y, pos_x + block.x, gx.rgb(220, 220, 220))
g.draw_block_color(pos_y + block.y, pos_x + block.x, gg.rgb(220, 220, 220))
}
}
}
fn (g &Game) draw_block_color(i int, j int, color gx.Color) {
fn (g &Game) draw_block_color(i int, j int, color gg.Color) {
g.gg.draw_rect_filled(f32((j - 1) * g.block_size) + g.margin, f32((i - 1) * g.block_size),
f32(g.block_size - 1), f32(g.block_size - 1), color)
}
fn (g &Game) draw_block(i int, j int, color_idx int) {
color := if g.state == .gameover { gx.gray } else { colors[color_idx] }
color := if g.state == .gameover { gg.gray } else { colors[color_idx] }
g.draw_block_color(i, j, color)
}

View file

@ -1,5 +1,4 @@
import gg
import gx
import sokol.sapp
import sokol.sgl
import x.ttf
@ -14,7 +13,7 @@ const custom_text_start_y = 80
const win_width = 400
const win_height = 400
const bg_color = gx.Color{50, 255, 50, 255}
const bg_color = gg.Color{50, 255, 50, 255}
const block_txt = os.read_file(custom_txt_path) or { '' }
const font_paths = [

View file

@ -1,5 +1,4 @@
import gg
import gx
import sokol.sapp
import sokol.sgl
import sokol.gfx
@ -9,7 +8,7 @@ import os
// import math
const win_width = 600
const win_height = 700
const bg_color = gx.white
const bg_color = gg.white
const font_paths = [
os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'Imprima-Regular.ttf')),
os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'Graduate-Regular.ttf')),

View file

@ -11,7 +11,6 @@
**********************************************************************/
import os
import gg
import gx
import sokol.gfx
import sokol.sgl
import sokol.sapp
@ -39,7 +38,7 @@ const help_text_rows = [
const win_width = 800
const win_height = 800
const bg_color = gx.black
const bg_color = gg.black
const pi_2 = 3.14159265359 / 2.0
const uv = [f32(0), 0, 1, 0, 1, 1, 0, 1]! // used for zoom icon during rotations
@ -569,13 +568,13 @@ fn draw_text(mut app App, in_txt string, in_x int, in_y int, fnt_sz f32) {
scale := app.gg.scale
font_size := int(fnt_sz * scale)
mut txt_conf_c0 := gx.TextCfg{
color: gx.white // gx.rgb( (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
mut txt_conf_c0 := gg.TextCfg{
color: gg.white // gg.rgb( (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
align: .left
size: font_size
}
mut txt_conf_c1 := gx.TextCfg{
color: gx.black // gx.rgb( (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
mut txt_conf_c1 := gg.TextCfg{
color: gg.black // gg.rgb( (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
align: .left
size: font_size
}

View file

@ -11,11 +11,10 @@ user's keyboard/mouse input.
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Polygons'
@ -27,9 +26,9 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0, 300.0],
gx.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gx.red)
gg.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gg.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gg.red)
ctx.end()
}
```

310
vlib/gg/color.v Normal file
View file

@ -0,0 +1,310 @@
module gg
pub const black = Color{
r: 0
g: 0
b: 0
}
pub const gray = Color{
r: 128
g: 128
b: 128
}
pub const white = Color{
r: 255
g: 255
b: 255
}
pub const red = Color{
r: 255
g: 0
b: 0
}
pub const green = Color{
r: 0
g: 255
b: 0
}
pub const blue = Color{
r: 0
g: 0
b: 255
}
pub const yellow = Color{
r: 255
g: 255
b: 0
}
pub const magenta = Color{
r: 255
g: 0
b: 255
}
pub const cyan = Color{
r: 0
g: 255
b: 255
}
pub const orange = Color{
r: 255
g: 165
b: 0
}
pub const purple = Color{
r: 128
g: 0
b: 128
}
pub const indigo = Color{
r: 75
g: 0
b: 130
}
pub const pink = Color{
r: 255
g: 192
b: 203
}
pub const violet = Color{
r: 238
g: 130
b: 238
}
pub const dark_blue = Color{
r: 0
g: 0
b: 139
}
pub const dark_gray = Color{
r: 169
g: 169
b: 169
}
pub const dark_green = Color{
r: 0
g: 100
b: 0
}
pub const dark_red = Color{
r: 139
g: 0
b: 0
}
pub const light_blue = Color{
r: 173
g: 216
b: 230
}
pub const light_gray = Color{
r: 211
g: 211
b: 211
}
pub const light_green = Color{
r: 144
g: 238
b: 144
}
pub const light_red = Color{
r: 255
g: 204
b: 203
}
// Color represents a 32 bit color value in sRGB format
@[markused]
pub struct Color {
pub mut:
r u8
g u8
b u8
a u8 = 255
}
// hex takes in a 32 bit integer and splits it into 4 byte values
pub fn hex(color int) Color {
return Color{
r: u8((color >> 16) & 0xFF)
g: u8((color >> 8) & 0xFF)
b: u8((color >> 0) & 0xFF)
}
}
// rgb builds a Color instance from given r, g, b values
pub fn rgb(r u8, g u8, b u8) Color {
return Color{
r: r
g: g
b: b
}
}
// rgba builds a Color instance from given r, g, b, a values
pub fn rgba(r u8, g u8, b u8, a u8) Color {
return Color{
r: r
g: g
b: b
a: a
}
}
// + adds `b` to `a`, with a maximum value of 255 for each channel
pub fn (a Color) + (b Color) Color {
mut na := int(a.a) + b.a
mut nr := int(a.r) + b.r
mut ng := int(a.g) + b.g
mut nb := int(a.b) + b.b
if na > 255 {
na = 255
}
if nr > 255 {
nr = 255
}
if ng > 255 {
ng = 255
}
if nb > 255 {
nb = 255
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// - subtracts `b` from `a`, with a minimum value of 0 for each channel
pub fn (a Color) - (b Color) Color {
mut na := if a.a > b.a { a.a } else { b.a }
mut nr := int(a.r) - b.r
mut ng := int(a.g) - b.g
mut nb := int(a.b) - b.b
if na < 0 {
na = 0
}
if nr < 0 {
nr = 0
}
if ng < 0 {
ng = 0
}
if nb < 0 {
nb = 0
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// * multiplies Color `c` and `c2` keeping channel values in [0, 255] range
pub fn (c Color) * (c2 Color) Color {
return Color{
r: c.r * c2.r
g: c.g * c2.g
b: c.b * c2.b
a: c.a * c2.a
}
}
// / divides `c` by `c2` and converts each channel's value to u8(int)
pub fn (c Color) / (c2 Color) Color {
return Color{
r: c.r / c2.r
g: c.g / c2.g
b: c.b / c2.b
a: c.a / c2.a
}
}
// over implements an `a` over `b` operation.
// see https://keithp.com/~keithp/porterduff/p253-porter.pdf
pub fn (a Color) over(b Color) Color {
aa := f32(a.a) / 255
ab := f32(b.a) / 255
ar := aa + ab * (1 - aa)
rr := (f32(a.r) * aa + f32(b.r) * ab * (1 - aa)) / ar
gr := (f32(a.g) * aa + f32(b.g) * ab * (1 - aa)) / ar
br := (f32(a.b) * aa + f32(b.b) * ab * (1 - aa)) / ar
return Color{
r: u8(rr)
g: u8(gr)
b: u8(br)
a: u8(ar * 255)
}
}
// eq checks if color `c` and `c2` are equal in every channel
pub fn (c Color) eq(c2 Color) bool {
return c.r == c2.r && c.g == c2.g && c.b == c2.b && c.a == c2.a
}
// str returns a string representation of the Color `c`
pub fn (c Color) str() string {
return 'Color{${c.r}, ${c.g}, ${c.b}, ${c.a}}'
}
// rgba8 converts a color value to an int in the RGBA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) rgba8() int {
return int(u32(c.r) << 24 | u32(c.g) << 16 | u32(c.b) << 8 | u32(c.a))
}
// bgra8 converts a color value to an int in the BGRA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) bgra8() int {
return int(u32(c.b) << 24 | u32(c.g) << 16 | u32(c.r) << 8 | u32(c.a))
}
// abgr8 converts a color value to an int in the ABGR8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) abgr8() int {
return int(u32(c.a) << 24 | u32(c.b) << 16 | u32(c.g) << 8 | u32(c.r))
}
const string_colors = {
'blue': blue
'red': red
'green': green
'yellow': yellow
'orange': orange
'purple': purple
'black': black
'gray': gray
'indigo': indigo
'pink': pink
'violet': violet
'white': white
'dark_blue': dark_blue
'dark_gray': dark_gray
'dark_green': dark_green
'dark_red': dark_red
'light_blue': light_blue
'light_gray': light_gray
'light_green': light_green
'light_red': light_red
}
// color_from_string returns a Color, corresponding to the given string
// or black Color if string is not found in lookup table, or a hex color if starting with #
pub fn color_from_string(s string) Color {
if s.starts_with('#') {
mut hex_str := '0x' + s[1..]
return hex(hex_str.int())
} else {
return string_colors[s]
}
}
// to_css_string returns a CSS compatible string e.g. `rgba(10,11,12,13)` of the color `c`.
pub fn (c Color) to_css_string() string {
return 'rgba(${c.r},${c.g},${c.b},${c.a})'
}

102
vlib/gg/color_test.v Normal file
View file

@ -0,0 +1,102 @@
// vtest build: !musl? // gx now transitively imports sokol, and that needs GL/gl.h, which is not installed on the musl CIs
import gg
fn test_hex() {
// valid colors
// a := gg.hex(0x6c5ce7ff)
// b := gg.rgba(108, 92, 231, 255)
assert gg.hex(0xff6600) == gg.rgb(255, 102, 0) // orange
// doesn't give right value with short hex value
short := gg.hex(0xfff)
assert short != gg.white
// assert short == gg.Color{0, 0, 15, 255}
}
fn test_add() {
a := gg.rgba(100, 100, 100, 100)
b := gg.rgba(100, 100, 100, 100)
r := gg.rgba(200, 200, 200, 200)
assert (a + b) == r
assert gg.red + gg.green == gg.yellow
assert gg.red + gg.blue == gg.magenta
assert gg.green + gg.blue == gg.cyan
}
fn test_sub() {
a := gg.rgba(100, 100, 100, 50)
b := gg.rgba(100, 100, 100, 100)
r := gg.rgba(0, 0, 0, 100)
assert (a - b) == r
assert gg.white - gg.green == gg.magenta
assert gg.white - gg.blue == gg.yellow
assert gg.white - gg.red == gg.cyan
}
fn test_mult() {
a := gg.rgba(10, 10, 10, 10)
b := gg.rgba(10, 10, 10, 10)
r := gg.rgba(100, 100, 100, 100)
assert (a * b) == r
}
fn test_div() {
a := gg.rgba(100, 100, 100, 100)
b := gg.rgba(10, 10, 10, 10)
r := gg.rgba(10, 10, 10, 10)
assert (a / b) == r
}
fn test_rgba8() {
assert gg.white.rgba8() == -1
assert gg.black.rgba8() == 255
assert gg.red.rgba8() == -16776961
assert gg.green.rgba8() == 16711935
assert gg.blue.rgba8() == 65535
}
fn test_bgra8() {
assert gg.white.bgra8() == -1
assert gg.black.bgra8() == 255
assert gg.red.bgra8() == 65535
assert gg.green.bgra8() == 16711935
assert gg.blue.bgra8() == -16776961
}
fn test_abgr8() {
assert gg.white.abgr8() == -1
assert gg.black.abgr8() == -16777216
assert gg.red.abgr8() == -16776961
assert gg.green.abgr8() == -16711936
assert gg.blue.abgr8() == -65536
}
fn test_over() {
// shorten names:
r := gg.red
g := gg.green
b := gg.blue
y := gg.yellow
semi_r := gg.Color{255, 0, 0, 128}
semi_g := gg.Color{0, 255, 0, 128}
semi_b := gg.Color{0, 0, 255, 128}
// fully opaque colors, should be preserved when laid *over* any others:
assert b.over(g) == b
assert r.over(g) == r
assert y.over(r) == y
assert g.over(r) == g
// half transparent pure colors, *over* pure colors, should preserve them correspondingly:
assert semi_r.over(r) == gg.Color{255, 0, 0, 255} // preserve pure red
assert semi_r.over(g) == gg.Color{128, 126, 0, 255}
assert semi_r.over(b) == gg.Color{128, 0, 126, 255}
assert semi_g.over(r) == gg.Color{126, 128, 0, 255}
assert semi_g.over(g) == gg.Color{0, 255, 0, 255} // preserve pure green
assert semi_g.over(b) == gg.Color{0, 128, 126, 255}
assert semi_b.over(r) == gg.Color{126, 0, 128, 255}
assert semi_b.over(g) == gg.Color{0, 126, 128, 255}
assert semi_b.over(b) == gg.Color{0, 0, 255, 255} // preserve pure blue
}

View file

@ -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 gx
import math
import sokol.sgl
@ -17,7 +16,7 @@ pub mut:
// NOTE calling this function frequently is very *inefficient*,
// for drawing shapes it's recommended to draw whole primitives with
// functions like `draw_rect_empty` or `draw_triangle_empty` etc.
pub fn (ctx &Context) draw_pixel(x f32, y f32, c gx.Color, params DrawPixelConfig) {
pub fn (ctx &Context) draw_pixel(x f32, y f32, c Color, params DrawPixelConfig) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -34,7 +33,7 @@ pub fn (ctx &Context) draw_pixel(x f32, y f32, c gx.Color, params DrawPixelConfi
// for drawing shapes it's recommended to draw whole primitives with
// functions like `draw_rect_empty` or `draw_triangle_empty` etc.
@[direct_array_access]
pub fn (ctx &Context) draw_pixels(points []f32, c gx.Color, params DrawPixelConfig) {
pub fn (ctx &Context) draw_pixels(points []f32, c Color, params DrawPixelConfig) {
if points.len % 2 != 0 {
return
}
@ -54,7 +53,7 @@ pub fn (ctx &Context) draw_pixels(points []f32, c gx.Color, params DrawPixelConf
}
// draw_line draws a line between the points `x,y` and `x2,y2` in color `c`.
pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c gx.Color) {
pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c Color) {
$if macos {
if ctx.native_rendering {
// Make the line more clear on hi dpi screens: draw a rectangle
@ -135,7 +134,7 @@ pub fn (ctx &Context) draw_line_with_config(x f32, y f32, x2 f32, y2 f32, config
// draw_poly_empty draws the outline of a polygon, given an array of points, and a color.
// NOTE that the points must be given in clockwise winding order.
pub fn (ctx &Context) draw_poly_empty(points []f32, c gx.Color) {
pub fn (ctx &Context) draw_poly_empty(points []f32, c Color) {
len := points.len / 2
if points.len % 2 != 0 || len < 3 {
return
@ -157,7 +156,7 @@ pub fn (ctx &Context) draw_poly_empty(points []f32, c gx.Color) {
// draw_convex_poly draws a convex polygon, given an array of points, and a color.
// NOTE that the points must be given in clockwise winding order.
// The contents of the `points` array should be `x` and `y` coordinate pairs.
pub fn (ctx &Context) draw_convex_poly(points []f32, c gx.Color) {
pub fn (ctx &Context) draw_convex_poly(points []f32, c Color) {
len := points.len / 2
if points.len % 2 != 0 || len < 3 {
return
@ -185,7 +184,7 @@ pub fn (ctx &Context) draw_convex_poly(points []f32, c gx.Color) {
// draw_rect_empty draws the outline of a rectangle.
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height and `c` is the color of the outline.
pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c gx.Color) {
pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c Color) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -219,7 +218,7 @@ pub fn (ctx &Context) draw_rect_empty(x f32, y f32, w f32, h f32, c gx.Color) {
// draw_rect_filled draws a filled rectangle.
// `x`,`y` is the top-left corner of the rectangle.
// `w` is the width, `h` is the height and `c` is the color of the fill.
pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c gx.Color) {
pub fn (ctx &Context) draw_rect_filled(x f32, y f32, w f32, h f32, c Color) {
$if macos {
if ctx.native_rendering {
C.darwin_draw_rect(x, ctx.height - (y + h), w, h, c)
@ -252,7 +251,7 @@ pub:
y f32
w f32
h f32
color gx.Color = gx.black
color Color = black
style PaintStyle = .fill
is_rounded bool
radius f32
@ -279,7 +278,7 @@ pub fn (ctx &Context) draw_rect(p DrawRectParams) {
// `w` is the width, `h` is the height.
// `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c Color) {
if w <= 0 || h <= 0 || radius < 0 {
return
}
@ -376,7 +375,7 @@ pub fn (ctx &Context) draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius
// `w` is the width, `h` is the height .
// `radius` is the radius of the corner-rounding in pixels.
// `c` is the color of the filled.
pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gx.Color) {
pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c Color) {
if w <= 0 || h <= 0 || radius < 0 {
return
}
@ -486,7 +485,7 @@ pub fn (ctx &Context) draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radiu
// `x2`,`y2` defines the second point
// `x3`,`y3` defines the third point
// `c` is the color of the outline.
pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) {
pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c Color) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -505,7 +504,7 @@ pub fn (ctx &Context) draw_triangle_empty(x f32, y f32, x2 f32, y2 f32, x3 f32,
// `x2`,`y2` defines the second point
// `x3`,`y3` defines the third point
// `c` is the color of the outline.
pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c gx.Color) {
pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32, y3 f32, c Color) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -523,7 +522,7 @@ pub fn (ctx &Context) draw_triangle_filled(x f32, y f32, x2 f32, y2 f32, x3 f32,
// `s` is the length of each side of the square.
// `c` is the color of the outline.
@[inline]
pub fn (ctx &Context) draw_square_empty(x f32, y f32, s f32, c gx.Color) {
pub fn (ctx &Context) draw_square_empty(x f32, y f32, s f32, c Color) {
ctx.draw_rect_empty(x, y, s, s, c)
}
@ -532,7 +531,7 @@ pub fn (ctx &Context) draw_square_empty(x f32, y f32, s f32, c gx.Color) {
// `s` is the length of each side of the square.
// `c` is the fill color.
@[inline]
pub fn (ctx &Context) draw_square_filled(x f32, y f32, s f32, c gx.Color) {
pub fn (ctx &Context) draw_square_filled(x f32, y f32, s f32, c Color) {
ctx.draw_rect_filled(x, y, s, s, c)
}
@ -556,7 +555,7 @@ fn radius_to_segments(r f32) int {
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c gx.Color) {
pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c Color) {
$if macos {
if ctx.native_rendering {
C.darwin_draw_circle_empty(x - radius + 1, ctx.height - (y + radius + 3),
@ -591,7 +590,7 @@ pub fn (ctx &Context) draw_circle_empty(x f32, y f32, radius f32, c gx.Color) {
// `x`,`y` defines the center of the circle.
// `radius` defines the radius of the circle.
// `c` is the fill color.
pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c gx.Color) {
pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c Color) {
$if macos {
if ctx.native_rendering {
C.darwin_draw_circle(x - radius + 1, ctx.height - (y + radius + 3), radius,
@ -608,7 +607,7 @@ pub fn (ctx &Context) draw_circle_filled(x f32, y f32, radius f32, c gx.Color) {
// `edges` defines number of edges in the polygon.
// `rotation` defines rotation of the polygon.
// `c` is the fill color.
pub fn (ctx &Context) draw_polygon_filled(x f32, y f32, size f32, edges int, rotation f32, c gx.Color) {
pub fn (ctx &Context) draw_polygon_filled(x f32, y f32, size f32, edges int, rotation f32, c Color) {
if edges <= 0 {
return
}
@ -641,7 +640,7 @@ pub fn (ctx &Context) draw_polygon_filled(x f32, y f32, size f32, edges int, rot
// `radius` defines the radius of the circle.
// `segments` affects how smooth/round the circle is.
// `c` is the fill color.
pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segments int, c gx.Color) {
pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segments int, c Color) {
ctx.draw_polygon_filled(x, y, radius, segments, 0, c)
}
@ -650,7 +649,7 @@ pub fn (ctx &Context) draw_circle_with_segments(x f32, y f32, radius f32, segmen
// `radius` defines the radius of the circle.
// `segments` affects how smooth/round the circle is.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_circle_line(x f32, y f32, radius int, segments int, c gx.Color) {
pub fn (ctx &Context) draw_circle_line(x f32, y f32, radius int, segments int, c Color) {
if segments <= 0 {
return
}
@ -687,7 +686,7 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, radius int, segments int, c
// draw_slice_empty draws the outline of a circle slice/pie
pub fn (ctx &Context) draw_slice_empty(x f32, y f32, radius f32, start_angle f32, end_angle f32, segments int,
c gx.Color) {
c Color) {
if segments <= 0 || radius <= 0 {
return
}
@ -724,7 +723,7 @@ pub fn (ctx &Context) draw_slice_empty(x f32, y f32, radius f32, start_angle f32
// `segments` affects how smooth/round the slice is.
// `c` is the fill color.
pub fn (ctx &Context) draw_slice_filled(x f32, y f32, radius f32, start_angle f32, end_angle f32, segments int,
c gx.Color) {
c Color) {
if segments <= 0 || radius < 0 {
return
}
@ -766,7 +765,7 @@ pub fn (ctx &Context) draw_slice_filled(x f32, y f32, radius f32, start_angle f3
// `segments` affects how smooth/round the arc is.
// `c` is the color of the arc/outline.
pub fn (ctx Context) draw_arc_line(x f32, y f32, radius f32, start_angle f32, end_angle f32, segments int,
c gx.Color) {
c Color) {
if segments <= 0 || radius < 0 {
return
}
@ -814,7 +813,7 @@ pub fn (ctx Context) draw_arc_line(x f32, y f32, radius f32, start_angle f32, en
// `segments` affects how smooth/round the arc is.
// `c` is the color of the arc outline.
pub fn (ctx &Context) draw_arc_empty(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32,
segments int, c gx.Color) {
segments int, c Color) {
outer_radius := inner_radius + thickness
if segments <= 0 || outer_radius < 0 {
return
@ -878,7 +877,7 @@ pub fn (ctx &Context) draw_arc_empty(x f32, y f32, inner_radius f32, thickness f
// `segments` affects how smooth/round the arc is.
// `c` is the fill color of the arc.
pub fn (ctx &Context) draw_arc_filled(x f32, y f32, inner_radius f32, thickness f32, start_angle f32, end_angle f32,
segments int, c gx.Color) {
segments int, c Color) {
outer_radius := inner_radius + thickness
if segments <= 0 || outer_radius < 0 {
return
@ -935,7 +934,7 @@ pub fn (ctx &Context) draw_arc_filled(x f32, y f32, inner_radius f32, thickness
// `rw` defines the *width* radius of the ellipse.
// `rh` defines the *height* radius of the ellipse.
// `c` is the color of the outline.
pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c gx.Color) {
pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c Color) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -955,7 +954,7 @@ pub fn (ctx &Context) draw_ellipse_empty(x f32, y f32, rw f32, rh f32, c gx.Colo
// `rw` defines the *width* radius of the ellipse.
// `rh` defines the *height* radius of the ellipse.
// `c` is the fill color.
pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c gx.Color) {
pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c Color) {
if c.a != 255 {
sgl.load_pipeline(ctx.pipeline.alpha)
}
@ -975,7 +974,7 @@ pub fn (ctx &Context) draw_ellipse_filled(x f32, y f32, rw f32, rh f32, c gx.Col
// The four points is provided as one `points` array which contains a stream of point pairs (x and y coordinates).
// Thus a cubic Bézier could be declared as: `points := [x1, y1, control_x1, control_y1, control_x2, control_y2, x2, y2]`.
// Please see `draw_cubic_bezier_in_steps` to control the amount of steps (segments) used to draw the curve.
pub fn (ctx &Context) draw_cubic_bezier(points []f32, c gx.Color) {
pub fn (ctx &Context) draw_cubic_bezier(points []f32, c Color) {
ctx.draw_cubic_bezier_in_steps(points, u32(30 * ctx.scale), c)
}
@ -984,7 +983,7 @@ pub fn (ctx &Context) draw_cubic_bezier(points []f32, c gx.Color) {
// taken to draw the curve.
// The four points is provided as one `points` array which contains a stream of point pairs (x and y coordinates).
// Thus a cubic Bézier could be declared as: `points := [x1, y1, control_x1, control_y1, control_x2, control_y2, x2, y2]`.
pub fn (ctx &Context) draw_cubic_bezier_in_steps(points []f32, steps u32, c gx.Color) {
pub fn (ctx &Context) draw_cubic_bezier_in_steps(points []f32, steps u32, c Color) {
if steps <= 0 || steps >= 20000 || points.len != 8 {
return
}

View file

@ -5,7 +5,6 @@ module gg
import os
import os.font
import gx
import time
import sokol.sapp
import sokol.sgl
@ -93,9 +92,9 @@ pub:
window_title string // the desired title of the window
icon sapp.IconDesc
html5_canvas_name string = 'canvas'
borderless_window bool // TODO: implement or deprecate
always_on_top bool // TODO: implement or deprecate
bg_color gx.Color // The background color of the window. By default, the first thing gg does in ctx.begin(), is clear the whole buffer with that color.
borderless_window bool // TODO: implement or deprecate
always_on_top bool // TODO: implement or deprecate
bg_color Color // The background color of the window. By default, the first thing gg does in ctx.begin(), is clear the whole buffer with that color.
init_fn FNCb = unsafe { nil } // Called once, after Sokol has finished its setup. Some gg and Sokol functions have to be called *in this* callback, or after this callback, but not before
frame_fn FNCb = unsafe { nil } // Called once per frame, usually 60 times a second (depends on swap_interval). See also https://dri.freedesktop.org/wiki/ConfigurationOptions/#synchronizationwithverticalrefreshswapintervals
native_frame_fn FNCb = unsafe { nil }
@ -581,7 +580,7 @@ pub fn (ctx &Context) quit() {
}
// set_bg_color sets the color of the window background to `c`.
pub fn (mut ctx Context) set_bg_color(c gx.Color) {
pub fn (mut ctx Context) set_bg_color(c Color) {
ctx.clear_pass = gfx.create_clear_pass_action(f32(c.r) / 255.0, f32(c.g) / 255.0,
f32(c.b) / 255.0, f32(c.a) / 255.0)
}
@ -697,13 +696,13 @@ pub mut:
width int // minimum width
height int // minimum height
show bool // do not show by default, use `-d show_fps` or set it manually in your app to override with: `app.gg.fps.show = true`
text_config gx.TextCfg = gx.TextCfg{
color: gx.yellow
text_config TextCfg = TextCfg{
color: yellow
size: 20
align: .center
vertical_align: .middle
}
background_color gx.Color = gx.Color{
background_color Color = Color{
r: 0
g: 0
b: 0

View file

@ -1,6 +1,5 @@
module gg
import gx
import js.dom
pub enum DOMEventType {
@ -210,7 +209,7 @@ pub:
window_title string
borderless_window bool
always_on_top bool
bg_color gx.Color
bg_color Color
init_fn FNCb = unsafe { nil }
frame_fn FNCb = unsafe { nil }
native_frame_fn FNCb = unsafe { nil }
@ -465,7 +464,7 @@ pub fn (mut ctx Context) end() {
// ctx.context.closePath()
}
pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c gx.Color) {
pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c Color) {
ctx.context.beginPath()
ctx.context.strokeStyle = c.to_css_string().str
ctx.context.moveTo(x1, y1)
@ -477,7 +476,7 @@ pub fn (mut ctx Context) draw_line(x1 f32, y1 f32, x2 f32, y2 f32, c gx.Color) {
pub fn (mut ctx Context) quit() {
}
pub fn (mut ctx Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) {
pub fn (mut ctx Context) draw_rect(x f32, y f32, w f32, h f32, c Color) {
ctx.context.beginPath()
ctx.context.fillStyle = c.to_css_string().str
ctx.context.fillRect(x, y, w, h)

View file

@ -3,8 +3,6 @@
module gg
import gx
pub type FNCb = fn (data voidptr)
pub type FNEvent = fn (e &Event, data voidptr)
@ -27,7 +25,7 @@ pub type FNChar = fn (c u32, data voidptr)
pub struct PenConfig {
pub:
color gx.Color
color Color
line_type PenLineType = .solid
thickness f32 = 1
}

View file

@ -20,5 +20,3 @@ fn C.darwin_draw_image(f32, f32, f32, f32, &Image)
fn C.darwin_draw_circle(f32, f32, f32, voidptr)
fn C.darwin_draw_circle_empty(f32, f32, f32, voidptr)
//, gx.Color c)

View file

@ -1,6 +1,6 @@
#include <Cocoa/Cocoa.h>
NSColor* nscolor(gx__Color c) {
NSColor* nscolor(gg__Color c) {
float red = (float)c.r / 255.0f;
float green = (float)c.g / 255.0f;
float blue = (float)c.b / 255.0f;
@ -58,7 +58,7 @@ gg__Size gg_get_screen_size() {
return res;
}
void darwin_draw_string(int x, int y, string s, gx__TextCfg cfg) {
void darwin_draw_string(int x, int y, string s, gg__TextCfg cfg) {
NSFont* font = [NSFont userFontOfSize:0]; // cfg.size];
// # NSFont* font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size];
if (cfg.mono) {
@ -99,7 +99,7 @@ int darwin_text_width(string s) {
return (int)(ceil(size.width));
}
void darwin_draw_rect(float x, float y, float width, float height, gx__Color c) {
void darwin_draw_rect(float x, float y, float width, float height, gg__Color c) {
NSColor* color = nscolor(c);
NSRect rect = NSMakeRect(x, y, width, height);
[color setFill];
@ -142,7 +142,7 @@ void darwin_draw_image(float x, float y, float w, float h, gg__Image* img) {
[i drawInRect:NSMakeRect(x, y, w, h)];
}
void darwin_draw_circle(float x, float y, float d, gx__Color color) {
void darwin_draw_circle(float x, float y, float d, gg__Color color) {
NSColor* c = nscolor(color);
NSRect rect = NSMakeRect(x, y, d * 2, d * 2);
NSBezierPath* circlePath = [NSBezierPath bezierPath];
@ -153,7 +153,7 @@ void darwin_draw_circle(float x, float y, float d, gx__Color color) {
// NSRectFill(rect);
}
void darwin_draw_circle_empty(float x, float y, float d, gx__Color color) {
void darwin_draw_circle_empty(float x, float y, float d, gg__Color color) {
NSColor* outlineColor = nscolor(color);
CGFloat outlineWidth = 1.0; //2.0;

View file

@ -1,6 +1,5 @@
module gg
import gx
import sokol.sgl
// Stuff for ui from now for screenshot (that would be interesting for gg if screenshot is implemented also for gg)
@ -11,11 +10,13 @@ pub fn (ctx &Context) scissor_rect(x int, y int, w int, h int) {
true)
}
// empty function
pub fn (ctx &Context) has_text_style() bool {
return false
}
pub fn (ctx &Context) set_text_style(font_name string, font_path string, size int, color gx.Color, align int,
// empty function
pub fn (ctx &Context) set_text_style(font_name string, font_path string, size int, color Color, align int,
vertical_align int) {
}

View file

@ -2,8 +2,6 @@
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module gg
import gx
// DrawImageConfig struct defines the various options
// that can be used to draw an image onto the screen
pub struct DrawImageConfig {
@ -15,7 +13,7 @@ pub mut:
img_rect Rect // defines the size and position on image when rendering to the screen
part_rect Rect // defines the size and position of part of the image to use when rendering
z f32
color gx.Color = gx.white
color Color = white
effect ImageEffect = .alpha
rotation f32 // the amount to rotate the image in degrees, counterclockwise. Use a negative value, to rotate it clockwise.

View file

@ -1,5 +0,0 @@
module gg
import gx
pub type Color = gx.Color

View file

@ -2,7 +2,6 @@ module main
import math
import gg
import gx
fn main() {
mut context := gg.new_context(
@ -16,7 +15,7 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_arc_filled(100, 100, 35, 45, 0, f32(math.radians(290)), 30, gx.red)
ctx.draw_arc_empty(100, 100, 30, 50, 0, f32(math.radians(290)), 30, gx.white)
ctx.draw_arc_filled(100, 100, 35, 45, 0, f32(math.radians(290)), 30, gg.red)
ctx.draw_arc_empty(100, 100, 30, 50, 0, f32(math.radians(290)), 30, gg.white)
ctx.end()
}

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
@ -15,10 +14,10 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_circle_empty(150, 150, 80, gx.blue)
ctx.draw_circle_filled(150, 150, 40, gx.yellow)
ctx.draw_circle_line(150, 150, 80, 6, gx.red)
ctx.draw_circle_line(150, 150, 120, 6, gx.green)
ctx.draw_circle_line(150, 150, 150, 8, gx.white)
ctx.draw_circle_empty(150, 150, 80, gg.blue)
ctx.draw_circle_filled(150, 150, 40, gg.yellow)
ctx.draw_circle_line(150, 150, 80, 6, gg.red)
ctx.draw_circle_line(150, 150, 120, 6, gg.green)
ctx.draw_circle_line(150, 150, 150, 8, gg.white)
ctx.end()
}

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
@ -15,7 +14,7 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_ellipse_filled(100, 100, 100, 50, gx.red)
ctx.draw_ellipse_empty(100, 100, 50, 25, gx.black)
ctx.draw_ellipse_filled(100, 100, 100, 50, gg.red)
ctx.draw_ellipse_empty(100, 100, 50, 25, gg.black)
ctx.end()
}

View file

@ -1,11 +1,10 @@
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Polygons'
@ -17,8 +16,8 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0, 300.0],
gx.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gx.red)
gg.blue)
ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gg.black)
ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gg.red)
ctx.end()
}

View file

@ -1,24 +1,23 @@
module main
import gg
import gx
gg.start(
bg_color: gx.white
bg_color: gg.white
window_title: 'Rectangles'
width: 250
height: 100
frame_fn: fn (ctx &gg.Context) {
ctx.begin()
ctx.draw_rect_filled(10, 10, 10, 10, gx.blue)
ctx.draw_rect_empty(30, 10, 10, 10, gx.red)
ctx.draw_rect_filled(50, 10, 30, 10, gx.green)
ctx.draw_rect_empty(100, 10, 30, 10, gx.black)
ctx.draw_rect_filled(10, 10, 10, 10, gg.blue)
ctx.draw_rect_empty(30, 10, 10, 10, gg.red)
ctx.draw_rect_filled(50, 10, 30, 10, gg.green)
ctx.draw_rect_empty(100, 10, 30, 10, gg.black)
ctx.draw_rect_empty(10, 50, 10, 10, gx.blue)
ctx.draw_rect_filled(30, 50, 10, 10, gx.red)
ctx.draw_rect_empty(50, 50, 30, 10, gx.green)
ctx.draw_rect_filled(100, 50, 30, 10, gx.black)
ctx.draw_rect_empty(10, 50, 10, 10, gg.blue)
ctx.draw_rect_filled(30, 50, 10, 10, gg.red)
ctx.draw_rect_empty(50, 50, 30, 10, gg.green)
ctx.draw_rect_filled(100, 50, 30, 10, gg.black)
ctx.end()
}
)

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
fn main() {
mut context := gg.new_context(
@ -16,19 +15,19 @@ fn main() {
fn frame(mut ctx gg.Context) {
ctx.begin()
// these should be rounded rectangles
ctx.draw_rounded_rect_empty(10, 10, 50, 100, 5, gx.blue)
ctx.draw_rounded_rect_empty(25, 25, 50, 100, 15, gx.yellow)
ctx.draw_rounded_rect_empty(50, 50, 50, 100, 50, gx.red)
ctx.draw_rounded_rect_empty(75, 75, 50, 100, 100, gx.green)
ctx.draw_rounded_rect_empty(100, 100, 50, 100, 1000, gx.white)
ctx.draw_rounded_rect_empty(110, 10, 100, 50, 5, gx.blue)
ctx.draw_rounded_rect_empty(125, 25, 100, 50, 15, gx.yellow)
ctx.draw_rounded_rect_empty(150, 50, 100, 50, 50, gx.red)
ctx.draw_rounded_rect_empty(175, 75, 100, 50, 100, gx.green)
ctx.draw_rounded_rect_empty(200, 100, 100, 50, 1000, gx.white)
ctx.draw_rounded_rect_empty(10, 10, 50, 100, 5, gg.blue)
ctx.draw_rounded_rect_empty(25, 25, 50, 100, 15, gg.yellow)
ctx.draw_rounded_rect_empty(50, 50, 50, 100, 50, gg.red)
ctx.draw_rounded_rect_empty(75, 75, 50, 100, 100, gg.green)
ctx.draw_rounded_rect_empty(100, 100, 50, 100, 1000, gg.white)
ctx.draw_rounded_rect_empty(110, 10, 100, 50, 5, gg.blue)
ctx.draw_rounded_rect_empty(125, 25, 100, 50, 15, gg.yellow)
ctx.draw_rounded_rect_empty(150, 50, 100, 50, 50, gg.red)
ctx.draw_rounded_rect_empty(175, 75, 100, 50, 100, gg.green)
ctx.draw_rounded_rect_empty(200, 100, 100, 50, 1000, gg.white)
// this should be a perfect circle
ctx.draw_rounded_rect_empty(10, 200, 50, 50, 1000, gx.magenta)
ctx.draw_rounded_rect_empty(10, 200, 50, 50, 1000, gg.magenta)
// this should be a perfect square
ctx.draw_rounded_rect_empty(250, 200, 50, 50, 0, gx.cyan)
ctx.draw_rounded_rect_empty(250, 200, 50, 50, 0, gg.cyan)
ctx.end()
}

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
struct App {
mut:
@ -20,7 +19,7 @@ fn main() {
window_title: 'Simple Polygons'
width: 500
height: 500
bg_color: gx.black
bg_color: gg.black
event_fn: event
frame_fn: render
user_data: app
@ -32,7 +31,7 @@ fn main() {
fn render(app &App) {
app.gg.begin()
color := gx.Color{
color := gg.Color{
r: 175
g: 0
b: 0

View file

@ -1,7 +1,6 @@
module main
import gg
import gx
struct App {
mut:
@ -12,7 +11,7 @@ mut:
fn main() {
mut app := &App{}
app.gg = gg.new_context(
bg_color: gx.white
bg_color: gg.white
width: 300
height: 300
window_title: 'Circles'
@ -42,7 +41,7 @@ fn on_event(e &gg.Event, mut app App) {
fn frame(mut app App) {
app.gg.begin()
app.gg.draw_circle_empty(150, 150, f32(app.radius), gx.blue)
app.gg.draw_circle_empty(150, 150, f32(app.radius), gg.blue)
app.gg.draw_text(20, 20, 'radius: ${app.radius}')
// app.gg.draw_text(20, 50, 'circle_segment_size: $circle_segment_size')
app.gg.end()

View file

@ -5,7 +5,6 @@ module gg
import fontstash
import sokol.sfons
import sokol.sgl
import gx
import os
import os.font
@ -21,6 +20,19 @@ pub mut:
scale f32 = 1.0
}
pub enum HorizontalAlign {
left = C.FONS_ALIGN_LEFT
center = C.FONS_ALIGN_CENTER
right = C.FONS_ALIGN_RIGHT
}
pub enum VerticalAlign {
top = C.FONS_ALIGN_TOP
middle = C.FONS_ALIGN_MIDDLE
bottom = C.FONS_ALIGN_BOTTOM
baseline = C.FONS_ALIGN_BASELINE
}
const buff_size = int($d('gg_text_buff_size', 2048))
fn clear_atlas_callback(uptr voidptr, error int, _val int) {
@ -131,7 +143,7 @@ fn new_ft(c FTConfig) ?&FT {
}
// set_text_cfg sets the current text configuration
pub fn (ctx &Context) set_text_cfg(cfg gx.TextCfg) {
pub fn (ctx &Context) set_text_cfg(cfg TextCfg) {
if !ctx.font_inited {
return
}
@ -181,10 +193,10 @@ pub:
y int
text string
color Color = gx.black
size int = 16
align gx.HorizontalAlign = .left
vertical_align gx.VerticalAlign = .top
color Color = black
size int = 16
align HorizontalAlign = .left
vertical_align VerticalAlign = .top
max_width int
family string
bold bool
@ -193,7 +205,7 @@ pub:
}
pub fn (ctx &Context) draw_text2(p DrawTextParams) {
ctx.draw_text(p.x, p.y, p.text, gx.TextCfg{
ctx.draw_text(p.x, p.y, p.text, TextCfg{
color: p.color
size: p.size
align: p.align
@ -208,10 +220,10 @@ pub fn (ctx &Context) draw_text2(p DrawTextParams) {
// draw_text draws the string in `text_` starting at top-left position `x`,`y`.
// Text settings can be provided with `cfg`.
pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg TextCfg) {
$if macos {
if ctx.native_rendering {
if cfg.align == gx.align_right {
if cfg.align == align_right {
width := ctx.text_width(text_)
// println('draw text ctx.height = ${ctx.height}')
C.darwin_draw_string(x - width, ctx.height - y, text_, cfg)

View file

@ -1,8 +1,19 @@
module gg
import gx
pub enum HorizontalAlign {
left
center
right
}
pub fn (mut ctx Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
pub enum VerticalAlign {
top
middle
bottom
baseline
}
pub fn (mut ctx Context) draw_text(x int, y int, text_ string, cfg TextCfg) {
ctx.context.fillStyle = cfg.color.to_css_string().str
ctx.context.font = cfg.to_css_string().str
ctx.context.fillText(text_.str, x, y)

View file

@ -2,7 +2,8 @@
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module gg
import gx
pub const align_right = HorizontalAlign.right
pub const align_left = HorizontalAlign.left
struct FTConfig {
font_path string
@ -19,10 +20,40 @@ struct StringToRender {
x int
y int
text string
cfg gx.TextCfg
cfg TextCfg
}
@[if debug_font ?]
fn debug_font_println(s string) {
println(s)
}
@[markused; params]
pub struct TextCfg {
pub:
color Color = black
size int = 16
align HorizontalAlign = .left
vertical_align VerticalAlign = .top
max_width int
family string
bold bool
mono bool
italic bool
}
// to_css_string returns a CSS compatible string of the TextCfg `cfg`.
// For example: `'mono 14px serif'`.
pub fn (cfg &TextCfg) to_css_string() string {
mut font_style := ''
if cfg.bold {
font_style += 'bold '
}
if cfg.mono {
font_style += 'mono '
}
if cfg.italic {
font_style += 'italic '
}
return '${font_style} ${cfg.size}px ${cfg.family}'
}

View file

@ -1,320 +1,126 @@
@[deprecated: 'module gx is deprecated, use `import gg` instead']
@[deprecated_after: '2026-01-24']
module gx
pub const black = Color{
r: 0
g: 0
b: 0
}
pub const gray = Color{
r: 128
g: 128
b: 128
}
pub const white = Color{
r: 255
g: 255
b: 255
}
pub const red = Color{
r: 255
g: 0
b: 0
}
pub const green = Color{
r: 0
g: 255
b: 0
}
pub const blue = Color{
r: 0
g: 0
b: 255
}
pub const yellow = Color{
r: 255
g: 255
b: 0
}
pub const magenta = Color{
r: 255
g: 0
b: 255
}
pub const cyan = Color{
r: 0
g: 255
b: 255
}
pub const orange = Color{
r: 255
g: 165
b: 0
}
pub const purple = Color{
r: 128
g: 0
b: 128
}
pub const indigo = Color{
r: 75
g: 0
b: 130
}
pub const pink = Color{
r: 255
g: 192
b: 203
}
pub const violet = Color{
r: 238
g: 130
b: 238
}
pub const dark_blue = Color{
r: 0
g: 0
b: 139
}
pub const dark_gray = Color{
r: 169
g: 169
b: 169
}
pub const dark_green = Color{
r: 0
g: 100
b: 0
}
pub const dark_red = Color{
r: 139
g: 0
b: 0
}
pub const light_blue = Color{
r: 173
g: 216
b: 230
}
pub const light_gray = Color{
r: 211
g: 211
b: 211
}
pub const light_green = Color{
r: 144
g: 238
b: 144
}
pub const light_red = Color{
r: 255
g: 204
b: 203
}
import gg
// Color represents a 32 bit color value in sRGB format
@[markused]
pub struct Color {
pub mut:
r u8
g u8
b u8
a u8 = 255
}
pub type Color = gg.Color
@[deprecated: 'use gg.black instead']
@[deprecated_after: '2026-01-24']
pub const black = gg.black
@[deprecated: 'use gg.gray instead']
@[deprecated_after: '2026-01-24']
pub const gray = gg.gray
@[deprecated: 'use gg.white instead']
@[deprecated_after: '2026-01-24']
pub const white = gg.white
@[deprecated: 'use gg.red instead']
@[deprecated_after: '2026-01-24']
pub const red = gg.red
@[deprecated: 'use gg.green instead']
@[deprecated_after: '2026-01-24']
pub const green = gg.green
@[deprecated: 'use gg.blue instead']
@[deprecated_after: '2026-01-24']
pub const blue = gg.blue
@[deprecated: 'use gg.yellow instead']
@[deprecated_after: '2026-01-24']
pub const yellow = gg.yellow
@[deprecated: 'use gg.magenta instead']
@[deprecated_after: '2026-01-24']
pub const magenta = gg.magenta
@[deprecated: 'use gg.cyan instead']
@[deprecated_after: '2026-01-24']
pub const cyan = gg.cyan
@[deprecated: 'use gg.orange instead']
@[deprecated_after: '2026-01-24']
pub const orange = gg.orange
@[deprecated: 'use gg.purple instead']
@[deprecated_after: '2026-01-24']
pub const purple = gg.purple
@[deprecated: 'use gg.indigo instead']
@[deprecated_after: '2026-01-24']
pub const indigo = gg.indigo
@[deprecated: 'use gg.pink instead']
@[deprecated_after: '2026-01-24']
pub const pink = gg.pink
@[deprecated: 'use gg.violet instead']
@[deprecated_after: '2026-01-24']
pub const violet = gg.violet
@[deprecated: 'use gg.dark_blue instead']
@[deprecated_after: '2026-01-24']
pub const dark_blue = gg.dark_blue
@[deprecated: 'use gg.dark_gray instead']
@[deprecated_after: '2026-01-24']
pub const dark_gray = gg.dark_gray
@[deprecated: 'use gg.dark_green instead']
@[deprecated_after: '2026-01-24']
pub const dark_green = gg.dark_green
@[deprecated: 'use gg.dark_red instead']
@[deprecated_after: '2026-01-24']
pub const dark_red = gg.dark_red
@[deprecated: 'use gg.light_blue instead']
@[deprecated_after: '2026-01-24']
pub const light_blue = gg.light_blue
@[deprecated: 'use gg.light_gray instead']
@[deprecated_after: '2026-01-24']
pub const light_gray = gg.light_gray
@[deprecated: 'use gg.light_green instead']
@[deprecated_after: '2026-01-24']
pub const light_green = gg.light_green
@[deprecated: 'use gg.light_red instead']
@[deprecated_after: '2026-01-24']
pub const light_red = gg.light_red
// hex takes in a 32 bit integer and splits it into 4 byte values
/*
@[deprecated: 'use gg.hex instead']
@[deprecated_after: '2026-01-24']
pub fn hex(color int) Color {
return Color{
r: u8((color >> 24) & 0xFF)
g: u8((color >> 16) & 0xFF)
b: u8((color >> 8) & 0xFF)
a: u8(color & 0xFF)
}
}
*/
pub fn hex(color int) Color {
return Color{
r: u8((color >> 16) & 0xFF)
g: u8((color >> 8) & 0xFF)
b: u8((color >> 0) & 0xFF)
}
return gg.hex(color)
}
// rgb builds a Color instance from given r, g, b values
@[deprecated: 'use gg.rgb instead']
@[deprecated_after: '2026-01-24']
pub fn rgb(r u8, g u8, b u8) Color {
return Color{
r: r
g: g
b: b
}
return gg.rgb(r, g, b)
}
// rgba builds a Color instance from given r, g, b, a values
@[deprecated: 'use gg.rgba instead']
@[deprecated_after: '2026-01-24']
pub fn rgba(r u8, g u8, b u8, a u8) Color {
return Color{
r: r
g: g
b: b
a: a
}
}
// + adds `b` to `a`, with a maximum value of 255 for each channel
pub fn (a Color) + (b Color) Color {
mut na := int(a.a) + b.a
mut nr := int(a.r) + b.r
mut ng := int(a.g) + b.g
mut nb := int(a.b) + b.b
if na > 255 {
na = 255
}
if nr > 255 {
nr = 255
}
if ng > 255 {
ng = 255
}
if nb > 255 {
nb = 255
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// - subtracts `b` from `a`, with a minimum value of 0 for each channel
pub fn (a Color) - (b Color) Color {
mut na := if a.a > b.a { a.a } else { b.a }
mut nr := int(a.r) - b.r
mut ng := int(a.g) - b.g
mut nb := int(a.b) - b.b
if na < 0 {
na = 0
}
if nr < 0 {
nr = 0
}
if ng < 0 {
ng = 0
}
if nb < 0 {
nb = 0
}
return Color{
r: u8(nr)
g: u8(ng)
b: u8(nb)
a: u8(na)
}
}
// * multiplies Color `c` and `c2` keeping channel values in [0, 255] range
pub fn (c Color) * (c2 Color) Color {
return Color{
r: c.r * c2.r
g: c.g * c2.g
b: c.b * c2.b
a: c.a * c2.a
}
}
// / divides `c` by `c2` and converts each channel's value to u8(int)
pub fn (c Color) / (c2 Color) Color {
return Color{
r: c.r / c2.r
g: c.g / c2.g
b: c.b / c2.b
a: c.a / c2.a
}
}
// over implements an `a` over `b` operation.
// see https://keithp.com/~keithp/porterduff/p253-porter.pdf
pub fn (a Color) over(b Color) Color {
aa := f32(a.a) / 255
ab := f32(b.a) / 255
ar := aa + ab * (1 - aa)
rr := (f32(a.r) * aa + f32(b.r) * ab * (1 - aa)) / ar
gr := (f32(a.g) * aa + f32(b.g) * ab * (1 - aa)) / ar
br := (f32(a.b) * aa + f32(b.b) * ab * (1 - aa)) / ar
return Color{
r: u8(rr)
g: u8(gr)
b: u8(br)
a: u8(ar * 255)
}
}
// eq checks if color `c` and `c2` are equal in every channel
pub fn (c Color) eq(c2 Color) bool {
return c.r == c2.r && c.g == c2.g && c.b == c2.b && c.a == c2.a
}
// str returns a string representation of the Color `c`
pub fn (c Color) str() string {
return 'Color{${c.r}, ${c.g}, ${c.b}, ${c.a}}'
}
// rgba8 converts a color value to an int in the RGBA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) rgba8() int {
return int(u32(c.r) << 24 | u32(c.g) << 16 | u32(c.b) << 8 | u32(c.a))
}
// bgra8 converts a color value to an int in the BGRA8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) bgra8() int {
return int(u32(c.b) << 24 | u32(c.g) << 16 | u32(c.r) << 8 | u32(c.a))
}
// abgr8 converts a color value to an int in the ABGR8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat
@[inline]
pub fn (c Color) abgr8() int {
return int(u32(c.a) << 24 | u32(c.b) << 16 | u32(c.g) << 8 | u32(c.r))
}
const string_colors = {
'blue': blue
'red': red
'green': green
'yellow': yellow
'orange': orange
'purple': purple
'black': black
'gray': gray
'indigo': indigo
'pink': pink
'violet': violet
'white': white
'dark_blue': dark_blue
'dark_gray': dark_gray
'dark_green': dark_green
'dark_red': dark_red
'light_blue': light_blue
'light_gray': light_gray
'light_green': light_green
'light_red': light_red
return gg.rgba(r, g, b, a)
}
// color_from_string returns a Color, corresponding to the given string
// or black Color if string is not found in lookup table, or a hex color if starting with #
@[deprecated: 'use gg.color_from_string instead']
@[deprecated_after: '2026-01-24']
pub fn color_from_string(s string) Color {
if s.starts_with('#') {
mut hex_str := '0x' + s[1..]
return hex(hex_str.int())
} else {
return string_colors[s]
}
}
// to_css_string returns a CSS compatible string e.g. `rgba(10,11,12,13)` of the color `c`.
pub fn (c Color) to_css_string() string {
return 'rgba(${c.r},${c.g},${c.b},${c.a})'
return gg.color_from_string(s)
}

View file

@ -1,3 +1,4 @@
// vtest build: !musl? // gx now transitively imports sokol, and that needs GL/gl.h, which is not installed on the musl CIs
import gx
fn test_hex() {

View file

@ -1,5 +1,9 @@
@[deprecated: 'module gx is deprecated, use `import gg` instead']
@[deprecated_after: '2026-01-24']
module gx
@[deprecated: 'use gg.Image']
@[deprecated_after: '2026-01-24']
pub struct Image {
mut:
obj voidptr

View file

@ -1,16 +1,10 @@
@[deprecated: 'module gx is deprecated, use import gg instead']
@[deprecated_after: '2026-01-24']
module gx
import fontstash as _
import gg
pub enum HorizontalAlign {
left = C.FONS_ALIGN_LEFT
center = C.FONS_ALIGN_CENTER
right = C.FONS_ALIGN_RIGHT
}
pub type HorizontalAlign = gg.HorizontalAlign
pub enum VerticalAlign {
top = C.FONS_ALIGN_TOP
middle = C.FONS_ALIGN_MIDDLE
bottom = C.FONS_ALIGN_BOTTOM
baseline = C.FONS_ALIGN_BASELINE
}
pub type VerticalAlign = gg.VerticalAlign

View file

@ -1,11 +1,17 @@
@[deprecated: 'module gx is deprecated, use import gg instead']
@[deprecated_after: '2026-01-24']
module gx
@[deprecated: 'use gg.HorizontalAlign instead']
@[deprecated_after: '2026-01-24']
pub enum HorizontalAlign {
left
center
right
}
@[deprecated: 'use gg.VerticalAlign instead']
@[deprecated_after: '2026-01-24']
pub enum VerticalAlign {
top
middle

View file

@ -1,35 +1,11 @@
@[deprecated: 'module gx is deprecated, use `import gg` instead']
@[deprecated_after: '2026-01-24']
module gx
import gg
// TODO: remove these, and use the enum everywhere
pub const align_left = HorizontalAlign.left
pub const align_right = HorizontalAlign.right
@[markused; params]
pub struct TextCfg {
pub:
color Color = black
size int = 16
align HorizontalAlign = .left
vertical_align VerticalAlign = .top
max_width int
family string
bold bool
mono bool
italic bool
}
// to_css_string returns a CSS compatible string of the TextCfg `cfg`.
// For example: `'mono 14px serif'`.
pub fn (cfg &TextCfg) to_css_string() string {
mut font_style := ''
if cfg.bold {
font_style += 'bold '
}
if cfg.mono {
font_style += 'mono '
}
if cfg.italic {
font_style += 'italic '
}
return '${font_style} ${cfg.size}px ${cfg.family}'
}
pub type TextCfg = gg.TextCfg

View file

@ -1,5 +1,5 @@
import gx
import gg
const color = gx.rgb(50, 90, 110) // gx.rgb(167,236,82)
const color = gg.rgb(50, 90, 110) // gg.rgb(167,236,82)
fn main() {}

View file

@ -1,8 +1,8 @@
import gx
import gg
const (
color = //gx.rgb(167,236,82)
gx.rgb(50, 90, 110)
color = //gg.rgb(167,236,82)
gg.rgb(50, 90, 110)
)
fn main() {}

View file

@ -1,7 +1,6 @@
module ui
import gg
import gx
import eventbus
pub type DrawFn = fn (ctx &gg.Context, state voidptr)
@ -31,7 +30,7 @@ pub mut:
my f64
width int
height int
bg_color gx.Color
bg_color gg.Color
click_fn ClickFn
mouse_down_fn ClickFn
mouse_up_fn ClickFn
@ -51,7 +50,7 @@ pub:
always_on_top bool
state voidptr
draw_fn DrawFn
bg_color gx.Color = default_window_color
bg_color gg.Color = default_window_color
on_click ClickFn
on_mouse_down ClickFn
on_mouse_up ClickFn

View file

@ -1,6 +1,5 @@
// vtest build: !musl?
import gg
import gx
struct Game {
mut:
@ -12,7 +11,7 @@ fn test_c_struct_with_reserved_field_name() {
gg: none
}
mut cont := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Polygons'

View file

@ -1,10 +1,11 @@
import gx
// vtest build: !musl? // gx now transitively imports sokol, and that needs GL/gl.h, which is not installed on the musl CIs
import gg
const left = gx.align_left
const left = gg.HorizontalAlign.left
fn test_main() {
align := left
assert dump(align.str()) == 'left'
assert dump(gx.align_left) == gx.align_left
assert gx.align_left.str() == 'left'
assert dump(gg.HorizontalAlign.left) == gg.HorizontalAlign.left
assert gg.HorizontalAlign.left.str() == 'left'
}

View file

@ -2,11 +2,10 @@
module main
import gg
import gx
fn main() {
x := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
bg_color: gg.rgb(174, 198, 255)
window_title: 'GG Hello'
frame_fn: fn (mut ctx gg.Context) {
ctx.begin()

View file

@ -240,7 +240,6 @@ Here a simple example of the usage:
```v oksyntax
import gg
import gx
import sokol.sapp
import sokol.sgl
import sokol.gfx
@ -249,7 +248,7 @@ import os
const win_width = 600
const win_height = 700
const bg_color = gx.white
const bg_color = gg.white
const font_paths = [
'arial.ttf',
]