setttings in editor tab

This commit is contained in:
Dongdong Zhou 2022-05-24 09:22:29 +01:00
parent 1cca869a0c
commit 3bcbae1894
10 changed files with 513 additions and 499 deletions

View File

@ -1015,10 +1015,9 @@ pub fn run_workbench_command(
}
LapceWorkbenchCommand::OpenLogFile => {
if let Some(path) = Config::log_file() {
let editor_view_id = self.main_split.active.clone();
self.main_split.jump_to_location(
ctx,
*editor_view_id,
None,
EditorLocationNew {
path,
position: None,
@ -1030,20 +1029,20 @@ pub fn run_workbench_command(
}
}
LapceWorkbenchCommand::OpenSettings => {
let settings = Arc::make_mut(&mut self.settings);
settings.shown = true;
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ShowSettings,
Target::Widget(self.settings.panel_widget_id),
));
self.main_split.open_settings(ctx);
// let settings = Arc::make_mut(&mut self.settings);
// settings.shown = true;
// ctx.submit_command(Command::new(
// LAPCE_UI_COMMAND,
// LapceUICommand::ShowSettings,
// Target::Widget(self.settings.panel_widget_id),
// ));
}
LapceWorkbenchCommand::OpenSettingsFile => {
if let Some(path) = Config::settings_file() {
let editor_view_id = self.main_split.active.clone();
self.main_split.jump_to_location(
ctx,
*editor_view_id,
None,
EditorLocationNew {
path,
position: None,
@ -1055,8 +1054,6 @@ pub fn run_workbench_command(
}
}
LapceWorkbenchCommand::OpenKeyboardShortcuts => {
let settings = Arc::make_mut(&mut self.settings);
settings.shown = true;
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ShowKeybindings,
@ -1065,10 +1062,9 @@ pub fn run_workbench_command(
}
LapceWorkbenchCommand::OpenKeyboardShortcutsFile => {
if let Some(path) = KeyPressData::file() {
let editor_view_id = self.main_split.active.clone();
self.main_split.jump_to_location(
ctx,
*editor_view_id,
None,
EditorLocationNew {
path,
position: None,
@ -1176,7 +1172,7 @@ pub fn run_workbench_command(
}
}
LapceWorkbenchCommand::FocusEditor => {
if let Some(active) = *self.main_split.active {
if let Some(active) = *self.main_split.active_tab {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
@ -1443,7 +1439,7 @@ fn hide_panel(&mut self, ctx: &mut EventCtx, kind: PanelKind) {
break;
}
}
if let Some(active) = *self.main_split.active {
if let Some(active) = *self.main_split.active_tab {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
@ -1977,6 +1973,170 @@ pub fn get_active_tab_mut(
)
}
fn new_editor_tab(
&mut self,
ctx: &mut EventCtx,
split_id: WidgetId,
) -> WidgetId {
let split = self.splits.get_mut(&split_id).unwrap();
let split = Arc::make_mut(split);
let editor_tab_id = WidgetId::next();
let editor_tab = LapceEditorTabData {
widget_id: editor_tab_id,
split: *self.split_id,
active: 0,
children: vec![],
layout_rect: Rc::new(RefCell::new(Rect::ZERO)),
content_is_hot: Rc::new(RefCell::new(false)),
};
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::SplitAdd(
0,
SplitContent::EditorTab(editor_tab.widget_id),
true,
),
Target::Widget(*self.split_id),
));
self.active_tab = Arc::new(Some(editor_tab.widget_id));
split
.children
.push(SplitContent::EditorTab(editor_tab.widget_id));
self.editor_tabs.insert(editor_tab_id, Arc::new(editor_tab));
editor_tab_id
}
fn editor_tab_new_settings(
&mut self,
ctx: &mut EventCtx,
editor_tab_id: WidgetId,
) {
let editor_tab = self.editor_tabs.get_mut(&editor_tab_id).unwrap();
let editor_tab = Arc::make_mut(editor_tab);
let child = EditorTabChild::Settings(WidgetId::next(), editor_tab_id);
editor_tab.children.push(child.clone());
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(0, child),
Target::Widget(editor_tab.widget_id),
));
}
fn editor_tab_new_editor(
&mut self,
ctx: &mut EventCtx,
editor_tab_id: WidgetId,
config: &Config,
) -> WidgetId {
let editor_tab = self.editor_tabs.get_mut(&editor_tab_id).unwrap();
let editor_tab = Arc::make_mut(editor_tab);
let editor = Arc::new(LapceEditorData::new(
None,
None,
Some(editor_tab.widget_id),
BufferContent::Local(LocalBufferKind::Empty),
config,
));
editor_tab.children.push(EditorTabChild::Editor(
editor.view_id,
editor.editor_id,
editor.find_view_id,
));
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(
0,
EditorTabChild::Editor(
editor.view_id,
editor.editor_id,
editor.find_view_id,
),
),
Target::Widget(editor_tab.widget_id),
));
self.insert_editor(editor.clone(), config);
editor.view_id
}
fn get_editor_from_tab(
&mut self,
ctx: &mut EventCtx,
editor_tab_id: WidgetId,
path: Option<PathBuf>,
_scratch: bool,
config: &Config,
) -> &mut LapceEditorData {
let editor_tab =
Arc::make_mut(self.editor_tabs.get_mut(&editor_tab_id).unwrap());
if !config.editor.show_tab {
if let EditorTabChild::Editor(id, _, _) = editor_tab.active_child() {
return Arc::make_mut(self.editors.get_mut(id).unwrap());
}
}
let mut editor_size = Size::ZERO;
for (i, child) in editor_tab.children.iter().enumerate() {
if let EditorTabChild::Editor(id, _, _) = child {
let editor = self.editors.get(id).unwrap();
let current_size = *editor.size.borrow();
if current_size.height > 0.0 {
editor_size = current_size;
}
if let Some(path) = path.as_ref() {
if editor.content == BufferContent::File(path.clone()) {
editor_tab.active = i;
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
Target::Widget(*id),
));
return Arc::make_mut(self.editors.get_mut(id).unwrap());
}
}
}
}
let new_editor = Arc::new(LapceEditorData::new(
None,
None,
Some(editor_tab.widget_id),
BufferContent::Local(LocalBufferKind::Empty),
config,
));
*new_editor.size.borrow_mut() = editor_size;
editor_tab.children.insert(
editor_tab.active + 1,
EditorTabChild::Editor(
new_editor.view_id,
new_editor.editor_id,
new_editor.find_view_id,
),
);
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(
editor_tab.active + 1,
EditorTabChild::Editor(
new_editor.view_id,
new_editor.editor_id,
new_editor.find_view_id,
),
),
Target::Widget(editor_tab.widget_id),
));
editor_tab.active += 1;
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
Target::Widget(new_editor.view_id),
));
self.insert_editor(new_editor.clone(), config);
return Arc::make_mut(self.editors.get_mut(&new_editor.view_id).unwrap());
}
fn get_editor_or_new(
&mut self,
ctx: &mut EventCtx,
@ -1989,159 +2149,13 @@ fn get_editor_or_new(
Some(view_id) => Arc::make_mut(self.editors.get_mut(&view_id).unwrap()),
None => match *self.active_tab {
Some(active) => {
let editor_tab =
Arc::make_mut(self.editor_tabs.get_mut(&active).unwrap());
match &editor_tab.children[editor_tab.active] {
EditorTabChild::Editor(id, _, _) => {
if config.editor.show_tab {
if path.is_some() || scratch {
let mut editor_size = Size::ZERO;
for (i, child) in
editor_tab.children.iter().enumerate()
{
match child {
EditorTabChild::Editor(id, _, _) => {
let editor =
self.editors.get(id).unwrap();
let current_size =
*editor.size.borrow();
if current_size.height > 0.0 {
editor_size = current_size;
}
if let Some(path) = path.as_ref() {
if editor.content
== BufferContent::File(
path.clone(),
)
{
editor_tab.active = i;
ctx.submit_command(
Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
Target::Widget(*id),
),
);
return Arc::make_mut(
self.editors
.get_mut(id)
.unwrap(),
);
}
}
}
}
}
let new_editor = Arc::new(LapceEditorData::new(
None,
None,
Some(editor_tab.widget_id),
BufferContent::Local(LocalBufferKind::Empty),
config,
));
*new_editor.size.borrow_mut() = editor_size;
editor_tab.children.insert(
editor_tab.active + 1,
EditorTabChild::Editor(
new_editor.view_id,
new_editor.editor_id,
new_editor.find_view_id,
),
);
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(
editor_tab.active + 1,
EditorTabChild::Editor(
new_editor.view_id,
new_editor.editor_id,
new_editor.find_view_id,
),
),
Target::Widget(editor_tab.widget_id),
));
editor_tab.active += 1;
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
Target::Widget(new_editor.view_id),
));
self.insert_editor(new_editor.clone(), config);
return Arc::make_mut(
self.editors
.get_mut(&new_editor.view_id)
.unwrap(),
);
}
Arc::make_mut(self.editors.get_mut(id).unwrap())
} else {
Arc::make_mut(self.editors.get_mut(id).unwrap())
}
}
}
self.get_editor_from_tab(ctx, active, path, scratch, config)
}
None => {
let split = self.splits.get_mut(&self.split_id).unwrap();
let split = Arc::make_mut(split);
let mut editor_tab = LapceEditorTabData {
widget_id: WidgetId::next(),
split: *self.split_id,
active: 0,
children: vec![],
layout_rect: Rc::new(RefCell::new(Rect::ZERO)),
content_is_hot: Rc::new(RefCell::new(false)),
};
let editor = Arc::new(LapceEditorData::new(
None,
None,
Some(editor_tab.widget_id),
BufferContent::Local(LocalBufferKind::Empty),
config,
));
editor_tab.children.push(EditorTabChild::Editor(
editor.view_id,
editor.editor_id,
editor.find_view_id,
));
self.active = Arc::new(Some(editor.view_id));
self.active_tab = Arc::new(Some(editor_tab.widget_id));
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(
0,
EditorTabChild::Editor(
editor.view_id,
editor.editor_id,
editor.find_view_id,
),
),
Target::Widget(editor_tab.widget_id),
));
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::SplitAdd(
0,
SplitContent::EditorTab(editor_tab.widget_id),
true,
),
Target::Widget(*self.split_id),
));
split
.children
.push(SplitContent::EditorTab(editor_tab.widget_id));
self.insert_editor(editor.clone(), config);
self.editor_tabs
.insert(editor_tab.widget_id, Arc::new(editor_tab));
Arc::make_mut(self.editors.get_mut(&editor.view_id).unwrap())
let editor_tab_id = self.new_editor_tab(ctx, *self.split_id);
let view_id =
self.editor_tab_new_editor(ctx, editor_tab_id, config);
Arc::make_mut(self.editors.get_mut(&view_id).unwrap())
}
},
}
@ -2167,6 +2181,37 @@ pub fn jump_to_position(
}
}
pub fn open_settings(&mut self, ctx: &mut EventCtx) {
match *self.active_tab {
Some(active) => {
let editor_tab =
Arc::make_mut(self.editor_tabs.get_mut(&active).unwrap());
for (i, child) in editor_tab.children.iter().enumerate() {
if let EditorTabChild::Settings(_, _) = child {
editor_tab.active = i;
return;
}
}
let child =
EditorTabChild::Settings(WidgetId::next(), editor_tab.widget_id);
editor_tab
.children
.insert(editor_tab.active + 1, child.clone());
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabAdd(editor_tab.active + 1, child),
Target::Widget(editor_tab.widget_id),
));
editor_tab.active += 1;
}
None => {
let editor_tab_id = self.new_editor_tab(ctx, *self.split_id);
self.editor_tab_new_settings(ctx, editor_tab_id);
}
}
}
pub fn jump_to_location(
&mut self,
ctx: &mut EventCtx,
@ -2611,6 +2656,26 @@ pub fn save_as(
}
}
pub fn settings_close(
&mut self,
ctx: &mut EventCtx,
widget_id: WidgetId,
editor_tab_id: WidgetId,
) {
let editor_tab = self.editor_tabs.get(&editor_tab_id).unwrap();
let mut index = 0;
for (i, child) in editor_tab.children.iter().enumerate() {
if child.widget_id() == widget_id {
index = i;
}
}
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::EditorTabRemove(index, true, true),
Target::Widget(editor_tab_id),
));
}
pub fn editor_close(
&mut self,
ctx: &mut EventCtx,
@ -2852,6 +2917,48 @@ pub fn split_move(
}
}
pub fn split_settings(
&mut self,
ctx: &mut EventCtx,
editor_tab_id: WidgetId,
direction: SplitDirection,
) {
let editor_tab = self.editor_tabs.get(&editor_tab_id).unwrap();
let split_id = editor_tab.split;
let new_editor_tab_id = WidgetId::next();
let mut new_editor_tab = LapceEditorTabData {
widget_id: new_editor_tab_id,
split: split_id,
active: 0,
children: vec![EditorTabChild::Settings(
WidgetId::next(),
new_editor_tab_id,
)],
layout_rect: Rc::new(RefCell::new(Rect::ZERO)),
content_is_hot: Rc::new(RefCell::new(false)),
};
let new_split_id = self.split(
ctx,
split_id,
SplitContent::EditorTab(editor_tab_id),
SplitContent::EditorTab(new_editor_tab.widget_id),
direction,
false,
false,
);
new_editor_tab.split = new_split_id;
if split_id != new_split_id {
let editor_tab = self.editor_tabs.get_mut(&editor_tab_id).unwrap();
let editor_tab = Arc::make_mut(editor_tab);
editor_tab.split = new_split_id;
}
self.editor_tabs
.insert(new_editor_tab.widget_id, Arc::new(new_editor_tab));
}
pub fn split_editor(
&mut self,
ctx: &mut EventCtx,
@ -2916,14 +3023,14 @@ pub enum InlineFindDirection {
#[derive(Clone, Debug, PartialEq)]
pub enum EditorTabChild {
Editor(WidgetId, WidgetId, Option<(WidgetId, WidgetId)>),
// Settings(WidgetId),
Settings(WidgetId, WidgetId),
}
impl EditorTabChild {
pub fn widget_id(&self) -> WidgetId {
match &self {
EditorTabChild::Editor(widget_id, _, _) => *widget_id,
// EditorTabChild::Settings(_) => todo!(),
EditorTabChild::Settings(widget_id, _) => *widget_id,
}
}
@ -2932,17 +3039,25 @@ pub fn child_info(&self, data: &LapceTabData) -> EditorTabChildInfo {
EditorTabChild::Editor(view_id, _, _) => {
let editor_data = data.main_split.editors.get(view_id).unwrap();
EditorTabChildInfo::Editor(editor_data.editor_info(data))
} // EditorTabChild::Settings(_) => todo!(),
}
EditorTabChild::Settings(_, _) => EditorTabChildInfo::Settings,
}
}
pub fn set_editor_tab(&self, data: &mut LapceTabData, editor_tab_id: WidgetId) {
match &self {
pub fn set_editor_tab(
&mut self,
data: &mut LapceTabData,
editor_tab_id: WidgetId,
) {
match self {
EditorTabChild::Editor(view_id, _, _) => {
let editor_data = data.main_split.editors.get_mut(view_id).unwrap();
let editor_data = Arc::make_mut(editor_data);
editor_data.tab_id = Some(editor_tab_id);
} // EditorTabChild::Settings(_) => todo!(),
}
EditorTabChild::Settings(_, current_editor_tab_id) => {
*current_editor_tab_id = editor_tab_id;
}
}
}
}
@ -2970,6 +3085,10 @@ pub fn tab_info(&self, data: &LapceTabData) -> EditorTabInfo {
};
info
}
pub fn active_child(&self) -> &EditorTabChild {
&self.children[self.active]
}
}
#[derive(Clone, Debug)]

View File

@ -135,6 +135,7 @@ pub fn to_data(
#[derive(Clone, Serialize, Deserialize)]
pub enum EditorTabChildInfo {
Editor(EditorInfo),
Settings,
}
impl EditorTabChildInfo {
@ -163,6 +164,9 @@ pub fn to_data(
editor_data.find_view_id,
)
}
EditorTabChildInfo::Settings => {
EditorTabChild::Settings(WidgetId::next(), editor_tab_id)
}
}
}
}

View File

@ -447,7 +447,7 @@ pub fn cancel(&mut self, ctx: &mut EventCtx) {
palette.palette_type = PaletteType::File;
palette.items.clear();
palette.filtered_items.clear();
if let Some(active) = *self.main_split.active {
if let Some(active) = *self.main_split.active_tab {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,

View File

@ -6,7 +6,9 @@
use crate::{
command::{CommandExecuted, CommandKind, LapceUICommand, LAPCE_UI_COMMAND},
data::LapceMainSplitData,
keypress::KeyPressFocus,
split::SplitDirection,
};
pub enum LapceSettingsKind {
@ -16,7 +18,6 @@ pub enum LapceSettingsKind {
#[derive(Clone)]
pub struct LapceSettingsPanelData {
pub shown: bool,
pub panel_widget_id: WidgetId,
pub keymap_widget_id: WidgetId,
@ -67,7 +68,6 @@ fn run_command(
impl LapceSettingsPanelData {
pub fn new() -> Self {
Self {
shown: false,
panel_widget_id: WidgetId::next(),
keymap_widget_id: WidgetId::next(),
keymap_view_id: WidgetId::next(),
@ -85,6 +85,56 @@ fn default() -> Self {
}
}
#[derive(Clone)]
pub struct LapceSettingsFocusData {
pub widget_id: WidgetId,
pub editor_tab_id: WidgetId,
pub main_split: LapceMainSplitData,
}
impl KeyPressFocus for LapceSettingsFocusData {
fn get_mode(&self) -> Mode {
Mode::Insert
}
fn check_condition(&self, _condition: &str) -> bool {
false
}
fn run_command(
&mut self,
ctx: &mut EventCtx,
command: &crate::command::LapceCommand,
_count: Option<usize>,
_mods: Modifiers,
_env: &Env,
) -> CommandExecuted {
match &command.kind {
CommandKind::Focus(cmd) => match cmd {
FocusCommand::SplitVertical => {
self.main_split.split_settings(
ctx,
self.editor_tab_id,
SplitDirection::Vertical,
);
}
FocusCommand::SplitClose => {
self.main_split.settings_close(
ctx,
self.widget_id,
self.editor_tab_id,
);
}
_ => return CommandExecuted::No,
},
_ => return CommandExecuted::No,
}
CommandExecuted::Yes
}
fn receive_char(&mut self, _ctx: &mut EventCtx, _c: &str) {}
}
pub enum SettingsValue {
Bool(bool),
}

View File

@ -56,6 +56,7 @@ fn clear_child(&mut self, ctx: &mut EventCtx, data: &mut LapceTabData) {
EditorTabChild::Editor(view_id, _, _) => {
data.main_split.editors.remove(view_id);
}
EditorTabChild::Settings(_, _) => {}
}
}
ctx.submit_command(Command::new(
@ -124,6 +125,7 @@ pub fn remove_child(
EditorTabChild::Editor(view_id, _, _) => {
data.main_split.editors.remove(&view_id);
}
EditorTabChild::Settings(_, _) => {}
}
}
}
@ -193,6 +195,7 @@ fn mouse_up(
layout_rect: Rc::new(RefCell::new(Rect::ZERO)),
content_is_hot: Rc::new(RefCell::new(false)),
};
let mut child = child.clone();
child.set_editor_tab(data, new_editor_tab.widget_id);
let new_split_id = data.main_split.split(
@ -240,6 +243,7 @@ fn mouse_up(
if from_id == &self.widget_id {
return;
}
let mut child = child.clone();
child.set_editor_tab(data, self.widget_id);
let editor_tab = data
.main_split
@ -307,7 +311,7 @@ fn event(
LapceUICommand::EditorTabAdd(index, content) => {
self.children.insert(
*index,
WidgetPod::new(editor_tab_child_widget(content)),
WidgetPod::new(editor_tab_child_widget(content, data)),
);
ctx.children_changed();
return;
@ -354,29 +358,33 @@ fn event(
data.main_split.editor_tabs.get(&self.widget_id)
{
let active = &tab.children[tab.active];
let EditorTabChildInfo::Editor(info) =
active.child_info(data);
if info.content
== BufferContent::Local(LocalBufferKind::Empty)
{
// File has not yet been loaded, most likely.
return;
}
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ActiveFileChanged {
path: if let BufferContent::File(path) =
info.content
match active.child_info(data) {
EditorTabChildInfo::Editor(info) => {
if info.content
== BufferContent::Local(
LocalBufferKind::Empty,
)
{
Some(path)
} else {
None
},
},
Target::Widget(data.file_explorer.widget_id),
));
// File has not yet been loaded, most likely.
return;
}
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ActiveFileChanged {
path: if let BufferContent::File(path) =
info.content
{
Some(path)
} else {
None
},
},
Target::Widget(data.file_explorer.widget_id),
));
}
EditorTabChildInfo::Settings => {}
}
return;
}
}
@ -601,6 +609,7 @@ fn paint(
let doc = data.main_split.editor_doc(*editor_id);
doc.buffer().is_pristine()
}
EditorTabChild::Settings(_, _) => true,
};
if !is_pristine {

View File

@ -218,6 +218,7 @@ fn handle_drag(
return;
}
let mut child = child.clone();
child.set_editor_tab(data, editor_tab.widget_id);
let editor_tab = data
.main_split
@ -363,6 +364,9 @@ fn layout(
text = editor.content.file_name().to_string();
}
}
EditorTabChild::Settings(_, _) => {
text = "Settings".to_string();
}
}
let text_layout = ctx
.text()

View File

@ -26,6 +26,7 @@
container::LapceEditorContainer, header::LapceEditorHeader, LapceEditor,
},
find::FindBox,
settings::LapceSettingsPanel,
};
pub struct LapceEditorView {
@ -37,11 +38,15 @@ pub struct LapceEditorView {
pub fn editor_tab_child_widget(
child: &EditorTabChild,
data: &LapceTabData,
) -> Box<dyn Widget<LapceTabData>> {
match child {
EditorTabChild::Editor(view_id, editor_id, find_view_id) => {
LapceEditorView::new(*view_id, *editor_id, *find_view_id).boxed()
}
EditorTabChild::Settings(widget_id, editor_tab_id) => {
LapceSettingsPanel::new(data, *widget_id, *editor_tab_id).boxed()
}
}
}

View File

@ -7,8 +7,8 @@
},
BoxConstraints, Command, Env, Event, EventCtx, ExtEventSink, FontWeight,
LayoutCtx, LifeCycle, LifeCycleCtx, Modifiers, MouseEvent, PaintCtx, Point,
Rect, RenderContext, Size, Target, TimerToken, UpdateCtx, Vec2, Widget,
WidgetExt, WidgetId, WidgetPod,
Rect, RenderContext, Size, Target, TimerToken, UpdateCtx, Widget, WidgetExt,
WidgetId, WidgetPod,
};
use inflector::Inflector;
use lapce_core::{
@ -24,7 +24,7 @@
data::{LapceEditorData, LapceTabData},
document::{BufferContent, Document},
keypress::KeyPressFocus,
proxy::VERSION,
settings::LapceSettingsFocusData,
};
use xi_rope::Rope;
@ -33,7 +33,6 @@
keymap::LapceKeymap,
scroll::{LapcePadding, LapceScrollNew},
split::LapceSplitNew,
svg::get_svg,
};
enum LapceSettingsKind {
@ -43,54 +42,22 @@ enum LapceSettingsKind {
Terminal,
}
#[derive(Clone)]
pub struct LapceSettingsPanelData {
pub shown: bool,
pub panel_widget_id: WidgetId,
pub keymap_widget_id: WidgetId,
pub keymap_view_id: WidgetId,
pub keymap_split_id: WidgetId,
pub settings_widget_id: WidgetId,
pub settings_view_id: WidgetId,
pub settings_split_id: WidgetId,
}
impl LapceSettingsPanelData {
pub fn new() -> Self {
Self {
shown: false,
panel_widget_id: WidgetId::next(),
keymap_widget_id: WidgetId::next(),
keymap_view_id: WidgetId::next(),
keymap_split_id: WidgetId::next(),
settings_widget_id: WidgetId::next(),
settings_view_id: WidgetId::next(),
settings_split_id: WidgetId::next(),
}
}
}
impl Default for LapceSettingsPanelData {
fn default() -> Self {
Self::new()
}
}
pub struct LapceSettingsPanel {
widget_id: WidgetId,
editor_tab_id: WidgetId,
active: usize,
content_rect: Rect,
header_rect: Rect,
switcher_rect: Rect,
switcher_line_height: f64,
close_rect: Rect,
children: Vec<WidgetPod<LapceTabData, LapceSplitNew>>,
}
impl LapceSettingsPanel {
pub fn new(data: &LapceTabData) -> Self {
pub fn new(
data: &LapceTabData,
widget_id: WidgetId,
editor_tab_id: WidgetId,
) -> Self {
let children = vec![
WidgetPod::new(LapceSettings::new_split(LapceSettingsKind::Core, data)),
WidgetPod::new(LapceSettings::new_split(LapceSettingsKind::UI, data)),
@ -105,11 +72,10 @@ pub fn new(data: &LapceTabData) -> Self {
WidgetPod::new(LapceKeymap::new_split(data)),
];
Self {
widget_id: data.settings.panel_widget_id,
widget_id,
editor_tab_id,
active: 0,
header_rect: Rect::ZERO,
content_rect: Rect::ZERO,
close_rect: Rect::ZERO,
switcher_rect: Rect::ZERO,
switcher_line_height: 40.0,
children,
@ -120,15 +86,8 @@ fn mouse_down(
&mut self,
ctx: &mut EventCtx,
mouse_event: &MouseEvent,
data: &mut LapceTabData,
_data: &mut LapceTabData,
) {
if self.icon_hit_test(mouse_event) || !self.panel_hit_test(mouse_event) {
let settings = Arc::make_mut(&mut data.settings);
settings.shown = false;
ctx.clear_cursor();
return;
}
ctx.set_handled();
ctx.request_focus();
if self.switcher_rect.contains(mouse_event.pos) {
@ -141,14 +100,6 @@ fn mouse_down(
}
}
}
fn icon_hit_test(&self, mouse_event: &MouseEvent) -> bool {
self.close_rect.contains(mouse_event.pos)
}
fn panel_hit_test(&self, mouse_event: &MouseEvent) -> bool {
self.content_rect.contains(mouse_event.pos)
}
}
impl Widget<LapceTabData> for LapceSettingsPanel {
@ -163,43 +114,29 @@ fn event(
data: &mut LapceTabData,
env: &Env,
) {
if !data.settings.shown && !event.should_propagate_to_hidden() {
return;
}
match event {
Event::Command(cmd) if cmd.is(LAPCE_UI_COMMAND) => {}
Event::Command(cmd) if cmd.is(LAPCE_COMMAND) => {}
_ => {
self.children[self.active].event(ctx, event, data, env);
}
}
self.children[self.active].event(ctx, event, data, env);
if ctx.is_handled() {
return;
}
match event {
Event::KeyDown(key_event) => {
let mut keypress = data.keypress.clone();
let mut focus = LapceSettingsFocusData {
widget_id: self.widget_id,
editor_tab_id: self.editor_tab_id,
main_split: data.main_split.clone(),
};
let mut_keypress = Arc::make_mut(&mut keypress);
let performed_action = mut_keypress.key_down(
ctx,
key_event,
Arc::make_mut(&mut data.settings),
env,
);
let performed_action =
mut_keypress.key_down(ctx, key_event, &mut focus, env);
data.keypress = keypress;
data.main_split = focus.main_split;
if performed_action {
ctx.set_handled();
}
}
Event::MouseMove(mouse_event) => {
Event::MouseMove(_mouse_event) => {
ctx.set_handled();
if self.icon_hit_test(mouse_event) {
ctx.set_cursor(&druid::Cursor::Pointer);
ctx.request_paint();
} else {
ctx.clear_cursor();
ctx.request_paint();
}
}
Event::MouseDown(mouse_event) => {
self.mouse_down(ctx, mouse_event, data);
@ -207,6 +144,17 @@ fn event(
Event::MouseUp(_mouse_event) => {
ctx.set_handled();
}
Event::Command(cmd) if cmd.is(LAPCE_COMMAND) => {
let cmd = cmd.get_unchecked(LAPCE_COMMAND);
let mut focus = LapceSettingsFocusData {
widget_id: self.widget_id,
editor_tab_id: self.editor_tab_id,
main_split: data.main_split.clone(),
};
focus.run_command(ctx, cmd, None, Modifiers::empty(), env);
data.main_split = focus.main_split;
println!("run cmd {cmd:?}");
}
Event::Command(cmd) if cmd.is(LAPCE_UI_COMMAND) => {
let command = cmd.get_unchecked(LAPCE_UI_COMMAND);
match command {
@ -219,7 +167,6 @@ fn event(
self.active = 4;
}
LapceUICommand::Hide => {
Arc::make_mut(&mut data.settings).shown = false;
if let Some(active) = *data.main_split.active {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
@ -242,9 +189,6 @@ fn lifecycle(
data: &LapceTabData,
env: &Env,
) {
if !data.settings.shown && !event.should_propagate_to_hidden() {
return;
}
for child in self.children.iter_mut() {
child.lifecycle(ctx, event, data, env);
}
@ -257,8 +201,8 @@ fn update(
data: &LapceTabData,
env: &Env,
) {
if data.settings.shown {
self.children[self.active].update(ctx, data, env);
for child in self.children.iter_mut() {
child.update(ctx, data, env);
}
}
@ -269,136 +213,61 @@ fn layout(
data: &LapceTabData,
env: &Env,
) -> Size {
let tab_size = bc.max();
let self_size = Size::new(
(tab_size.width * 0.8).min(900.0),
(tab_size.height * 0.8).min(700.0),
);
let origin = Point::new(
tab_size.width / 2.0 - self_size.width / 2.0,
(tab_size.height / 2.0 - self_size.height / 2.0) / 2.0,
)
.round();
let self_size = bc.max();
let origin = Point::ZERO;
self.content_rect = self_size.to_rect().with_origin(origin).round();
self.header_rect = Size::new(self_size.width, 50.0)
.to_rect()
.with_origin(origin)
.round();
let close_size = 26.0;
self.close_rect = Size::new(close_size, close_size)
self.switcher_rect = Size::new(150.0, self_size.height)
.to_rect()
.with_origin(
origin
+ (
self.header_rect.width()
- (self.header_rect.height() / 2.0 - close_size / 2.0)
- close_size,
self.header_rect.height() / 2.0 - close_size / 2.0,
),
)
.with_origin(Point::ZERO)
.round();
self.switcher_rect =
Size::new(150.0, self_size.height - self.header_rect.height())
.to_rect()
.with_origin(origin + (0.0, self.header_rect.height()))
.round();
let content_size = Size::new(
self_size.width - self.switcher_rect.width() - 40.0,
self_size.height - self.header_rect.height(),
self_size.width - self.switcher_rect.width() - 20.0,
self_size.height,
);
let content_origin = origin
+ (
self_size.width - content_size.width - 20.0,
self_size.height - content_size.height,
);
let content_origin = Point::new(self.switcher_rect.width() + 20.0, 0.0);
let content_bc = BoxConstraints::tight(content_size);
let child = &mut self.children[self.active];
child.layout(ctx, &content_bc, data, env);
child.set_origin(ctx, data, env, content_origin);
tab_size
self_size
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) {
if data.settings.shown {
let rect = ctx.size().to_rect();
ctx.fill(
rect,
&data
.config
.get_color_unchecked(LapceTheme::LAPCE_DROPDOWN_SHADOW)
.clone()
.with_alpha(0.5),
);
ctx.fill(
self.content_rect,
data.config
.get_color_unchecked(LapceTheme::PANEL_BACKGROUND),
);
ctx.fill(
self.content_rect,
data.config
.get_color_unchecked(LapceTheme::EDITOR_BACKGROUND),
);
ctx.fill(
Size::new(self.switcher_rect.width(), self.switcher_line_height)
.to_rect()
.with_origin(
self.switcher_rect.origin()
+ (0.0, self.active as f64 * self.switcher_line_height),
),
data.config
.get_color_unchecked(LapceTheme::EDITOR_BACKGROUND),
);
const SETTINGS_SECTIONS: [&str; 5] = [
"Core Settings",
"UI Settings",
"Editor Settings",
"Terminal Settings",
"Keybindings",
];
for (i, text) in SETTINGS_SECTIONS.into_iter().enumerate() {
let text_layout = ctx
.text()
.new_text_layout(text)
.font(
data.config.ui.font_family(),
(data.config.ui.font_size() + 1) as f64,
)
.text_color(
data.config
.get_color_unchecked(LapceTheme::EDITOR_FOREGROUND)
.clone(),
)
.build()
.unwrap();
let text_size = text_layout.size();
ctx.draw_text(
&text_layout,
ctx.fill(
Size::new(self.switcher_rect.width(), self.switcher_line_height)
.to_rect()
.with_origin(
self.switcher_rect.origin()
+ (
20.0,
i as f64 * self.switcher_line_height
+ (self.switcher_line_height / 2.0
- text_size.height / 2.0),
),
);
}
+ (0.0, self.active as f64 * self.switcher_line_height),
),
data.config
.get_color_unchecked(LapceTheme::EDITOR_CURRENT_LINE),
);
const SETTINGS_SECTIONS: [&str; 5] = [
"Core Settings",
"UI Settings",
"Editor Settings",
"Terminal Settings",
"Keybindings",
];
for (i, text) in SETTINGS_SECTIONS.into_iter().enumerate() {
let text_layout = ctx
.text()
.new_text_layout(format!("Settings v{VERSION}"))
.new_text_layout(text)
.font(
data.config.ui.font_family(),
((data.config.ui.font_size() as f64) * 1.2).round(),
)
.range_attribute(
9..9 + VERSION.len() + 1,
TextAttribute::FontSize(
((data.config.ui.font_size() as f64) * 0.8).round(),
),
(data.config.ui.font_size() + 1) as f64,
)
.text_color(
data.config
@ -408,84 +277,28 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) {
.build()
.unwrap();
let text_size = text_layout.size();
let x = self.header_rect.height() / 2.0 - text_size.height / 2.0;
let y = self.header_rect.height() / 2.0 - text_size.height / 2.0;
ctx.draw_text(&text_layout, self.header_rect.origin() + (x, y));
let svg = get_svg("close.svg").unwrap();
let icon_padding = 4.0;
ctx.draw_svg(
&svg,
self.close_rect.inflate(-icon_padding, -icon_padding),
Some(
data.config
.get_color_unchecked(LapceTheme::EDITOR_FOREGROUND),
),
ctx.draw_text(
&text_layout,
self.switcher_rect.origin()
+ (
20.0,
i as f64 * self.switcher_line_height
+ (self.switcher_line_height / 2.0
- text_size.height / 2.0),
),
);
self.children[self.active].paint(ctx, data, env);
let shadow_width = 5.0;
if data.config.ui.drop_shadow() {
ctx.blurred_rect(
self.content_rect,
shadow_width,
data.config
.get_color_unchecked(LapceTheme::LAPCE_DROPDOWN_SHADOW),
);
}
if data.config.ui.drop_shadow() {
ctx.with_save(|ctx| {
ctx.clip(
self.switcher_rect.inflate(50.0, 0.0) + Vec2::new(50.0, 0.0),
);
ctx.blurred_rect(
self.switcher_rect,
shadow_width,
data.config
.get_color_unchecked(LapceTheme::LAPCE_DROPDOWN_SHADOW),
);
});
} else {
ctx.stroke(
Line::new(
Point::new(
self.switcher_rect.x1 + 0.5,
self.switcher_rect.y0,
),
Point::new(
self.switcher_rect.x1 + 0.5,
self.switcher_rect.y1,
),
),
data.config.get_color_unchecked(LapceTheme::LAPCE_BORDER),
1.0,
);
}
if data.config.ui.drop_shadow() {
ctx.with_save(|ctx| {
ctx.clip(
self.header_rect.inflate(0.0, 50.0) + Vec2::new(0.0, 50.0),
);
ctx.blurred_rect(
self.header_rect,
shadow_width,
data.config
.get_color_unchecked(LapceTheme::LAPCE_DROPDOWN_SHADOW),
);
});
} else {
ctx.stroke(
Line::new(
Point::new(self.header_rect.x0, self.header_rect.y1 - 0.5),
Point::new(self.header_rect.x1, self.header_rect.y1 - 0.5),
),
data.config.get_color_unchecked(LapceTheme::LAPCE_BORDER),
1.0,
);
}
}
self.children[self.active].paint(ctx, data, env);
ctx.stroke(
Line::new(
Point::new(self.switcher_rect.x1 + 0.5, self.switcher_rect.y0),
Point::new(self.switcher_rect.x1 + 0.5, self.switcher_rect.y1),
),
data.config.get_color_unchecked(LapceTheme::LAPCE_BORDER),
1.0,
);
}
}
@ -513,7 +326,7 @@ pub fn new_split(kind: LapceSettingsKind, data: &LapceTabData) -> LapceSplitNew
)
.hide_header()
.hide_gutter()
.padding((15.0, 15.0));
.padding((15.0, 15.0, 0.0, 15.0));
let split = LapceSplitNew::new(data.settings.settings_split_id)
.horizontal()
@ -789,7 +602,8 @@ pub fn name(
.clone(),
)
.default_attribute(TextAttribute::Weight(FontWeight::BOLD))
.max_width(self.width)
.max_width(self.width - 30.0)
.set_line_height(1.5)
.build()
.unwrap();
self.name_text = Some(text_layout);
@ -820,7 +634,8 @@ pub fn desc(
.get_color_unchecked(LapceTheme::EDITOR_FOREGROUND)
.clone(),
)
.max_width(max_width)
.max_width(max_width - 30.0)
.set_line_height(1.5)
.build()
.unwrap();
self.desc_text = Some(text_layout);
@ -867,6 +682,12 @@ pub fn value(
fn get_key(&self) -> String {
format!("{}.{}", self.kind, self.name.to_kebab_case())
}
fn clear_text_layout_cache(&mut self) {
self.name_text = None;
self.desc_text = None;
self.value_text = None;
}
}
impl KeyPressFocus for LapceSettingsItemKeypress {
@ -977,7 +798,8 @@ fn event(
.with_origin(Point::new(
0.0,
self.name(ctx.text(), data).size().height
+ self.padding * 2.0,
+ self.padding * 2.0
+ 4.0,
));
if rect.contains(mouse_event.pos) {
self.value = serde_json::json!(!checked);
@ -1049,9 +871,7 @@ fn update(
_env: &Env,
) {
if data.config.id != old_data.config.id {
self.name_text = None;
self.desc_text = None;
self.value_text = None;
self.clear_text_layout_cache();
}
if let Some(view_id) = self.input_view_id.as_ref() {
let editor = data.main_split.editors.get(view_id).unwrap();
@ -1093,7 +913,11 @@ fn layout(
data: &LapceTabData,
env: &Env,
) -> Size {
self.width = bc.max().width;
let width = bc.max().width;
if width != self.width {
self.width = width;
self.clear_text_layout_cache();
}
let text = ctx.text();
let name = self.name(text, data).size();
let desc = self.desc(text, data).size();
@ -1142,7 +966,7 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceTabData, env: &Env) {
let x = if let serde_json::Value::Bool(checked) = self.value {
let width = 13.0;
let height = 13.0;
let origin = Point::new(0.0, y);
let origin = Point::new(0.0, y + 4.0);
let rect = Size::new(width, height).to_rect().with_origin(origin);
ctx.stroke(
rect,

View File

@ -1,5 +1,6 @@
use crate::{
editor::{tab::LapceEditorTab, view::LapceEditorView},
settings::LapceSettingsPanel,
terminal::LapceTerminalView,
};
use std::sync::Arc;
@ -68,6 +69,15 @@ pub fn split_content_widget(
.boxed();
editor_tab = editor_tab.with_child(editor);
}
EditorTabChild::Settings(widget_id, editor_tab_id) => {
let settings = LapceSettingsPanel::new(
data,
*widget_id,
*editor_tab_id,
)
.boxed();
editor_tab = editor_tab.with_child(settings);
}
}
}
editor_tab.boxed()
@ -528,7 +538,7 @@ pub fn split_terminal_close(
Arc::make_mut(panel).shown = false;
}
}
if let Some(active) = *data.main_split.active {
if let Some(active) = *data.main_split.active_tab {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,

View File

@ -118,7 +118,8 @@ pub fn new(data: &LapceTabData) -> Self {
let picker = FilePicker::new(data);
let settings = LapceSettingsPanel::new(data);
let settings =
LapceSettingsPanel::new(data, WidgetId::next(), WidgetId::next());
let alert = AlertBox::new(data);
@ -1027,7 +1028,7 @@ fn handle_event(
ctx.set_handled();
}
LapceUICommand::FocusEditor => {
if let Some(active) = *data.main_split.active {
if let Some(active) = *data.main_split.active_tab {
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::Focus,
@ -1119,9 +1120,6 @@ fn event(
if data.alert.active || event.should_propagate_to_hidden() {
self.alert.event(ctx, event, data, env);
}
if data.settings.shown || event.should_propagate_to_hidden() {
self.settings.event(ctx, event, data, env);
}
if data.picker.active || event.should_propagate_to_hidden() {
self.picker.event(ctx, event, data, env);
}
@ -1247,10 +1245,6 @@ fn update(
ctx.request_layout();
}
if old_data.settings.shown != data.settings.shown {
ctx.request_layout();
}
if old_data.picker.active != data.picker.active {
ctx.request_layout();
}
@ -1555,11 +1549,6 @@ fn layout(
);
}
if data.settings.shown {
self.settings.layout(ctx, bc, data, env);
self.settings.set_origin(ctx, data, env, Point::ZERO);
}
if data.alert.active {
self.alert.layout(ctx, bc, data, env);
self.alert.set_origin(ctx, data, env, Point::ZERO);