react-os-shell 0.3.18 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- export { Files as default, openFilesInTrashMode } from './chunk-7YCCZIDL.js';
2
- import './chunk-VLUA3CW4.js';
3
- import './chunk-HADXZNYO.js';
1
+ export { Files as default, openFilesInTrashMode } from './chunk-XHHU2QLD.js';
2
+ import './chunk-UVJCI67Z.js';
3
+ import './chunk-ATKI25NG.js';
4
4
  import './chunk-KUIPWCTJ.js';
5
5
  import './chunk-WIJ45SYD.js';
6
6
  import './chunk-6YY6A6SV.js';
7
7
  import './chunk-GI7ABQPU.js';
8
8
  import './chunk-PLGHQ7QW.js';
9
9
  import './chunk-SSA762W5.js';
10
- //# sourceMappingURL=Files-IIVM7S6O.js.map
11
- //# sourceMappingURL=Files-IIVM7S6O.js.map
10
+ //# sourceMappingURL=Files-XNTNB33C.js.map
11
+ //# sourceMappingURL=Files-XNTNB33C.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Files-IIVM7S6O.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Files-XNTNB33C.js"}
@@ -0,0 +1,8 @@
1
+ export { Preview as default, setPdfPreview } from './chunk-ATKI25NG.js';
2
+ import './chunk-KUIPWCTJ.js';
3
+ import './chunk-WIJ45SYD.js';
4
+ import './chunk-GI7ABQPU.js';
5
+ import './chunk-PLGHQ7QW.js';
6
+ import './chunk-SSA762W5.js';
7
+ //# sourceMappingURL=Preview-UV4X3NCN.js.map
8
+ //# sourceMappingURL=Preview-UV4X3NCN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Preview-VMZ3CJF6.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"Preview-UV4X3NCN.js"}
@@ -1,6 +1,6 @@
1
- export { openFilesInTrashMode } from '../chunk-7YCCZIDL.js';
2
- import '../chunk-VLUA3CW4.js';
3
- export { setPdfPreview } from '../chunk-HADXZNYO.js';
1
+ export { openFilesInTrashMode } from '../chunk-XHHU2QLD.js';
2
+ import '../chunk-UVJCI67Z.js';
3
+ export { setPdfPreview } from '../chunk-ATKI25NG.js';
4
4
  import '../chunk-KUIPWCTJ.js';
5
5
  import '../chunk-WIJ45SYD.js';
6
6
  export { setSpreadsheetPreview } from '../chunk-6YY6A6SV.js';
@@ -25,9 +25,9 @@ var Game2048 = lazy(() => import('../Game2048-3RH3ELRD.js'));
25
25
  var Minesweeper = lazy(() => import('../Minesweeper-ZDK33A6S.js'));
26
26
  var Email = lazy(() => import('../Email-7FJHS6Y7.js'));
27
27
  var Calendar = lazy(() => import('../Calendar-R4IBIPIU.js'));
28
- var Preview = lazy(() => import('../Preview-VMZ3CJF6.js'));
28
+ var Preview = lazy(() => import('../Preview-UV4X3NCN.js'));
29
29
  var Documents = lazy(() => import('../Documents-AUK2YPDI.js'));
30
- var Files = lazy(() => import('../Files-IIVM7S6O.js'));
30
+ var Files = lazy(() => import('../Files-XNTNB33C.js'));
31
31
  var Browser = lazy(() => import('../Browser-6JQTSHQF.js'));
32
32
  var utilityApps = {
33
33
  "/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, autoHeight: true, dimensions: [280, 420] },
@@ -514,16 +514,17 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
514
514
  const [showHint, setShowHint] = useState(true);
515
515
  const [measureEnabled, setMeasureEnabled] = useState(false);
516
516
  const [measureMode, setMeasureMode] = useState("horizontal");
517
- const [measureAutocad, setMeasureAutocad] = useState(true);
518
517
  const [measureDistance, setMeasureDistance] = useState(null);
518
+ const [measureFixedDist, setMeasureFixedDist] = useState(null);
519
+ const [measureFixedInput, setMeasureFixedInput] = useState("");
519
520
  const measureModeRef = useRef(measureMode);
520
- const measureAutocadRef = useRef(measureAutocad);
521
+ const measureFixedDistRef = useRef(measureFixedDist);
521
522
  useEffect(() => {
522
523
  measureModeRef.current = measureMode;
523
524
  }, [measureMode]);
524
525
  useEffect(() => {
525
- measureAutocadRef.current = measureAutocad;
526
- }, [measureAutocad]);
526
+ measureFixedDistRef.current = measureFixedDist;
527
+ }, [measureFixedDist]);
527
528
  const measureRedrawRef = useRef(null);
528
529
  const measureRef = useRef(null);
529
530
  useEffect(() => {
@@ -692,14 +693,23 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
692
693
  lineEl.setAttribute("stroke-linecap", "round");
693
694
  lineEl.style.display = "none";
694
695
  svg.appendChild(lineEl);
696
+ const fixedLineEl = document.createElementNS("http://www.w3.org/2000/svg", "line");
697
+ fixedLineEl.setAttribute("stroke", "#ff8800");
698
+ fixedLineEl.setAttribute("stroke-width", "1.5");
699
+ fixedLineEl.setAttribute("stroke-linecap", "round");
700
+ fixedLineEl.style.display = "none";
701
+ svg.appendChild(fixedLineEl);
695
702
  const snapEl = document.createElement("div");
696
703
  snapEl.style.cssText = `position:absolute;width:14px;height:14px;border:2px solid #ff8800;background:rgba(255,255,255,0.7);transform:translate(-50%,-50%) rotate(45deg);box-sizing:border-box;display:none;`;
697
704
  overlay.appendChild(snapEl);
698
705
  measureRef.current = {
699
706
  picks: [],
707
+ rawSecondClick: null,
700
708
  overlay,
701
709
  svg,
702
710
  line: lineEl,
711
+ fixedLine: fixedLineEl,
712
+ fixedLabel: null,
703
713
  refLine: refLineEl,
704
714
  extLineA,
705
715
  extLineB,
@@ -807,24 +817,48 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
807
817
  el.style.left = `${p.x}px`;
808
818
  el.style.top = `${p.y}px`;
809
819
  };
810
- const computeRenderedEnds = () => {
820
+ const reconcileLockedPick = () => {
821
+ const s = measureRef.current;
822
+ if (!s || !s.rawSecondClick || s.picks.length < 2) return;
823
+ const a = s.picks[0];
824
+ const raw = s.rawSecondClick;
825
+ const fixed = measureFixedDistRef.current;
826
+ const mode = measureModeRef.current;
827
+ if (fixed !== null && Number.isFinite(fixed) && (mode === "horizontal" || mode === "vertical")) {
828
+ if (mode === "horizontal") {
829
+ const sign = raw.x >= a.x ? 1 : -1;
830
+ s.picks[1] = { x: a.x + sign * Math.abs(fixed), y: raw.y };
831
+ } else {
832
+ const sign = raw.y >= a.y ? 1 : -1;
833
+ s.picks[1] = { x: raw.x, y: a.y + sign * Math.abs(fixed) };
834
+ }
835
+ } else {
836
+ s.picks[1] = { x: raw.x, y: raw.y };
837
+ }
838
+ };
839
+ const computeMainDimEnds = () => {
811
840
  const s = measureRef.current;
812
841
  const a = s.picks[0];
813
842
  const b = s.picks[1];
814
843
  const mode = measureModeRef.current;
815
- if (mode === "horizontal") {
816
- return { from: a, to: { x: b.x, y: a.y } };
844
+ const fixed = measureFixedDistRef.current;
845
+ if (fixed !== null && Number.isFinite(fixed) && mode === "horizontal") {
846
+ return { from: { x: b.x, y: a.y }, to: { x: b.x, y: b.y } };
817
847
  }
818
- if (mode === "vertical") {
819
- return { from: a, to: { x: a.x, y: b.y } };
848
+ if (fixed !== null && Number.isFinite(fixed) && mode === "vertical") {
849
+ return { from: { x: a.x, y: b.y }, to: { x: b.x, y: b.y } };
820
850
  }
851
+ if (mode === "horizontal") return { from: a, to: { x: b.x, y: a.y } };
852
+ if (mode === "vertical") return { from: a, to: { x: a.x, y: b.y } };
821
853
  return { from: a, to: b };
822
854
  };
823
855
  const updateOverlay = () => {
824
856
  const s = measureRef.current;
825
857
  if (!s) return;
858
+ reconcileLockedPick();
826
859
  const mode = measureModeRef.current;
827
- const autocad = measureAutocadRef.current;
860
+ const fixed = measureFixedDistRef.current;
861
+ const fixedActive = fixed !== null && Number.isFinite(fixed) && (mode === "horizontal" || mode === "vertical");
828
862
  if (s.markers[0]) positionMarker(s.markers[0], s.picks[0].x, s.picks[0].y);
829
863
  if (s.markers[1]) positionMarker(s.markers[1], s.picks[1].x, s.picks[1].y);
830
864
  const refDir = mode === "horizontal" ? { dx: 1, dy: 0 } : mode === "vertical" ? { dx: 0, dy: 1 } : null;
@@ -852,24 +886,43 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
852
886
  }
853
887
  if (s.picks.length === 2) {
854
888
  const a = s.picks[0], b = s.picks[1];
855
- const ends = computeRenderedEnds();
889
+ const ends = computeMainDimEnds();
856
890
  const fp = pxFromScene(ends.from.x, ends.from.y);
857
891
  const tp = pxFromScene(ends.to.x, ends.to.y);
858
892
  s.line.setAttribute("x1", String(fp.x));
859
893
  s.line.setAttribute("y1", String(fp.y));
860
894
  s.line.setAttribute("x2", String(tp.x));
861
895
  s.line.setAttribute("y2", String(tp.y));
862
- s.line.style.display = "";
863
- if (autocad) {
864
- s.line.setAttribute("marker-start", "url(#dxf-measure-arrow)");
865
- s.line.setAttribute("marker-end", "url(#dxf-measure-arrow)");
896
+ s.line.setAttribute("marker-start", "url(#dxf-measure-arrow)");
897
+ s.line.setAttribute("marker-end", "url(#dxf-measure-arrow)");
898
+ const mainLen = Math.hypot(tp.x - fp.x, tp.y - fp.y);
899
+ s.line.style.display = mainLen > 0.5 ? "" : "none";
900
+ if (fixedActive && s.fixedLine) {
901
+ const r = mode === "horizontal" ? { x: b.x, y: a.y } : { x: a.x, y: b.y };
902
+ const ap = pxFromScene(a.x, a.y);
903
+ const rp = pxFromScene(r.x, r.y);
904
+ s.fixedLine.setAttribute("x1", String(ap.x));
905
+ s.fixedLine.setAttribute("y1", String(ap.y));
906
+ s.fixedLine.setAttribute("x2", String(rp.x));
907
+ s.fixedLine.setAttribute("y2", String(rp.y));
908
+ s.fixedLine.setAttribute("marker-start", "url(#dxf-measure-arrow)");
909
+ s.fixedLine.setAttribute("marker-end", "url(#dxf-measure-arrow)");
910
+ s.fixedLine.style.display = "";
911
+ const fLabel = ensureFixedLabel();
912
+ fLabel.textContent = formatMeasureDistance(Math.abs(fixed));
913
+ const fcx = (ap.x + rp.x) / 2;
914
+ const fcy = (ap.y + rp.y) / 2;
915
+ fLabel.style.left = `${fcx}px`;
916
+ fLabel.style.top = `${fcy}px`;
917
+ const w = canvas.clientWidth, h = canvas.clientHeight;
918
+ fLabel.style.display = fcx < 0 || fcy < 0 || fcx > w || fcy > h ? "none" : "";
866
919
  } else {
867
- s.line.removeAttribute("marker-start");
868
- s.line.removeAttribute("marker-end");
920
+ if (s.fixedLine) s.fixedLine.style.display = "none";
921
+ if (s.fixedLabel) s.fixedLabel.style.display = "none";
869
922
  }
870
923
  const extA = s.extLineA;
871
924
  const extB = s.extLineB;
872
- if (autocad && mode === "horizontal" && Math.abs(b.y - a.y) > 1e-9) {
925
+ if (!fixedActive && mode === "horizontal" && Math.abs(b.y - a.y) > 1e-9) {
873
926
  const p = pxFromScene(b.x, a.y);
874
927
  const q = pxFromScene(b.x, b.y);
875
928
  extB.setAttribute("x1", String(p.x));
@@ -878,7 +931,7 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
878
931
  extB.setAttribute("y2", String(q.y));
879
932
  extB.style.display = "";
880
933
  extA.style.display = "none";
881
- } else if (autocad && mode === "vertical" && Math.abs(b.x - a.x) > 1e-9) {
934
+ } else if (!fixedActive && mode === "vertical" && Math.abs(b.x - a.x) > 1e-9) {
882
935
  const p = pxFromScene(a.x, b.y);
883
936
  const q = pxFromScene(b.x, b.y);
884
937
  extB.setAttribute("x1", String(p.x));
@@ -898,13 +951,25 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
898
951
  s.label.style.top = `${cy}px`;
899
952
  const w = canvas.clientWidth, h = canvas.clientHeight;
900
953
  s.label.style.display = cx < 0 || cy < 0 || cx > w || cy > h ? "none" : "";
954
+ if (mainLen <= 0.5) s.label.style.display = "none";
901
955
  }
902
956
  } else {
903
957
  s.line.style.display = "none";
958
+ if (s.fixedLine) s.fixedLine.style.display = "none";
959
+ if (s.fixedLabel) s.fixedLabel.style.display = "none";
904
960
  if (s.extLineA) s.extLineA.style.display = "none";
905
961
  if (s.extLineB) s.extLineB.style.display = "none";
906
962
  }
907
963
  };
964
+ const ensureFixedLabel = () => {
965
+ const s = measureRef.current;
966
+ if (s.fixedLabel) return s.fixedLabel;
967
+ const el = document.createElement("div");
968
+ el.style.cssText = `position:absolute;left:-9999px;top:-9999px;transform:translate(-50%,-50%);padding:2px 6px;font-size:11px;font-weight:600;font-family:system-ui,-apple-system,sans-serif;background:rgba(255,136,0,0.75);color:#fff;border-radius:4px;white-space:nowrap;box-shadow:0 1px 4px rgba(0,0,0,0.25);pointer-events:none;`;
969
+ overlay.appendChild(el);
970
+ s.fixedLabel = el;
971
+ return el;
972
+ };
908
973
  const DRAG_TOL = 4;
909
974
  const DRAG_TIME = 350;
910
975
  let downX = 0, downY = 0, downTime = 0, downActive = false, dragging = false;
@@ -954,11 +1019,20 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
954
1019
  const recomputeLabel = () => {
955
1020
  const s = measureRef.current;
956
1021
  if (!s || s.picks.length !== 2) return;
1022
+ reconcileLockedPick();
957
1023
  const a = s.picks[0], b = s.picks[1];
958
1024
  const mode = measureModeRef.current;
1025
+ const fixed = measureFixedDistRef.current;
1026
+ const fixedActive = fixed !== null && Number.isFinite(fixed) && (mode === "horizontal" || mode === "vertical");
959
1027
  let dist;
960
1028
  let suffix = "";
961
- if (mode === "horizontal") {
1029
+ if (fixedActive && mode === "horizontal") {
1030
+ dist = Math.abs(b.y - a.y);
1031
+ suffix = " \u2195";
1032
+ } else if (fixedActive && mode === "vertical") {
1033
+ dist = Math.abs(b.x - a.x);
1034
+ suffix = " \u2194";
1035
+ } else if (mode === "horizontal") {
962
1036
  dist = Math.abs(b.x - a.x);
963
1037
  suffix = " \u2194";
964
1038
  } else if (mode === "vertical") {
@@ -984,16 +1058,23 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
984
1058
  for (const m of s.markers) m.parentElement?.removeChild(m);
985
1059
  s.markers = [];
986
1060
  s.picks = [];
1061
+ s.rawSecondClick = null;
987
1062
  s.line.style.display = "none";
1063
+ if (s.fixedLine) s.fixedLine.style.display = "none";
1064
+ if (s.fixedLabel) s.fixedLabel.style.display = "none";
988
1065
  if (s.refLine) s.refLine.style.display = "none";
989
1066
  if (s.extLineA) s.extLineA.style.display = "none";
990
1067
  if (s.extLineB) s.extLineB.style.display = "none";
991
1068
  if (s.label) s.label.style.opacity = "0";
992
1069
  setMeasureDistance(null);
993
1070
  }
994
- s.picks.push({ x: p.x, y: p.y });
995
- s.markers.push(makeMarker());
996
- if (s.picks.length === 2) {
1071
+ if (s.picks.length === 0) {
1072
+ s.picks.push({ x: p.x, y: p.y });
1073
+ s.markers.push(makeMarker());
1074
+ } else {
1075
+ s.rawSecondClick = { x: p.x, y: p.y };
1076
+ s.picks.push({ x: p.x, y: p.y });
1077
+ s.markers.push(makeMarker());
997
1078
  recomputeLabel();
998
1079
  }
999
1080
  updateOverlay();
@@ -1039,7 +1120,7 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
1039
1120
  }, [measureEnabled, loading, error]);
1040
1121
  useEffect(() => {
1041
1122
  measureRedrawRef.current?.();
1042
- }, [measureMode, measureAutocad]);
1123
+ }, [measureMode, measureFixedDist]);
1043
1124
  const toggleLayer = (name) => {
1044
1125
  setLayers((prev) => prev.map((l) => {
1045
1126
  if (l.name !== name) return l;
@@ -1130,21 +1211,6 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
1130
1211
  }
1131
1212
  ),
1132
1213
  measureEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
1133
- /* @__PURE__ */ jsx(
1134
- "button",
1135
- {
1136
- onClick: () => {
1137
- setMeasureAutocad((prev) => {
1138
- const next = !prev;
1139
- if (next && measureMode === "point") setMeasureMode("horizontal");
1140
- return next;
1141
- });
1142
- },
1143
- className: btn + (measureAutocad ? " bg-orange-100 text-orange-700" : ""),
1144
- title: measureAutocad ? "AutoCAD dim style is ON \u2014 extension lines + arrows" : "AutoCAD dim style is OFF \u2014 plain line. Click to turn on (also switches to H if you're in Point).",
1145
- children: "\u22A5"
1146
- }
1147
- ),
1148
1214
  /* @__PURE__ */ jsxs("div", { className: "flex items-stretch h-7 rounded border border-gray-200 overflow-hidden text-[11px] font-semibold", children: [
1149
1215
  /* @__PURE__ */ jsx(
1150
1216
  "button",
@@ -1173,6 +1239,41 @@ function DxfPanel({ url, filename, onDownload, onEmail }) {
1173
1239
  children: "V"
1174
1240
  }
1175
1241
  )
1242
+ ] }),
1243
+ (measureMode === "horizontal" || measureMode === "vertical") && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1244
+ /* @__PURE__ */ jsx(
1245
+ "input",
1246
+ {
1247
+ type: "number",
1248
+ inputMode: "decimal",
1249
+ step: "any",
1250
+ value: measureFixedInput,
1251
+ placeholder: measureMode === "horizontal" ? "fix \u0394x" : "fix \u0394y",
1252
+ onChange: (e) => {
1253
+ const raw = e.target.value;
1254
+ setMeasureFixedInput(raw);
1255
+ if (raw.trim() === "") setMeasureFixedDist(null);
1256
+ else {
1257
+ const n = parseFloat(raw);
1258
+ setMeasureFixedDist(Number.isFinite(n) && n !== 0 ? n : null);
1259
+ }
1260
+ },
1261
+ className: "h-7 w-20 px-1.5 text-[11px] font-mono rounded border border-gray-200 bg-white text-gray-700 focus:outline-none focus:border-orange-400",
1262
+ title: "Lock the second pick's axis coord to first pick + this value (mm). The reported measurement becomes the perpendicular distance."
1263
+ }
1264
+ ),
1265
+ measureFixedDist !== null && /* @__PURE__ */ jsx(
1266
+ "button",
1267
+ {
1268
+ onClick: () => {
1269
+ setMeasureFixedDist(null);
1270
+ setMeasureFixedInput("");
1271
+ },
1272
+ className: "text-gray-400 hover:text-gray-600 text-[11px] px-1",
1273
+ title: "Clear fixed distance",
1274
+ children: "\xD7"
1275
+ }
1276
+ )
1176
1277
  ] })
1177
1278
  ] }),
1178
1279
  measureEnabled && measureDistance !== null && /* @__PURE__ */ jsxs(
@@ -2546,5 +2647,5 @@ function ImagePanel({ url, filename, onDownload, onEmail }) {
2546
2647
  }
2547
2648
 
2548
2649
  export { Preview, setPdfPreview };
2549
- //# sourceMappingURL=chunk-HADXZNYO.js.map
2550
- //# sourceMappingURL=chunk-HADXZNYO.js.map
2650
+ //# sourceMappingURL=chunk-ATKI25NG.js.map
2651
+ //# sourceMappingURL=chunk-ATKI25NG.js.map