Skip to content

Commit

Permalink
start implementing the graphic picker
Browse files Browse the repository at this point in the history
  • Loading branch information
melody-rs committed Jun 25, 2024
1 parent 6067f2d commit cbfba0e
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 29 deletions.
3 changes: 2 additions & 1 deletion crates/components/src/map_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,11 +456,12 @@ impl MapView {
&update_state.graphics,
glam::vec2(event_size.x, event_size.y),
);
let graphic = &event.pages[0].graphic; // FIXME handle missing first page (should never happen though...)
let sprite = luminol_graphics::Event::new_standalone(
&update_state.graphics,
update_state.filesystem,
&viewport,
event,
graphic,
&self.map.atlas,
)
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions crates/components/src/tilepicker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl Tilepicker {
&update_state.graphics,
tileset,
update_state.filesystem,
false,
)?;

let mut brush_seed = [0u8; 16];
Expand Down
8 changes: 8 additions & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ pub use project_manager::ProjectManager;
pub use alox_48;
pub use data_cache::format_traced_error;

pub mod prelude {
pub use crate::{Modal, Tab, UpdateState, Window};
pub use luminol_audio::Source;
pub use luminol_data::rpg;
pub use luminol_filesystem::FileSystem;
pub use luminol_graphics::*;
}

static GIT_REVISION: once_cell::sync::OnceCell<&'static str> = once_cell::sync::OnceCell::new();

pub fn set_git_revision(revision: &'static str) {
Expand Down
22 changes: 9 additions & 13 deletions crates/graphics/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,11 @@ impl Event {
graphics_state: &GraphicsState,
filesystem: &impl luminol_filesystem::FileSystem,
viewport: &Viewport,
event: &luminol_data::rpg::Event,
graphic: &luminol_data::rpg::Graphic,
atlas: &Atlas,
) -> color_eyre::Result<Option<Self>> {
let Some(page) = event.pages.first() else {
color_eyre::eyre::bail!("event does not have first page");
};

let mut is_placeholder = false;
let texture = if let Some(ref filename) = page.graphic.character_name {
let texture = if let Some(ref filename) = graphic.character_name {
let texture = graphics_state
.texture_loader
.load_now_dir(filesystem, "Graphics/Characters", filename)
Expand All @@ -137,13 +133,13 @@ impl Event {
graphics_state.texture_loader.placeholder_texture()
}
}
} else if page.graphic.tile_id.is_some() {
} else if graphic.tile_id.is_some() {
atlas.atlas_texture.clone()
} else {
return Ok(None);
};

let (quad, sprite_size) = if let Some(id) = page.graphic.tile_id {
let (quad, sprite_size) = if let Some(id) = graphic.tile_id {
// Why does this have to be + 1?
let quad = atlas.calc_quad((id + 1) as i16);

Expand All @@ -167,8 +163,8 @@ impl Event {
// Reduced by 0.01 px on all sides to reduce texture bleeding
let tex_coords = egui::Rect::from_min_size(
egui::pos2(
page.graphic.pattern as f32 * cw + 0.01,
(page.graphic.direction as f32 - 2.) / 2. * ch + 0.01,
graphic.pattern as f32 * cw + 0.01,
(graphic.direction as f32 - 2.) / 2. * ch + 0.01,
),
egui::vec2(cw - 0.02, ch - 0.02),
);
Expand All @@ -182,9 +178,9 @@ impl Event {
let sprite = Sprite::new(
graphics_state,
quad,
page.graphic.character_hue,
page.graphic.opacity,
page.graphic.blend_type,
graphic.character_hue,
graphic.opacity,
graphic.blend_type,
&texture,
viewport,
transform,
Expand Down
13 changes: 9 additions & 4 deletions crates/graphics/src/tilepicker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,20 @@ impl Tilepicker {
graphics_state: &GraphicsState,
tileset: &luminol_data::rpg::Tileset,
filesystem: &impl luminol_filesystem::FileSystem,
exclude_autotiles: bool,
) -> color_eyre::Result<Self> {
let atlas = graphics_state
.atlas_loader
.load_atlas(graphics_state, filesystem, tileset)?;

let tilepicker_data = (47..(384 + 47))
.step_by(48)
.chain(384..(atlas.tileset_height as i16 / 32 * 8 + 384))
.collect_vec();
let tilepicker_data = if exclude_autotiles {
(384..(atlas.tileset_height as i16 / 32 * 8 + 384)).collect_vec()
} else {
(47..(384 + 47))
.step_by(48)
.chain(384..(atlas.tileset_height as i16 / 32 * 8 + 384))
.collect_vec()
};
let tilepicker_data = luminol_data::Table3::new_data(
8,
1 + (atlas.tileset_height / 32) as usize,
Expand Down
139 changes: 139 additions & 0 deletions crates/modals/src/event_graphic_picker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright (C) 2024 Lily Lyons
//
// This file is part of Luminol.
//
// Luminol is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Luminol is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Luminol. If not, see <http://www.gnu.org/licenses/>.
//
// Additional permission under GNU GPL version 3 section 7
//
// If you modify this Program, or any covered work, by linking or combining
// it with Steamworks API by Valve Corporation, containing parts covered by
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.

use luminol_core::prelude::*;

pub struct Modal {
entries: Vec<camino::Utf8PathBuf>,
open: bool,
id_source: egui::Id,

tilepicker: Tilepicker,

button_viewport: Viewport,
button_sprite: Option<Event>,

sprite: Option<(Viewport, Event)>,
}

impl Modal {
pub fn new(
update_state: &UpdateState<'_>,
graphic: &rpg::Graphic,
tileset: &rpg::Tileset,
id_source: egui::Id,
) -> Self {
// TODO error handling
let entries = update_state
.filesystem
.read_dir("Graphics/Characters")
.unwrap()
.into_iter()
.map(|m| {
m.path
.strip_prefix("Graphics/Characters")
.unwrap_or(&m.path)
.with_extension("")
})
.collect();

let tilepicker = Tilepicker::new(
&update_state.graphics,
tileset,
update_state.filesystem,
false,
)
.unwrap();

let button_viewport = Viewport::new(&update_state.graphics, Default::default());
let button_sprite = Event::new_standalone(
&update_state.graphics,
update_state.filesystem,
&button_viewport,
graphic,
&tilepicker.atlas,
)
.unwrap();

Self {
entries,
open: false,
id_source,

tilepicker,

button_viewport,
button_sprite,

sprite: None,
}
}
}

impl luminol_core::Modal for Modal {
type Data = luminol_data::rpg::Graphic;

fn button<'m>(
&'m mut self,
data: &'m mut Self::Data,
update_state: &'m mut UpdateState<'_>,
) -> impl egui::Widget + 'm {
move |ui: &mut egui::Ui| {
let button_text = match data {
rpg::Graphic {
character_name: Some(name),
..
} => name.to_string(),
rpg::Graphic {
tile_id: Some(id), ..
} => format!("Tile {id}"),
_ => "None".to_string(),
};

let button_response = ui.button(button_text);
if button_response.clicked() {
self.open = true;
}
self.show_window(update_state, ui.ctx(), data);

button_response
}
}

fn reset(&mut self) {
self.open = false;
}
}

impl Modal {
pub fn update_graphic(&mut self, update_state: &UpdateState<'_>, graphic: &rpg::Graphic) {}

fn show_window(
&mut self,
update_state: &luminol_core::UpdateState<'_>,
ctx: &egui::Context,
data: &mut rpg::Graphic,
) {
}
}
2 changes: 2 additions & 0 deletions crates/modals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ pub mod sound_picker;
pub mod graphic_picker;

pub mod database_modal;

pub mod event_graphic_picker;
10 changes: 7 additions & 3 deletions crates/ui/src/tabs/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,12 @@ impl luminol_core::Tab for Tab {
// Double-click/press enter on events to edit them
if ui.input(|i| !i.modifiers.command) {
let event = map.events[selected_event_id].clone();
self.event_windows
.add_window(event_edit::Window::new(event, self.id));
self.event_windows.add_window(event_edit::Window::new(
update_state,
event,
self.id,
tileset,
));
}
}

Expand Down Expand Up @@ -551,7 +555,7 @@ impl luminol_core::Tab for Tab {
if response.double_clicked()
|| (is_focused && ui.input(|i| i.key_pressed(egui::Key::Enter)))
{
if let Some(id) = self.add_event(&mut map) {
if let Some(id) = self.add_event(update_state, &mut map, tileset) {
self.push_to_history(
update_state,
&mut map,
Expand Down
14 changes: 12 additions & 2 deletions crates/ui/src/tabs/map/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,12 @@ impl super::Tab {
}
}

pub(super) fn add_event(&mut self, map: &mut luminol_data::rpg::Map) -> Option<usize> {
pub(super) fn add_event(
&mut self,
update_state: &luminol_core::UpdateState<'_>,
map: &mut luminol_data::rpg::Map,
tileset: &luminol_data::rpg::Tileset,
) -> Option<usize> {
let mut first_vacant_id = 1;
let mut max_event_id = 0;

Expand Down Expand Up @@ -235,7 +240,12 @@ impl super::Tab {
map.events.insert(new_event_id, event.clone());

self.event_windows
.add_window(crate::windows::event_edit::Window::new(event, self.id));
.add_window(crate::windows::event_edit::Window::new(
update_state,
event,
map.tileset_id,
tileset,
));
Some(new_event_id)
}

Expand Down
Loading

0 comments on commit cbfba0e

Please sign in to comment.