Canvas, Palettes, Bitmap updates
This commit is contained in:
@@ -36,10 +36,6 @@ void Canvas::UpdateColorPainter(const gfx::Bitmap &bitmap, const ImVec4 &color,
|
||||
ImVec2 bg_size, int tile_size, float scale,
|
||||
float grid_size) {
|
||||
global_scale_ = scale;
|
||||
if (scale != 1.0f) {
|
||||
bg_size.x *= scale / 2;
|
||||
bg_size.y *= scale / 2;
|
||||
}
|
||||
DrawBackground(bg_size);
|
||||
DrawContextMenu();
|
||||
DrawBitmap(bitmap, 2, scale);
|
||||
@@ -63,7 +59,8 @@ void Canvas::DrawBackground(ImVec2 canvas_size) {
|
||||
canvas_p0_ = ImGui::GetCursorScreenPos();
|
||||
if (!custom_canvas_size_) canvas_sz_ = ImGui::GetContentRegionAvail();
|
||||
if (canvas_size.x != 0) canvas_sz_ = canvas_size;
|
||||
canvas_p1_ = ImVec2(canvas_p0_.x + canvas_sz_.x, canvas_p0_.y + canvas_sz_.y);
|
||||
canvas_p1_ = ImVec2(canvas_p0_.x + (canvas_sz_.x * global_scale_),
|
||||
canvas_p0_.y + (canvas_sz_.y * global_scale_));
|
||||
draw_list_ = ImGui::GetWindowDrawList(); // Draw border and background color
|
||||
draw_list_->AddRectFilled(canvas_p0_, canvas_p1_, kRectangleColor);
|
||||
draw_list_->AddRect(canvas_p0_, canvas_p1_, kRectangleBorder);
|
||||
@@ -71,7 +68,9 @@ void Canvas::DrawBackground(ImVec2 canvas_size) {
|
||||
|
||||
void Canvas::DrawContextMenu() {
|
||||
const ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::InvisibleButton("canvas", canvas_sz_, kMouseFlags);
|
||||
auto scaled_sz =
|
||||
ImVec2(canvas_sz_.x * global_scale_, canvas_sz_.y * global_scale_);
|
||||
ImGui::InvisibleButton("canvas", scaled_sz, kMouseFlags);
|
||||
const bool is_active = ImGui::IsItemActive(); // Held
|
||||
const ImVec2 origin(canvas_p0_.x + scrolling_.x,
|
||||
canvas_p0_.y + scrolling_.y); // Lock scrolled origin
|
||||
@@ -94,6 +93,11 @@ void Canvas::DrawContextMenu() {
|
||||
if (ImGui::BeginPopup("context")) {
|
||||
ImGui::MenuItem("Show Grid", nullptr, &enable_grid_);
|
||||
ImGui::Selectable("Show Labels", &enable_hex_tile_labels_);
|
||||
if (ImGui::MenuItem("Reset Position", nullptr, false)) {
|
||||
scrolling_.x = 0;
|
||||
scrolling_.y = 0;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("8x8", nullptr, custom_step_ == 8.0f)) {
|
||||
custom_step_ = 8.0f;
|
||||
}
|
||||
@@ -106,10 +110,12 @@ void Canvas::DrawContextMenu() {
|
||||
if (ImGui::MenuItem("64x64", nullptr, custom_step_ == 64.0f)) {
|
||||
custom_step_ = 64.0f;
|
||||
}
|
||||
if (ImGui::MenuItem("Reset Position", nullptr, false)) {
|
||||
scrolling_.x = 0;
|
||||
scrolling_.y = 0;
|
||||
}
|
||||
// Display bitmap metadata such as canvas size and global scale
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Canvas Size: %.0f x %.0f", canvas_sz_.x, canvas_sz_.y);
|
||||
ImGui::Text("Global Scale: %.1f", global_scale_);
|
||||
ImGui::Text("Mouse Position: %.0f x %.0f", mouse_pos.x, mouse_pos.y);
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
@@ -149,6 +155,8 @@ bool Canvas::DrawTilePainter(const Bitmap &bitmap, int size, float scale) {
|
||||
// Draw the currently selected tile on the overworld here
|
||||
// Save the coordinates of the selected tile.
|
||||
drawn_tile_pos_ = io.MousePos;
|
||||
SDL_Log("Drawn tile position: %.0f, %.0f", drawn_tile_pos_.x,
|
||||
drawn_tile_pos_.y);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,13 +167,17 @@ bool Canvas::DrawTilePainter(const Bitmap &bitmap, int size, float scale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Canvas::DrawSolidTilePainter(const ImVec4 &color, int size) {
|
||||
bool Canvas::DrawSolidTilePainter(const ImVec4 &color, int tile_size) {
|
||||
const ImGuiIO &io = ImGui::GetIO();
|
||||
const bool is_hovered = ImGui::IsItemHovered();
|
||||
is_hovered_ = is_hovered;
|
||||
// Lock scrolled origin
|
||||
const ImVec2 origin(canvas_p0_.x + scrolling_.x, canvas_p0_.y + scrolling_.y);
|
||||
const ImVec2 mouse_pos(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
|
||||
auto scaled_tile_size = tile_size * global_scale_;
|
||||
|
||||
static bool is_dragging = false;
|
||||
static ImVec2 start_drag_pos;
|
||||
|
||||
if (is_hovered) {
|
||||
// Reset the previous tile hover
|
||||
@@ -175,25 +187,36 @@ bool Canvas::DrawSolidTilePainter(const ImVec4 &color, int size) {
|
||||
|
||||
// Calculate the coordinates of the mouse
|
||||
ImVec2 painter_pos;
|
||||
painter_pos.x = std::floor((double)mouse_pos.x / size) * size;
|
||||
painter_pos.y = std::floor((double)mouse_pos.y / size) * size;
|
||||
painter_pos.x =
|
||||
std::floor((double)mouse_pos.x / scaled_tile_size) * scaled_tile_size;
|
||||
painter_pos.y =
|
||||
std::floor((double)mouse_pos.y / scaled_tile_size) * scaled_tile_size;
|
||||
|
||||
// Clamp the size to a grid
|
||||
painter_pos.x = std::clamp(painter_pos.x, 0.0f, canvas_sz_.x);
|
||||
painter_pos.y = std::clamp(painter_pos.y, 0.0f, canvas_sz_.y);
|
||||
painter_pos.x =
|
||||
std::clamp(painter_pos.x, 0.0f, canvas_sz_.x * global_scale_);
|
||||
painter_pos.y =
|
||||
std::clamp(painter_pos.y, 0.0f, canvas_sz_.y * global_scale_);
|
||||
|
||||
auto painter_pos_end = ImVec2(painter_pos.x + size, painter_pos.y + size);
|
||||
auto painter_pos_end = ImVec2(painter_pos.x + scaled_tile_size,
|
||||
painter_pos.y + scaled_tile_size);
|
||||
points_.push_back(painter_pos);
|
||||
points_.push_back(painter_pos_end);
|
||||
|
||||
draw_list_->AddRectFilled(
|
||||
ImVec2(origin.x + painter_pos.x, origin.y + painter_pos.y),
|
||||
ImVec2(origin.x + painter_pos.x + size,
|
||||
origin.y + painter_pos.y + size),
|
||||
ImVec2(origin.x + painter_pos.x + 1, origin.y + painter_pos.y + 1),
|
||||
ImVec2(origin.x + painter_pos.x + scaled_tile_size,
|
||||
origin.y + painter_pos.y + scaled_tile_size),
|
||||
IM_COL32(color.x * 255, color.y * 255, color.z * 255, 255));
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
drawn_tile_pos_ = mouse_pos;
|
||||
is_dragging = true;
|
||||
start_drag_pos = painter_pos;
|
||||
}
|
||||
|
||||
if (is_dragging && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
is_dragging = false;
|
||||
drawn_tile_pos_ = start_drag_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -204,13 +227,12 @@ bool Canvas::DrawSolidTilePainter(const ImVec4 &color, int size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Canvas::DrawTileOnBitmap(const ImVec2 &position, int tile_size,
|
||||
gfx::Bitmap &bitmap, uint16_t color) {
|
||||
// Calculate the tile indices based on the click position
|
||||
int tile_index_x = static_cast<int>(position.x) / tile_size;
|
||||
int tile_index_y = static_cast<int>(position.y) / tile_size;
|
||||
void Canvas::DrawTileOnBitmap(int tile_size, gfx::Bitmap &bitmap,
|
||||
ImVec4 color) {
|
||||
const ImVec2 position = drawn_tile_pos_;
|
||||
int tile_index_x = static_cast<int>(position.x / global_scale_) / tile_size;
|
||||
int tile_index_y = static_cast<int>(position.y / global_scale_) / tile_size;
|
||||
|
||||
// Calculate the pixel start position based on tile index and tile size
|
||||
ImVec2 start_position(tile_index_x * tile_size, tile_index_y * tile_size);
|
||||
|
||||
// Update the bitmap's pixel data based on the start_position and color
|
||||
@@ -221,7 +243,7 @@ void Canvas::DrawTileOnBitmap(const ImVec2 &position, int tile_size,
|
||||
(start_position.y + y) * bitmap.width() + (start_position.x + x);
|
||||
|
||||
// Write the color to the pixel
|
||||
bitmap.WriteToPixel(pixel_index, color);
|
||||
bitmap.WriteColor(pixel_index, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,11 +321,11 @@ void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, bool ready) {
|
||||
}
|
||||
|
||||
void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, float scale) {
|
||||
draw_list_->AddImage(
|
||||
(void *)bitmap.texture(),
|
||||
ImVec2(canvas_p0_.x + border_offset, canvas_p0_.y + border_offset),
|
||||
ImVec2(canvas_p0_.x + (bitmap.width() * scale),
|
||||
canvas_p0_.y + (bitmap.height() * scale)));
|
||||
draw_list_->AddImage((void *)bitmap.texture(),
|
||||
ImVec2(canvas_p0_.x, canvas_p0_.y),
|
||||
ImVec2(canvas_p0_.x + (bitmap.width() * scale),
|
||||
canvas_p0_.y + (bitmap.height() * scale)));
|
||||
draw_list_->AddRect(canvas_p0_, canvas_p1_, kRectangleBorder);
|
||||
}
|
||||
|
||||
void Canvas::DrawBitmap(const Bitmap &bitmap, int x_offset, int y_offset,
|
||||
@@ -417,23 +439,23 @@ void Canvas::DrawGrid(float grid_step) {
|
||||
if (custom_step_ != 0.f) grid_step = custom_step_;
|
||||
|
||||
grid_step *= global_scale_; // Apply global scale to grid step
|
||||
for (float x = fmodf(scrolling_.x, grid_step); x < canvas_sz_.x;
|
||||
x += grid_step)
|
||||
for (float x = fmodf(scrolling_.x, grid_step);
|
||||
x < canvas_sz_.x * global_scale_; x += grid_step)
|
||||
draw_list_->AddLine(ImVec2(canvas_p0_.x + x, canvas_p0_.y),
|
||||
ImVec2(canvas_p0_.x + x, canvas_p1_.y),
|
||||
IM_COL32(200, 200, 200, 50), 0.5f);
|
||||
for (float y = fmodf(scrolling_.y, grid_step); y < canvas_sz_.y;
|
||||
y += grid_step)
|
||||
for (float y = fmodf(scrolling_.y, grid_step);
|
||||
y < canvas_sz_.y * global_scale_; y += grid_step)
|
||||
draw_list_->AddLine(ImVec2(canvas_p0_.x, canvas_p0_.y + y),
|
||||
ImVec2(canvas_p1_.x, canvas_p0_.y + y),
|
||||
IM_COL32(200, 200, 200, 50), 0.5f);
|
||||
|
||||
if (enable_hex_tile_labels_) {
|
||||
// Draw the hex ID of the tile in the center of the tile square
|
||||
for (float x = fmodf(scrolling_.x, grid_step); x < canvas_sz_.x;
|
||||
x += grid_step) {
|
||||
for (float y = fmodf(scrolling_.y, grid_step); y < canvas_sz_.y;
|
||||
y += grid_step) {
|
||||
for (float x = fmodf(scrolling_.x, grid_step);
|
||||
x < canvas_sz_.x * global_scale_; x += grid_step) {
|
||||
for (float y = fmodf(scrolling_.y, grid_step);
|
||||
y < canvas_sz_.y * global_scale_; y += grid_step) {
|
||||
int tile_x = (x - scrolling_.x) / grid_step;
|
||||
int tile_y = (y - scrolling_.y) / grid_step;
|
||||
int tile_id = tile_x + (tile_y * 16);
|
||||
|
||||
@@ -48,8 +48,7 @@ class Canvas {
|
||||
bool DrawSolidTilePainter(const ImVec4& color, int size);
|
||||
|
||||
// Draws a tile on the canvas at the specified position
|
||||
void DrawTileOnBitmap(const ImVec2& position, int tile_size,
|
||||
gfx::Bitmap& bitmap, uint16_t color);
|
||||
void DrawTileOnBitmap(int tile_size, gfx::Bitmap& bitmap, ImVec4 color);
|
||||
|
||||
// Dictates which tile is currently selected based on what the user clicks
|
||||
// in the canvas window. Represented and split apart into a grid of tiles.
|
||||
@@ -81,15 +80,17 @@ class Canvas {
|
||||
|
||||
auto Points() const { return points_; }
|
||||
auto GetDrawList() const { return draw_list_; }
|
||||
auto GetZeroPoint() const { return canvas_p0_; }
|
||||
auto zero_point() const { return canvas_p0_; }
|
||||
auto Scrolling() const { return scrolling_; }
|
||||
auto drawn_tile_position() const { return drawn_tile_pos_; }
|
||||
auto GetCanvasSize() const { return canvas_sz_; }
|
||||
auto canvas_size() const { return canvas_sz_; }
|
||||
void SetCanvasSize(ImVec2 canvas_size) {
|
||||
canvas_sz_ = canvas_size;
|
||||
custom_canvas_size_ = true;
|
||||
}
|
||||
auto IsMouseHovering() const { return is_hovered_; }
|
||||
void ZoomIn() { global_scale_ += 0.1f; }
|
||||
void ZoomOut() { global_scale_ -= 0.1f; }
|
||||
|
||||
void set_global_scale(float scale) { global_scale_ = scale; }
|
||||
auto global_scale() const { return global_scale_; }
|
||||
|
||||
@@ -23,18 +23,19 @@ namespace gui {
|
||||
|
||||
void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
|
||||
gfx::SNESPalette& palette) {
|
||||
const auto palette_row_size = 7;
|
||||
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)100);
|
||||
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
|
||||
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
ImGui::Text("Palette");
|
||||
for (int n = 0; n < palette.size(); n++) {
|
||||
|
||||
ImGui::PushID(n);
|
||||
if ((n % 7) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||||
if ((n % palette_row_size) != 0)
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||||
|
||||
// Check if the current row is selected
|
||||
bool is_selected = (palette_id == n / 7);
|
||||
bool is_selected = (palette_id == n / palette_row_size);
|
||||
|
||||
// Add outline rectangle to the selected row
|
||||
if (is_selected) {
|
||||
@@ -47,7 +48,7 @@ void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
|
||||
ImGuiColorEditFlags_NoPicker |
|
||||
ImGuiColorEditFlags_NoTooltip,
|
||||
ImVec2(20, 20))) {
|
||||
palette_id = n / 7;
|
||||
palette_id = n / palette_row_size;
|
||||
refresh_graphics = true;
|
||||
}
|
||||
|
||||
@@ -76,15 +77,15 @@ void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
|
||||
if (is_loaded) {
|
||||
for (const auto& [key, value] : graphics_bin) {
|
||||
int offset = height * (key + 1);
|
||||
int top_left_y = canvas.GetZeroPoint().y + 2;
|
||||
int top_left_y = canvas.zero_point().y + 2;
|
||||
if (key >= 1) {
|
||||
top_left_y = canvas.GetZeroPoint().y + height * key;
|
||||
top_left_y = canvas.zero_point().y + height * key;
|
||||
}
|
||||
canvas.GetDrawList()->AddImage(
|
||||
(void*)value.texture(),
|
||||
ImVec2(canvas.GetZeroPoint().x + 2, top_left_y),
|
||||
ImVec2(canvas.GetZeroPoint().x + 0x100,
|
||||
canvas.GetZeroPoint().y + offset));
|
||||
ImVec2(canvas.zero_point().x + 2, top_left_y),
|
||||
ImVec2(canvas.zero_point().x + 0x100,
|
||||
canvas.zero_point().y + offset));
|
||||
}
|
||||
}
|
||||
canvas.DrawTileSelector(tile_size);
|
||||
@@ -108,15 +109,15 @@ void GraphicsManagerCanvasPipeline(int width, int height, int tile_size,
|
||||
if (is_loaded) {
|
||||
for (const auto& [key, value] : graphics_manager) {
|
||||
int offset = height * (key + 1);
|
||||
int top_left_y = canvas.GetZeroPoint().y + 2;
|
||||
int top_left_y = canvas.zero_point().y + 2;
|
||||
if (key >= 1) {
|
||||
top_left_y = canvas.GetZeroPoint().y + height * key;
|
||||
top_left_y = canvas.zero_point().y + height * key;
|
||||
}
|
||||
canvas.GetDrawList()->AddImage(
|
||||
(void*)value->texture(),
|
||||
ImVec2(canvas.GetZeroPoint().x + 2, top_left_y),
|
||||
ImVec2(canvas.GetZeroPoint().x + 0x100,
|
||||
canvas.GetZeroPoint().y + offset));
|
||||
ImVec2(canvas.zero_point().x + 2, top_left_y),
|
||||
ImVec2(canvas.zero_point().x + 0x100,
|
||||
canvas.zero_point().y + offset));
|
||||
}
|
||||
}
|
||||
canvas.DrawTileSelector(tile_size);
|
||||
|
||||
Reference in New Issue
Block a user