// Copyright 2026 Ling71671
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
fn calc_ruler_step(zoom : Double) -> Double {
let target = 80.0 / zoom
if target > 20000.0 {
50000.0
} else if target > 10000.0 {
20000.0
} else if target > 5000.0 {
10000.0
} else if target > 2000.0 {
5000.0
} else if target > 1000.0 {
2000.0
} else if target > 500.0 {
1000.0
} else if target > 200.0 {
500.0
} else if target > 100.0 {
200.0
} else if target > 50.0 {
100.0
} else if target > 20.0 {
50.0
} else {
20.0
}
}
///|
fn render_grid_aisles(
dl : @draw.DrawList,
state : BenchmarkState,
cv_x : Double,
cv_y : Double,
cv_w : Double,
cv_h : Double,
sc_x : Double,
sc_y : Double,
) -> Unit {
let aisle_col = @color.Color::border_muted()
for bi = 0; bi <= 10; bi = bi + 1 {
let aisle_wx = bi.to_double() * 1000.0
let aisle_sx = sc_x + (aisle_wx - state.cam_x) * state.zoom
if aisle_sx >= cv_x && aisle_sx <= cv_x + cv_w {
dl.add_line(
@math.Vec2::new(aisle_sx, cv_y),
@math.Vec2::new(aisle_sx, cv_y + cv_h),
aisle_col,
1.0,
)
}
let aisle_wy = bi.to_double() * 1000.0
let aisle_sy = sc_y + (aisle_wy - state.cam_y) * state.zoom
if aisle_sy >= cv_y && aisle_sy <= cv_y + cv_h {
dl.add_line(
@math.Vec2::new(cv_x, aisle_sy),
@math.Vec2::new(cv_x + cv_w, aisle_sy),
aisle_col,
1.0,
)
}
}
}
///|
fn render_cad_rulers(
dl : @draw.DrawList,
state : BenchmarkState,
cv_x : Double,
cv_y : Double,
cv_w : Double,
cv_h : Double,
vp_x : Double,
vp_y : Double,
ruler_w : Double,
ruler_h : Double,
min_wx : Double,
max_wx : Double,
min_wy : Double,
max_wy : Double,
sc_x : Double,
sc_y : Double,
) -> Unit {
let ruler_bg = @color.Color::bg_window()
let ruler_border = @color.Color::border_muted()
let ruler_tick_col = @color.Color::border_strong()
let ruler_text_col = @color.Color::text_secondary()
// Top Ruler Background & Border
dl.add_rect(@math.Rect::new(cv_x, vp_y, cv_w, ruler_h), ruler_bg, 0.0)
dl.add_line(
@math.Vec2::new(cv_x, vp_y + ruler_h),
@math.Vec2::new(cv_x + cv_w, vp_y + ruler_h),
ruler_border,
1.0,
)
// Left Ruler Background & Border
dl.add_rect(@math.Rect::new(vp_x, cv_y, ruler_w, cv_h), ruler_bg, 0.0)
dl.add_line(
@math.Vec2::new(vp_x + ruler_w, cv_y),
@math.Vec2::new(vp_x + ruler_w, cv_y + cv_h),
ruler_border,
1.0,
)
// Top-Left Corner Box
dl.add_rect(
@math.Rect::new(vp_x, vp_y, ruler_w, ruler_h),
@color.Color::bg_surface(),
0.0,
)
dl.add_text(
@math.Vec2::new(vp_x + 16.0, vp_y + 4.0),
"px",
10.0,
ruler_text_col,
)
// Draw Top Ruler Ticks & Coordinate Labels
let step_x = calc_ruler_step(state.zoom)
let first_tick_x = (min_wx / step_x).to_int().to_double() * step_x
let mut cur_wx = first_tick_x
while cur_wx <= max_wx {
let sx = sc_x + (cur_wx - state.cam_x) * state.zoom
if sx >= cv_x && sx <= cv_x + cv_w {
dl.add_line(
@math.Vec2::new(sx, vp_y + ruler_h - 8.0),
@math.Vec2::new(sx, vp_y + ruler_h),
ruler_tick_col,
1.0,
)
let label_txt = cur_wx.to_int().to_string()
dl.add_text(
@math.Vec2::new(sx + 3.0, vp_y + 3.0),
label_txt,
9.0,
ruler_text_col,
)
}
cur_wx = cur_wx + step_x
}
// Draw Left Ruler Ticks & Coordinate Labels
let step_y = calc_ruler_step(state.zoom)
let first_tick_y = (min_wy / step_y).to_int().to_double() * step_y
let mut cur_wy = first_tick_y
while cur_wy <= max_wy {
let sy = sc_y + (cur_wy - state.cam_y) * state.zoom
if sy >= cv_y && sy <= cv_y + cv_h {
dl.add_line(
@math.Vec2::new(vp_x + ruler_w - 8.0, sy),
@math.Vec2::new(vp_x + ruler_w, sy),
ruler_tick_col,
1.0,
)
let label_txt = cur_wy.to_int().to_string()
dl.add_text(
@math.Vec2::new(vp_x + 2.0, sy - 5.0),
label_txt,
9.0,
ruler_text_col,
)
}
cur_wy = cur_wy + step_y
}
}
///|
fn render_ruler_projections(
dl : @draw.DrawList,
state : BenchmarkState,
cv_x : Double,
cv_y : Double,
cv_w : Double,
cv_h : Double,
vp_x : Double,
vp_y : Double,
ruler_w : Double,
ruler_h : Double,
sc_x : Double,
sc_y : Double,
pitch : Double,
cell_size : Double,
grid_dim : Int,
) -> Unit {
if state.selected_id >= 0 {
let sel_id = state.selected_id
let r = sel_id / grid_dim
let c = sel_id % grid_dim
let is_dragged = state.item_drag_dx != 0.0 ||
state.item_drag_dy != 0.0 ||
state.is_dragging_item
let sel_orig_wx = c.to_double() * pitch
let sel_orig_wy = r.to_double() * pitch
let sel_wx = if is_dragged {
sel_orig_wx + state.item_drag_dx
} else {
sel_orig_wx
}
let sel_wy = if is_dragged {
sel_orig_wy + state.item_drag_dy
} else {
sel_orig_wy
}
let sel_sx = sc_x + (sel_wx - state.cam_x) * state.zoom
let sel_sy = sc_y + (sel_wy - state.cam_y) * state.zoom
let sel_sw = (cell_size * state.zoom).max(8.0)
let sel_sh = (cell_size * state.zoom).max(8.0)
// Top Ruler Projection Highlight
if sel_sx + sel_sw >= cv_x && sel_sx <= cv_x + cv_w {
let proj_x = sel_sx.max(cv_x)
let proj_w = sel_sw.max(16.0)
dl.add_rect(
@math.Rect::new(proj_x, vp_y, proj_w, ruler_h),
@color.Color::rgba(139, 92, 246, 40),
0.0,
)
dl.add_line(
@math.Vec2::new(proj_x, vp_y),
@math.Vec2::new(proj_x, vp_y + ruler_h),
@color.Color::rgb(139, 92, 246),
1.5,
)
let coord_txt = sel_wx.to_int().to_string()
dl.add_text(
@math.Vec2::new(proj_x + 2.0, vp_y + 2.0),
coord_txt,
9.0,
@color.Color::rgb(109, 40, 217),
)
}
// Left Ruler Projection Highlight
if sel_sy + sel_sh >= cv_y && sel_sy <= cv_y + cv_h {
let proj_y = sel_sy.max(cv_y)
let proj_h = sel_sh.max(16.0)
dl.add_rect(
@math.Rect::new(vp_x, proj_y, ruler_w, proj_h),
@color.Color::rgba(139, 92, 246, 40),
0.0,
)
dl.add_line(
@math.Vec2::new(vp_x, proj_y),
@math.Vec2::new(vp_x + ruler_w, proj_y),
@color.Color::rgb(139, 92, 246),
1.5,
)
let coord_txt = sel_wy.to_int().to_string()
dl.add_text(
@math.Vec2::new(vp_x + 2.0, proj_y),
coord_txt,
9.0,
@color.Color::rgb(109, 40, 217),
)
}
}
}