Stirling-PDF/frontend/src/components/pageEditor/PageEditorControls.tsx

246 lines
7.2 KiB
TypeScript
Raw Normal View History

2025-06-19 19:47:44 +01:00
import React from "react";
import {
Tooltip,
ActionIcon,
Paper
} from "@mantine/core";
import UndoIcon from "@mui/icons-material/Undo";
import RedoIcon from "@mui/icons-material/Redo";
import ContentCutIcon from "@mui/icons-material/ContentCut";
import DownloadIcon from "@mui/icons-material/Download";
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import DeleteIcon from "@mui/icons-material/Delete";
import CloseIcon from "@mui/icons-material/Close";
2025-08-25 17:11:23 +01:00
import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak";
2025-06-19 19:47:44 +01:00
interface PageEditorControlsProps {
// Close/Reset functions
onClosePdf: () => void;
// Undo/Redo
onUndo: () => void;
onRedo: () => void;
canUndo: boolean;
canRedo: boolean;
// Page operations
onRotate: (direction: 'left' | 'right') => void;
onDelete: () => void;
onSplit: () => void;
2025-08-23 02:03:51 +01:00
onSplitAll: () => void;
2025-08-25 17:11:23 +01:00
onPageBreak: () => void;
onPageBreakAll: () => void;
2025-06-19 19:47:44 +01:00
// Export functions
onExportSelected: () => void;
onExportAll: () => void;
exportLoading: boolean;
// Selection state
selectionMode: boolean;
selectedPages: number[];
2025-08-23 02:03:51 +01:00
// Split state (for tooltip logic)
splitPositions?: Set<number>;
totalPages?: number;
2025-06-19 19:47:44 +01:00
}
const PageEditorControls = ({
onClosePdf,
onUndo,
onRedo,
canUndo,
canRedo,
onRotate,
onDelete,
onSplit,
2025-08-23 02:03:51 +01:00
onSplitAll,
2025-08-25 17:11:23 +01:00
onPageBreak,
onPageBreakAll,
2025-06-19 19:47:44 +01:00
onExportSelected,
onExportAll,
exportLoading,
selectionMode,
2025-08-23 02:03:51 +01:00
selectedPages,
splitPositions,
totalPages
2025-06-19 19:47:44 +01:00
}: PageEditorControlsProps) => {
2025-08-23 02:03:51 +01:00
// Calculate split all tooltip text
const getSplitAllTooltip = () => {
if (selectionMode) {
return "Split Selected";
}
if (!splitPositions || !totalPages) {
return "Split All";
}
// Check if all possible splits are active
const allPossibleSplitsCount = totalPages - 1;
const hasAllSplits = splitPositions.size === allPossibleSplitsCount &&
Array.from({length: allPossibleSplitsCount}, (_, i) => i).every(pos => splitPositions.has(pos));
return hasAllSplits ? "Remove All Splits" : "Split All";
};
2025-08-25 17:11:23 +01:00
// Calculate page break tooltip text
const getPageBreakTooltip = () => {
if (selectionMode) {
return selectedPages.length > 0
? `Insert ${selectedPages.length} Page Break${selectedPages.length > 1 ? 's' : ''}`
: "Insert Page Breaks";
}
return "Insert Page Breaks After All Pages";
};
2025-06-19 19:47:44 +01:00
return (
<div
style={{
Stirling 2.0 (#3928) # Description of Changes <!-- File context for managing files between tools and views Optimisation for large files Updated Split to work with new file system and match Matts stepped design closer --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2025-07-16 17:53:50 +01:00
position: 'absolute',
2025-06-19 19:47:44 +01:00
left: '50%',
bottom: '20px',
transform: 'translateX(-50%)',
zIndex: 50,
display: 'flex',
justifyContent: 'center',
pointerEvents: 'none',
background: 'transparent',
}}
>
<Paper
radius="xl"
shadow="lg"
p={16}
style={{
display: 'flex',
alignItems: 'center',
gap: 12,
borderRadius: 32,
boxShadow: '0 8px 32px rgba(0,0,0,0.12)',
pointerEvents: 'auto',
minWidth: 400,
justifyContent: 'center'
}}
>
{/* Close PDF */}
<Tooltip label="Close PDF">
<ActionIcon
onClick={onClosePdf}
color="red"
variant="light"
size="lg"
>
<CloseIcon />
</ActionIcon>
</Tooltip>
<div style={{ width: 1, height: 28, backgroundColor: 'var(--mantine-color-gray-3)', margin: '0 8px' }} />
{/* Undo/Redo */}
<Tooltip label="Undo">
<ActionIcon onClick={onUndo} disabled={!canUndo} size="lg">
<UndoIcon />
</ActionIcon>
</Tooltip>
<Tooltip label="Redo">
<ActionIcon onClick={onRedo} disabled={!canRedo} size="lg">
<RedoIcon />
</ActionIcon>
</Tooltip>
<div style={{ width: 1, height: 28, backgroundColor: 'var(--mantine-color-gray-3)', margin: '0 8px' }} />
{/* Page Operations */}
<Tooltip label={selectionMode ? "Rotate Selected Left" : "Rotate All Left"}>
<ActionIcon
onClick={() => onRotate('left')}
disabled={selectionMode && selectedPages.length === 0}
variant={selectionMode && selectedPages.length > 0 ? "light" : "default"}
color={selectionMode && selectedPages.length > 0 ? "blue" : undefined}
size="lg"
>
<RotateLeftIcon />
</ActionIcon>
</Tooltip>
<Tooltip label={selectionMode ? "Rotate Selected Right" : "Rotate All Right"}>
<ActionIcon
onClick={() => onRotate('right')}
disabled={selectionMode && selectedPages.length === 0}
variant={selectionMode && selectedPages.length > 0 ? "light" : "default"}
color={selectionMode && selectedPages.length > 0 ? "blue" : undefined}
size="lg"
>
<RotateRightIcon />
</ActionIcon>
</Tooltip>
2025-08-23 02:04:58 +01:00
{selectionMode && (
<Tooltip label="Delete Selected">
<ActionIcon
onClick={onDelete}
disabled={selectedPages.length === 0}
color="red"
variant={selectedPages.length > 0 ? "light" : "default"}
size="lg"
>
<DeleteIcon />
</ActionIcon>
</Tooltip>
)}
2025-08-23 02:03:51 +01:00
<Tooltip label={getSplitAllTooltip()}>
2025-06-19 19:47:44 +01:00
<ActionIcon
2025-08-23 02:03:51 +01:00
onClick={selectionMode ? onSplit : onSplitAll}
2025-06-19 19:47:44 +01:00
disabled={selectionMode && selectedPages.length === 0}
variant={selectionMode && selectedPages.length > 0 ? "light" : "default"}
color={selectionMode && selectedPages.length > 0 ? "blue" : undefined}
size="lg"
>
<ContentCutIcon />
</ActionIcon>
</Tooltip>
2025-08-25 17:11:23 +01:00
<Tooltip label={getPageBreakTooltip()}>
<ActionIcon
onClick={selectionMode ? onPageBreak : onPageBreakAll}
disabled={selectionMode && selectedPages.length === 0}
variant={selectionMode && selectedPages.length > 0 ? "light" : "default"}
color={selectionMode && selectedPages.length > 0 ? "orange" : undefined}
size="lg"
>
<InsertPageBreakIcon />
</ActionIcon>
</Tooltip>
2025-06-19 19:47:44 +01:00
<div style={{ width: 1, height: 28, backgroundColor: 'var(--mantine-color-gray-3)', margin: '0 8px' }} />
{/* Export Controls */}
2025-08-23 02:04:58 +01:00
{selectionMode && (
2025-06-19 19:47:44 +01:00
<Tooltip label="Export Selected">
<ActionIcon
onClick={onExportSelected}
2025-08-23 02:04:58 +01:00
disabled={exportLoading || selectedPages.length === 0}
2025-06-19 19:47:44 +01:00
color="blue"
2025-08-23 02:04:58 +01:00
variant={selectedPages.length > 0 ? "light" : "default"}
2025-06-19 19:47:44 +01:00
size="lg"
>
<DownloadIcon />
</ActionIcon>
</Tooltip>
)}
<Tooltip label="Export All">
<ActionIcon
onClick={onExportAll}
disabled={exportLoading}
color="green"
variant="light"
size="lg"
>
<DownloadIcon />
</ActionIcon>
</Tooltip>
</Paper>
</div>
);
};
export default PageEditorControls;