add panels
This commit is contained in:
+108
-1
@@ -12,8 +12,10 @@ use std::cell::{Cell, RefCell};
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::constants::{BOTTOM_PANEL_HEIGHT, LEFT_PANEL_WIDTH, RIGHT_PANEL_WIDTH};
|
||||
use crate::editor::{Language, Workspace};
|
||||
use crate::keymap::{KeyBinding, KeyMap};
|
||||
use crate::panel::{PanelHandle, PanelState};
|
||||
|
||||
thread_local! {
|
||||
/// Текущий экземпляр API. `thread_local`, потому что UI GPUI привязан к
|
||||
@@ -78,6 +80,57 @@ pub struct AppApi {
|
||||
workspace: Rc<RefCell<Workspace>>,
|
||||
#[lua(skip)]
|
||||
keymap: Rc<RefCell<KeyMap>>,
|
||||
#[lua(skip)]
|
||||
left_panel: PanelHandle,
|
||||
#[lua(skip)]
|
||||
right_panel: PanelHandle,
|
||||
#[lua(skip)]
|
||||
bottom_panel: PanelHandle,
|
||||
}
|
||||
|
||||
/// API одной панели окна.
|
||||
///
|
||||
/// Один и тот же тип используется для `app.left_panel`, `app.right_panel` и
|
||||
/// `app.bottom_panel`: отличается только состояние, на которое ссылается
|
||||
/// объект. Поэтому панели управляются одинаково: `app.left_panel:open()`,
|
||||
/// `app.bottom_panel:toggle()` и так далее.
|
||||
#[derive(mlua::UserData)]
|
||||
pub struct PanelApi {
|
||||
#[lua(skip)]
|
||||
state: PanelHandle,
|
||||
}
|
||||
|
||||
impl PanelApi {
|
||||
fn new(state: PanelHandle) -> Self {
|
||||
Self { state }
|
||||
}
|
||||
}
|
||||
|
||||
#[mlua::userdata_impl]
|
||||
impl PanelApi {
|
||||
/// Открывает панель.
|
||||
#[lua(infallible)]
|
||||
pub fn open(&self) {
|
||||
self.state.borrow_mut().open();
|
||||
}
|
||||
|
||||
/// Закрывает панель.
|
||||
#[lua(infallible)]
|
||||
pub fn close(&self) {
|
||||
self.state.borrow_mut().close();
|
||||
}
|
||||
|
||||
/// Переключает панель и возвращает новое состояние.
|
||||
#[lua(infallible)]
|
||||
pub fn toggle(&self) -> bool {
|
||||
self.state.borrow_mut().toggle()
|
||||
}
|
||||
|
||||
/// Открыта ли панель прямо сейчас.
|
||||
#[lua(infallible)]
|
||||
pub fn is_open(&self) -> bool {
|
||||
self.state.borrow().is_open()
|
||||
}
|
||||
}
|
||||
|
||||
#[mlua::userdata_impl]
|
||||
@@ -86,7 +139,13 @@ impl AppApi {
|
||||
/// [`AppApi::global`].
|
||||
#[lua(skip)]
|
||||
pub fn install(workspace: Rc<RefCell<Workspace>>, keymap: Rc<RefCell<KeyMap>>) -> Self {
|
||||
let api = Self { workspace, keymap };
|
||||
let api = Self {
|
||||
workspace,
|
||||
keymap,
|
||||
left_panel: Rc::new(RefCell::new(PanelState::new(LEFT_PANEL_WIDTH))),
|
||||
right_panel: Rc::new(RefCell::new(PanelState::new(RIGHT_PANEL_WIDTH))),
|
||||
bottom_panel: Rc::new(RefCell::new(PanelState::new(BOTTOM_PANEL_HEIGHT))),
|
||||
};
|
||||
INSTANCE.with(|slot| *slot.borrow_mut() = Some(api.clone()));
|
||||
api
|
||||
}
|
||||
@@ -104,6 +163,24 @@ impl AppApi {
|
||||
})
|
||||
}
|
||||
|
||||
/// Состояние левой панели (для вида).
|
||||
#[lua(skip)]
|
||||
pub fn left_panel_handle(&self) -> PanelHandle {
|
||||
self.left_panel.clone()
|
||||
}
|
||||
|
||||
/// Состояние правой панели (для вида).
|
||||
#[lua(skip)]
|
||||
pub fn right_panel_handle(&self) -> PanelHandle {
|
||||
self.right_panel.clone()
|
||||
}
|
||||
|
||||
/// Состояние нижней панели (для вида).
|
||||
#[lua(skip)]
|
||||
pub fn bottom_panel_handle(&self) -> PanelHandle {
|
||||
self.bottom_panel.clone()
|
||||
}
|
||||
|
||||
/// Все открытые вкладки в порядке слева направо.
|
||||
#[allow(dead_code)]
|
||||
// Часть публичного API приложения: вызывается внешним кодом и тестами.
|
||||
@@ -287,6 +364,36 @@ impl AppApi {
|
||||
self.workspace.borrow_mut().clear_language(index)
|
||||
}
|
||||
|
||||
/// Левая панель окна.
|
||||
///
|
||||
/// В Lua доступна как `app.left_panel` с методами `open`, `close`,
|
||||
/// `toggle` и `is_open`.
|
||||
#[allow(dead_code)]
|
||||
#[lua(getter, infallible)]
|
||||
pub fn left_panel(&self) -> PanelApi {
|
||||
PanelApi::new(self.left_panel.clone())
|
||||
}
|
||||
|
||||
/// Правая панель окна.
|
||||
///
|
||||
/// В Lua доступна как `app.right_panel` с методами `open`, `close`,
|
||||
/// `toggle` и `is_open`.
|
||||
#[allow(dead_code)]
|
||||
#[lua(getter, infallible)]
|
||||
pub fn right_panel(&self) -> PanelApi {
|
||||
PanelApi::new(self.right_panel.clone())
|
||||
}
|
||||
|
||||
/// Нижняя панель окна.
|
||||
///
|
||||
/// В Lua доступна как `app.bottom_panel` с теми же методами, что и
|
||||
/// `app.right_panel`.
|
||||
#[allow(dead_code)]
|
||||
#[lua(getter, infallible)]
|
||||
pub fn bottom_panel(&self) -> PanelApi {
|
||||
PanelApi::new(self.bottom_panel.clone())
|
||||
}
|
||||
|
||||
/// Закрывает окно приложения.
|
||||
#[lua(infallible)]
|
||||
pub fn close(&self) {
|
||||
|
||||
Reference in New Issue
Block a user