diff options
Diffstat (limited to 'src/sheet/luaref.rs')
| -rw-r--r-- | src/sheet/luaref.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/sheet/luaref.rs b/src/sheet/luaref.rs new file mode 100644 index 0000000..fa4b8f9 --- /dev/null +++ b/src/sheet/luaref.rs @@ -0,0 +1,82 @@ +use crate::state::GlobalState; + +use super::{ + foreach::LuaForEach, + register::{Register, SheetId}, +}; +use mlua::prelude::*; + +pub struct SheetLuaRef { + id: SheetId, +} + +impl SheetLuaRef { + pub fn new(id: SheetId) -> Self { + Self { id } + } + + pub fn id(&self) -> SheetId { + self.id + } +} + +impl LuaUserData for SheetLuaRef { + fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("width", |_, luaref| { + Ok(Register::get(luaref.id).unwrap().read().unwrap().width()) + }); + + fields.add_field_method_get("height", |_, luaref| { + Ok(Register::get(luaref.id).unwrap().read().unwrap().height()) + }); + } + + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_method_mut("cell", |lua, luaref, (row, column): (usize, usize)| { + if let Some(rw) = Register::get(luaref.id) { + let sheet = rw.read().unwrap(); + Ok(sheet.get_ref(row, column).into_lua(lua).unwrap()) + } else { + Ok(LuaValue::Nil) + } + }); + + methods.add_method_mut("foreach", |_, luaref, func: LuaFunction| { + let range: Vec<_> = { + let state = GlobalState::instance(); + let lock = state.sheetview.active_sheet().unwrap(); + let sheet = lock.read().unwrap(); + + if sheet.id() != luaref.id() { + return Ok(()); + } + + let (width, height) = (sheet.width(), sheet.height()); + + if state.sheetview.selection_anchor.is_some() { + state.sheetview.selection() + } else { + let mut cells = Vec::new(); + for row in 0..height { + for column in 0..width { + cells.push((row, column)); + } + } + cells + } + }; + + Register::get(luaref.id).unwrap().lua_foreach(func, range) + }) + } +} + +impl<'lua> FromLua<'lua> for SheetLuaRef { + fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { + if let Some(ud) = value.as_userdata() { + ud.take() + } else { + Err(LuaError::runtime("failed to parse sheet")) + } + } +} |