forked from 1b-agent/opencadstudio-upstream
options: fonts and plot styles can live in a chosen folder
Options > Files lets the fonts and plot style folders move elsewhere, such as a share a whole team uses (Change... / Default). Fonts are then looked up and downloaded there, and plot style tables listed and saved there; the choice is kept in the profile. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
e9a2b9d196
commit
686fb71780
8 files changed
+147
-15
No files matched your search
@@ -2694,6 +2694,11 @@ pub enum Message {
|
||||
SelectionCyclingChanged(bool),
|
||||
/// Reveal one of the application's own folders in the system file manager.
|
||||
OpenFolder(String),
|
||||
/// Choose another folder for fonts or plot styles (`None` result:
|
||||
/// cancelled).
|
||||
ChooseFolder(crate::ui::window::options::MovableFolder),
|
||||
/// Use this folder, or the default one for `None`.
|
||||
FolderChosen(crate::ui::window::options::MovableFolder, Option<std::path::PathBuf>),
|
||||
/// Change isolines per surface in the current drawing (ISOLINES).
|
||||
IsolinesChanged(i16),
|
||||
/// The isolines slider was released; rebuild the meshes if it moved.
|
||||
|
||||
@@ -443,6 +443,9 @@ pub struct UserSettings {
|
||||
pub file_dia: bool,
|
||||
/// TRIMEXTENDMODE: TRIM and EXTEND start in Quick mode (else Standard).
|
||||
pub trim_extend_quick: bool,
|
||||
/// Fonts and plot styles kept in a chosen folder (`None`: the default).
|
||||
pub fonts_folder: Option<String>,
|
||||
pub plot_styles_folder: Option<String>,
|
||||
/// The file type ATTACH's picker was last left on (1-based).
|
||||
pub attach_filter: u32,
|
||||
/// SURFACEASSOCIATIVITY: new surfaces stay associative to their sources.
|
||||
@@ -918,6 +921,8 @@ impl Default for UserSettings {
|
||||
xref_fade: 50,
|
||||
file_dia: true,
|
||||
trim_extend_quick: true,
|
||||
fonts_folder: None,
|
||||
plot_styles_folder: None,
|
||||
attach_filter: 7,
|
||||
surface_associativity: true,
|
||||
ucs_ortho: true,
|
||||
|
||||
@@ -811,6 +811,15 @@ impl OpenCADStudio {
|
||||
xref_fade: crate::scene::cache::block_cache::xref_fade_ctl(),
|
||||
file_dia: crate::sys::file_dia(),
|
||||
trim_extend_quick: crate::modules::draw::modify::trim::quick_mode(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fonts_folder: crate::io::font_repo::fonts_folder().map(|p| p.display().to_string()),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
plot_styles_folder: crate::io::plot_style::plot_styles_folder()
|
||||
.map(|p| p.display().to_string()),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fonts_folder: None,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
plot_styles_folder: None,
|
||||
attach_filter: crate::sys::attach_filter(),
|
||||
surface_associativity: crate::scene::model::sweep_model::surface_associativity(),
|
||||
ucs_ortho: crate::modules::view::view_cmd::ucs_ortho(),
|
||||
@@ -948,6 +957,13 @@ impl OpenCADStudio {
|
||||
self.ribbon.xref_fade = crate::scene::cache::block_cache::xref_fade_ctl();
|
||||
crate::sys::set_file_dia(s.file_dia);
|
||||
crate::modules::draw::modify::trim::set_quick_mode(s.trim_extend_quick);
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
crate::io::font_repo::set_fonts_folder(s.fonts_folder.as_ref().map(Into::into));
|
||||
crate::io::plot_style::set_plot_styles_folder(
|
||||
s.plot_styles_folder.as_ref().map(Into::into),
|
||||
);
|
||||
}
|
||||
crate::sys::set_attach_filter(s.attach_filter);
|
||||
crate::scene::model::sweep_model::set_surface_associativity(s.surface_associativity);
|
||||
crate::modules::view::view_cmd::set_ucs_ortho(s.ucs_ortho);
|
||||
|
||||
@@ -9369,6 +9369,34 @@ impl OpenCADStudio {
|
||||
crate::sys::open_url(&path, None)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Message::ChooseFolder(_) | Message::FolderChosen(..) => Task::none(),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Message::ChooseFolder(folder) => Task::perform(
|
||||
async {
|
||||
rfd::AsyncFileDialog::new()
|
||||
.pick_folder()
|
||||
.await
|
||||
.map(|handle| crate::sys::handle_path(&handle))
|
||||
},
|
||||
move |picked| match picked {
|
||||
Some(path) => Message::FolderChosen(folder, Some(path)),
|
||||
None => Message::Noop,
|
||||
},
|
||||
),
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
Message::FolderChosen(folder, path) => {
|
||||
use crate::ui::window::options::MovableFolder;
|
||||
match folder {
|
||||
MovableFolder::Fonts => crate::io::font_repo::set_fonts_folder(path),
|
||||
MovableFolder::PlotStyles => {
|
||||
crate::io::plot_style::set_plot_styles_folder(path)
|
||||
}
|
||||
}
|
||||
self.save_config();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PickDragRectToggled(rectangle) => {
|
||||
self.pick_drag_rect = rectangle;
|
||||
self.persist_settings_if_changed();
|
||||
|
||||
@@ -375,6 +375,9 @@ impl OpenCADStudio {
|
||||
.map(|p| p.display().to_string()),
|
||||
color_books: crate::ui::color_select::book::folder()
|
||||
.map(|p| p.display().to_string()),
|
||||
fonts_moved: crate::io::font_repo::fonts_folder().is_some(),
|
||||
plot_styles_moved: crate::io::plot_style::plot_styles_folder()
|
||||
.is_some(),
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
||||
+16
-1
@@ -18,11 +18,26 @@ const REPO_API_URL: &str = "https://api.github.com/repos/HakanSeven12/OpenCADStu
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
const MAX_FONT_BYTES: u64 = 16 * 1024 * 1024;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
static FONTS_FOLDER: std::sync::RwLock<Option<PathBuf>> = std::sync::RwLock::new(None);
|
||||
|
||||
/// A folder chosen in Options to hold the fonts instead of the default one,
|
||||
/// such as a share on the office network.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn fonts_folder() -> Option<PathBuf> {
|
||||
FONTS_FOLDER.read().unwrap_or_else(|e| e.into_inner()).clone()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn set_fonts_folder(folder: Option<PathBuf>) {
|
||||
*FONTS_FOLDER.write().unwrap_or_else(|e| e.into_inner()) = folder;
|
||||
}
|
||||
|
||||
/// Local store for fonts downloaded from the community repository. Text
|
||||
/// resolution searches here after the drawing folder.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn fonts_dir() -> Option<PathBuf> {
|
||||
crate::config::config_dir().map(|dir| dir.join("fonts"))
|
||||
fonts_folder().or_else(|| crate::config::config_dir().map(|dir| dir.join("fonts")))
|
||||
}
|
||||
|
||||
/// Web builds have no filesystem to cache fonts into.
|
||||
|
||||
@@ -34,8 +34,26 @@ const STANDARD_PLOT_STYLES: &[&str] = &[
|
||||
SCREENING_25_PLOT_STYLE,
|
||||
];
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
static PLOT_STYLES_FOLDER: std::sync::RwLock<Option<PathBuf>> = std::sync::RwLock::new(None);
|
||||
|
||||
/// A folder chosen in Options to hold the plot style tables instead of the
|
||||
/// default one, such as a share on the office network.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn plot_styles_folder() -> Option<PathBuf> {
|
||||
PLOT_STYLES_FOLDER.read().unwrap_or_else(|e| e.into_inner()).clone()
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn set_plot_styles_folder(folder: Option<PathBuf>) {
|
||||
*PLOT_STYLES_FOLDER.write().unwrap_or_else(|e| e.into_inner()) = folder;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn plot_styles_dir() -> Result<PathBuf, String> {
|
||||
if let Some(folder) = plot_styles_folder() {
|
||||
return Ok(folder);
|
||||
}
|
||||
crate::config::config_dir()
|
||||
.map(|path| path.join("plotstyles"))
|
||||
.ok_or_else(|| "Plot styles folder could not be resolved".to_string())
|
||||
|
||||
+56
-14
@@ -95,7 +95,14 @@ pub struct AppPrefs {
|
||||
pub page_setup_on_new_layout: bool,
|
||||
}
|
||||
|
||||
/// The fixed locations the Files page lists.
|
||||
/// A Files-page location the user may move elsewhere.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum MovableFolder {
|
||||
Fonts,
|
||||
PlotStyles,
|
||||
}
|
||||
|
||||
/// The locations the Files page lists.
|
||||
///
|
||||
/// `None` where the platform could not give one — the row then says so and
|
||||
/// its button is disabled rather than opening nothing.
|
||||
@@ -110,6 +117,9 @@ pub struct Folders {
|
||||
pub fonts: Option<String>,
|
||||
/// Where `.acb` colour books are kept and loaded ones copied to.
|
||||
pub color_books: Option<String>,
|
||||
/// The fonts / plot styles folder was chosen in Options.
|
||||
pub fonts_moved: bool,
|
||||
pub plot_styles_moved: bool,
|
||||
}
|
||||
|
||||
/// Values read from the current drawing's header rather than from preferences.
|
||||
@@ -1750,11 +1760,13 @@ pub fn view_window<'a>(
|
||||
|
||||
let modeling = modeling.spacing(0).width(sizing.width);
|
||||
|
||||
// The application has no support-file search path, so this page does not
|
||||
// pretend to offer one. It shows where things actually live and opens the
|
||||
// folder — which is the question people are really asking when they go
|
||||
// looking for a Files page.
|
||||
let folder_row = |label: std::borrow::Cow<'a, str>, path: Option<String>| {
|
||||
// The page shows where things live and opens the folder — which is the
|
||||
// question people are really asking when they go looking for a Files
|
||||
// page. Fonts and plot styles can move elsewhere, such as a share on the
|
||||
// office network that a whole team uses.
|
||||
let folder_row = |label: std::borrow::Cow<'a, str>,
|
||||
path: Option<String>,
|
||||
movable: Option<(MovableFolder, bool)>| {
|
||||
let shown = path
|
||||
.clone()
|
||||
.unwrap_or_else(|| crate::t!("Not available").into_owned());
|
||||
@@ -1764,38 +1776,68 @@ pub fn view_window<'a>(
|
||||
if let Some(path) = path {
|
||||
open = open.on_press(Message::OpenFolder(path));
|
||||
}
|
||||
let mut buttons = row![open].spacing(6);
|
||||
if let Some((folder, moved)) = movable {
|
||||
buttons = buttons.push(
|
||||
button(text(crate::t!("Change...")).size(11))
|
||||
.padding([4, 10])
|
||||
.style(button::secondary)
|
||||
.on_press(Message::ChooseFolder(folder)),
|
||||
);
|
||||
if moved {
|
||||
buttons = buttons.push(
|
||||
button(text(crate::t!("Default")).size(11))
|
||||
.padding([4, 10])
|
||||
.style(button::secondary)
|
||||
.on_press(Message::FolderChosen(folder, None)),
|
||||
);
|
||||
}
|
||||
}
|
||||
row![
|
||||
column![text(label).size(12), text(shown).size(11),]
|
||||
.spacing(2)
|
||||
.width(Fill),
|
||||
open,
|
||||
buttons,
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center)
|
||||
};
|
||||
// Browsers have no folder picker.
|
||||
let movable = |folder: MovableFolder, moved: bool| {
|
||||
(!cfg!(target_arch = "wasm32")).then_some((folder, moved))
|
||||
};
|
||||
|
||||
let files = column![
|
||||
text(crate::t!("Files")).size(15),
|
||||
Space::new().height(6),
|
||||
text(crate::t!(
|
||||
"Where the application keeps its own files. These locations are fixed."
|
||||
"Where the application keeps its own files."
|
||||
))
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
Space::new().height(16),
|
||||
folder_row(crate::t!("Configuration"), folders.config.clone()),
|
||||
folder_row(crate::t!("Configuration"), folders.config.clone(), None),
|
||||
Space::new().height(12),
|
||||
folder_row(crate::t!("Plot styles"), folders.plot_styles.clone()),
|
||||
folder_row(
|
||||
crate::t!("Plot styles"),
|
||||
folders.plot_styles.clone(),
|
||||
movable(MovableFolder::PlotStyles, folders.plot_styles_moved),
|
||||
),
|
||||
Space::new().height(12),
|
||||
folder_row(crate::t!("Plugins"), folders.plugins.clone()),
|
||||
folder_row(crate::t!("Plugins"), folders.plugins.clone(), None),
|
||||
Space::new().height(12),
|
||||
folder_row(crate::t!("Autosave files"), folders.autosave.clone()),
|
||||
folder_row(crate::t!("Autosave files"), folders.autosave.clone(), None),
|
||||
Space::new().height(12),
|
||||
folder_row(crate::t!("Fonts"), folders.fonts.clone()),
|
||||
folder_row(
|
||||
crate::t!("Fonts"),
|
||||
folders.fonts.clone(),
|
||||
movable(MovableFolder::Fonts, folders.fonts_moved),
|
||||
),
|
||||
Space::new().height(12),
|
||||
folder_row(
|
||||
crate::t!("Color book locations"),
|
||||
folders.color_books.clone()
|
||||
folders.color_books.clone(),
|
||||
None,
|
||||
),
|
||||
Space::new().height(16),
|
||||
text(crate::t!("Default template for new drawings")).size(12),
|
||||
|
||||
Reference in new issue
Block a user