Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/cubyz/ui/tooltip_background.png

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this slightly transparent? I cannot see through it at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly i dont know myself i just made it like that cuz it looks nicer, i can make it non transparent or more transparent if you like, i can see through it just fine but maybe its cuz of my monitor settings

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to just make it opaque.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/graphics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,30 @@ pub const draw = struct { // MARK: draw
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
}

fn drawSlice(destMin: Vec2f, destMax: Vec2f, uvMin: Vec2f, uvMax: Vec2f) void {
boundSubImage(destMin, destMax - destMin, uvMin, uvMax - uvMin);
}

pub fn bound9SliceImage(pos: Vec2f, dim: Vec2f, textureSize: Vec2f, slices: Vec2f, sliceScale: f32) void {
const widthSlice = slices[0]*sliceScale;
const heightSlice = slices[1]*sliceScale;

// Construct UV
const u: Vec2f = .{slices[0]/textureSize[0], (textureSize[0] - slices[0])/textureSize[0]};
const v: Vec2f = .{slices[1]/textureSize[1], (textureSize[1] - slices[1])/textureSize[1]};

// Draw all Slices
drawSlice(.{pos[0], pos[1]}, .{pos[0] + widthSlice, pos[1] + heightSlice}, .{0, 0}, .{u[0], v[0]});
drawSlice(.{pos[0] + widthSlice, pos[1]}, .{pos[0] + dim[0] - widthSlice, pos[1] + heightSlice}, .{u[0], 0}, .{u[1], v[0]});
drawSlice(.{pos[0] + dim[0] - widthSlice, pos[1]}, .{pos[0] + dim[0], pos[1] + heightSlice}, .{u[1], 0}, .{1, v[0]});
drawSlice(.{pos[0], pos[1] + heightSlice}, .{pos[0] + widthSlice, pos[1] + dim[1] - heightSlice}, .{0, v[0]}, .{u[0], v[1]});
drawSlice(.{pos[0] + widthSlice, pos[1] + heightSlice}, .{pos[0] + dim[0] - widthSlice, pos[1] + dim[1] - heightSlice}, .{u[0], v[0]}, .{u[1], v[1]});
drawSlice(.{pos[0] + dim[0] - widthSlice, pos[1] + heightSlice}, .{pos[0] + dim[0], pos[1] + dim[1] - heightSlice}, .{u[1], v[0]}, .{1, v[1]});
drawSlice(.{pos[0], pos[1] + dim[1] - heightSlice}, .{pos[0] + widthSlice, pos[1] + dim[1]}, .{0, v[1]}, .{u[0], 1});
drawSlice(.{pos[0] + widthSlice, pos[1] + dim[1] - heightSlice}, .{pos[0] + dim[0] - widthSlice, pos[1] + dim[1]}, .{u[0], v[1]}, .{u[1], 1});
drawSlice(.{pos[0] + dim[0] - widthSlice, pos[1] + dim[1] - heightSlice}, .{pos[0] + dim[0], pos[1] + dim[1]}, .{u[1], v[1]}, .{1, 1});
}

pub fn customShadedImage(uniforms: anytype, _pos: Vec2f, _dim: Vec2f) void {
var pos = _pos;
var dim = _dim;
Expand Down
23 changes: 6 additions & 17 deletions src/gui/components/Button.zig
Original file line number Diff line number Diff line change
Expand Up @@ -162,23 +162,12 @@ pub fn render(self: *Button, mousePosition: Vec2f) void {
self.hovered = false;
draw.customShadedRect(buttonUniforms, self.pos + Vec2f{2, 2}, self.size - Vec2f{4, 4});
}
{ // Draw the outline using the 9-slice texture.
const cornerSize = (textures.outlineTextureSize - Vec2f{1, 1});
const cornerSizeUV = (textures.outlineTextureSize - Vec2f{1, 1})/Vec2f{2, 2}/textures.outlineTextureSize;
const lowerTexture = (textures.outlineTextureSize - Vec2f{1, 1})/Vec2f{2, 2}/textures.outlineTextureSize;
const upperTexture = (textures.outlineTextureSize + Vec2f{1, 1})/Vec2f{2, 2}/textures.outlineTextureSize;
textures.outlineTexture.bindTo(0);
// Corners:
graphics.draw.boundSubImage(self.pos + Vec2f{0, 0}, cornerSize, .{0, 0}, cornerSizeUV);
graphics.draw.boundSubImage(self.pos + Vec2f{self.size[0], 0} - Vec2f{cornerSize[0], 0}, cornerSize, .{upperTexture[0], 0}, cornerSizeUV);
graphics.draw.boundSubImage(self.pos + Vec2f{0, self.size[1]} - Vec2f{0, cornerSize[1]}, cornerSize, .{0, upperTexture[1]}, cornerSizeUV);
graphics.draw.boundSubImage(self.pos + self.size - cornerSize, cornerSize, upperTexture, cornerSizeUV);
// Edges:
graphics.draw.boundSubImage(self.pos + Vec2f{cornerSize[0], 0}, Vec2f{self.size[0] - 2*cornerSize[0], cornerSize[1]}, .{lowerTexture[0], 0}, .{upperTexture[0] - lowerTexture[0], cornerSizeUV[1]});
graphics.draw.boundSubImage(self.pos + Vec2f{cornerSize[0], self.size[1] - cornerSize[1]}, Vec2f{self.size[0] - 2*cornerSize[0], cornerSize[1]}, .{lowerTexture[0], upperTexture[1]}, .{upperTexture[0] - lowerTexture[0], cornerSizeUV[1]});
graphics.draw.boundSubImage(self.pos + Vec2f{0, cornerSize[1]}, Vec2f{cornerSize[0], self.size[1] - 2*cornerSize[1]}, .{0, lowerTexture[1]}, .{cornerSizeUV[0], upperTexture[1] - lowerTexture[1]});
graphics.draw.boundSubImage(self.pos + Vec2f{self.size[0] - cornerSize[0], cornerSize[1]}, Vec2f{cornerSize[0], self.size[1] - 2*cornerSize[1]}, .{upperTexture[0], lowerTexture[1]}, .{cornerSizeUV[0], upperTexture[1] - lowerTexture[1]});
}

const cornerSize = (textures.outlineTextureSize - Vec2f{1, 1})/Vec2f{2, 2};

textures.outlineTexture.bindTo(0);
graphics.draw.bound9SliceImage(self.pos, self.size, textures.outlineTextureSize, cornerSize, 2);

const oldColor = draw.setColor(if (self.disabled) 0xff808080 else 0xffffffff);
defer draw.restoreColor(oldColor);
const textPos = self.pos + self.size/@as(Vec2f, @splat(2.0)) - self.child.size()/@as(Vec2f, @splat(2.0));
Expand Down
37 changes: 5 additions & 32 deletions src/gui/gui.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const gui_component = @import("gui_component.zig");
pub const GuiComponent = gui_component.GuiComponent;
pub const GuiWindow = @import("GuiWindow.zig");

pub const tooltip = @import("tooltip.zig");
pub const windowlist = @import("windows/_list.zig");
const gamepad_cursor = @import("gamepad_cursor.zig");

Expand Down Expand Up @@ -147,6 +148,7 @@ pub fn init() void { // MARK: init()
ContinuousSlider.globalInit();
DiscreteSlider.globalInit();
TextInput.globalInit();
tooltip.globalInit();
load();
gamepad_cursor.init();
}
Expand All @@ -167,6 +169,7 @@ pub fn deinit() void {
ContinuousSlider.globalDeinit();
DiscreteSlider.globalDeinit();
TextInput.globalDeinit();
tooltip.globalDeinit();
inline for (@typeInfo(windowlist).@"struct".decls) |decl| {
const WindowStruct = @field(windowlist, decl.name);
if (@hasDecl(WindowStruct, "deinit")) {
Expand Down Expand Up @@ -784,38 +787,8 @@ pub const inventory = struct { // MARK: inventory
// Draw tooltip:
const hovered = hoveredItemSlot orelse return;
if (carried.getAmount(0) == 0) {
if (hovered.inventory.getItem(hovered.itemSlot).getTooltip()) |tooltip| {
var textBuffer = graphics.TextBuffer.init(main.stackAllocator, tooltip, .{}, false, .left);
defer textBuffer.deinit();
const fontSize = 16;
var size = textBuffer.calculateLineBreaks(fontSize, 300);
size[0] = 0;
for (textBuffer.lineBreaks.items) |lineBreak| {
size[0] = @max(size[0], lineBreak.width);
}
const windowSize = main.Window.getWindowSize()/@as(Vec2f, @splat(scale));
const xOffset = 18;
const padding: f32 = 1;
const border: f32 = padding + 1;
var pos = mousePos;
if (pos[0] + size[0] + border + xOffset >= windowSize[0]) {
pos[0] -= size[0] + xOffset;
} else {
pos[0] += xOffset;
}
pos[1] = @min(pos[1] - fontSize, windowSize[1] - size[1] - border);
pos = @max(pos, Vec2f{border, border});
{
const oldColor = draw.setColor(0xffffff00);
defer draw.restoreColor(oldColor);
draw.rect(pos - @as(Vec2f, @splat(border)), size + @as(Vec2f, @splat(2*border)));
}
{
const oldColor = draw.setColor(0xff000000);
defer draw.restoreColor(oldColor);
draw.rect(pos - @as(Vec2f, @splat(padding)), size + @as(Vec2f, @splat(2*padding)));
}
textBuffer.render(pos[0], pos[1], fontSize);
if (hovered.inventory.getItem(hovered.itemSlot).getTooltip()) |tooltipContent| {
tooltip.renderFromText(tooltipContent, mousePos);
}
}
}
Expand Down
64 changes: 64 additions & 0 deletions src/gui/tooltip.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const std = @import("std");

const main = @import("main");
const graphics = main.graphics;
const draw = graphics.draw;
const Texture = graphics.Texture;
const vec = main.vec;
const Vec2f = vec.Vec2f;
const Vec4f = vec.Vec4f;
const gui = main.gui;
const GuiComponent = gui.GuiComponent;

var tooltipTexture: Texture = undefined;
var cornerSize: Vec2f = undefined;

const fontSize: f32 = 16;
const offsetFromMouse: f32 = 4;

pub fn globalInit() void {
tooltipTexture = Texture.initFromFile("assets/cubyz/ui/tooltip_background.png");
cornerSize = (@as(Vec2f, @floatFromInt(tooltipTexture.size())) - Vec2f{1, 1})/Vec2f{2, 2};
}

pub fn globalDeinit() void {
tooltipTexture.deinit();
}

pub fn render(guiComponent: *GuiComponent, pos: Vec2f) void {
const size = guiComponent.size() + Vec2f{cornerSize[0]*2, cornerSize[1]*2};
tooltipTexture.bindTo(0);

const windowSize = main.Window.getWindowSize()/@as(Vec2f, @splat(gui.scale));
var renderPos = pos + Vec2f{offsetFromMouse, 0};
if (renderPos[0] + size[0] > windowSize[0]) {
renderPos = pos - Vec2f{size[0] + cornerSize[0]*2, 0};
}
Comment thread
IntegratedQuantum marked this conversation as resolved.
renderPos = @max(Vec2f{0, 0}, renderPos);
if (renderPos[1] + size[1] > windowSize[1]) {
renderPos[1] += windowSize[1] - (renderPos[1] + size[1]);
}

draw.bound9SliceImage(renderPos, size, @floatFromInt(tooltipTexture.size()), cornerSize, 1);

const adjustment = renderPos - guiComponent.pos() + Vec2f{cornerSize[0], cornerSize[1]};
const oldTranslation = draw.setTranslation(adjustment);
defer draw.restoreTranslation(oldTranslation);
const oldClip = draw.setClip(guiComponent.size());
defer draw.restoreClip(oldClip);
guiComponent.render(guiComponent.pos());
}

pub fn renderFromText(text: []const u8, pos: Vec2f) void {
var label = GuiComponent.Label.init(Vec2f{0, 0}, 300, text, .left);
defer label.deinit();
var size = label.text.calculateLineBreaks(fontSize, 300);
size[0] = 0;
for (label.text.lineBreaks.items) |lineBreak| {
size[0] = @max(size[0], lineBreak.width);
}
label.size = size;

var component = label.toComponent();
render(&component, pos);
}
Loading