Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added possiblity for the user to set a custom print-scale. #1140

Merged
merged 3 commits into from
Aug 18, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 183 additions & 84 deletions new-client/src/plugins/Print/GeneralOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { withSnackbar } from "notistack";
import {
FormControl,
FormHelperText,
IconButton,
InputAdornment,
InputLabel,
MenuItem,
Select,
Input,
Tooltip,
} from "@mui/material";
import FormatListNumberedIcon from "@mui/icons-material/FormatListNumbered";

const Root = styled(Grid)(() => ({
display: "flex",
Expand All @@ -23,6 +28,7 @@ const StyledFormControl = styled(FormControl)(({ theme }) => ({
class GeneralOptions extends React.PureComponent {
state = {
anchorEl: null,
useCustomScale: false,
};

// Default colors for color picker used to set text color (used in map title, scale, etc)
Expand All @@ -43,100 +49,204 @@ class GeneralOptions extends React.PureComponent {
"#9B9B9B",
];

// Handles interaction with the scale-selector. We cannot let the
// parent handler (handleChange) take care of this on its own since
// we have an extra vale ("CUSTOM_SCALE") that should not affect the selected
// scale, but instead update the state so that a scale-input is shown.
handleScaleSelectChange = (e) => {
const { handleChange } = this.props;
const { value } = e.target;
// If we're not dealing with a custom scale, just update the scale, otherwise
// update the local state so that the user can set a custom scale.
value !== "CUSTOM_SCALE"
? handleChange(e)
: this.setState({ useCustomScale: true });
};

// Handles when the custom scale input is to be hidden, and the scale-selector
// is to be shown. We have to make sure to update the scale to the option closest
// to the current value.
handleDisableCustomScaleInput = () => {
const { handleChange, scales, scale } = this.props;
// First we'll have to grab the closest scale option
const closestScaleOption = scales.reduce((prev, curr) =>
Math.abs(curr - scale) < Math.abs(prev - scale) ? curr : prev
);
// Then we'll update the scale to that value
handleChange({ target: { name: "scale", value: closestScaleOption } });
// And then we'll toggle the scale-input.
this.setState({ useCustomScale: false });
};

renderPaperSizeSelector = () => {
const { format, handleChange } = this.props;
return (
<Select
variant="standard"
value={format}
onChange={handleChange}
inputProps={{
name: "format",
id: "format",
}}
>
{this.props.options.paperFormats.map((value, index) => {
return (
<MenuItem key={"paperFormat_" + index} value={value}>
{value.toUpperCase()}
</MenuItem>
);
})}
</Select>
);
};

renderUseMarginSelector = () => {
const { useMargin, handleChange } = this.props;
return (
<Select
variant="standard"
value={useMargin}
onChange={handleChange}
inputProps={{
name: "useMargin",
id: "useMargin",
}}
>
<MenuItem value={true}>Ja</MenuItem>
<MenuItem value={false}>Nej</MenuItem>
</Select>
);
};

renderOrientationSelector = () => {
const { orientation, handleChange } = this.props;
return (
<Select
variant="standard"
value={orientation}
onChange={handleChange}
inputProps={{
name: "orientation",
id: "orientation",
}}
>
<MenuItem value={"landscape"}>Liggande</MenuItem>
<MenuItem value={"portrait"}>Stående</MenuItem>
</Select>
);
};

renderScaleSelector = () => {
const { model, scales, scale } = this.props;
// We're gonna have to create a new array with an object for each scale-value.
// The objects contain the actual scale-value, along with a user-friendly label.
// For example, scale: 1000, label: 1:1 000
// We also add the extra option ("CUSTOM_SCALE"), allowing the user to select a
// a custom scale value.
const scaleSelectorOptions = [
...scales.map((s) => {
return { value: s, label: model.getUserFriendlyScale(s) };
}),
{ value: "CUSTOM_SCALE", label: "Ange annan skala" },
];
return (
<Select
variant="standard"
value={scale}
onChange={this.handleScaleSelectChange}
inputProps={{
name: "scale",
id: "scale",
}}
>
{scaleSelectorOptions.map((scale, i) => {
// Note: it is crucial to keep the scale value (in state) divided by 1000 from what is shown to user!
return (
<MenuItem key={i} value={scale.value}>
{scale.label}
</MenuItem>
);
})}
</Select>
);
};

renderScaleInput = () => {
return (
<Input
value={this.props.scale}
type="number"
startAdornment={<InputAdornment position="start">1:</InputAdornment>}
endAdornment={
<InputAdornment position="end">
<Tooltip title="Visa fördefinerade val">
<IconButton
aria-label="toggle custom scale selector"
onClick={this.handleDisableCustomScaleInput}
>
<FormatListNumberedIcon />
</IconButton>
</Tooltip>
</InputAdornment>
}
inputProps={{
name: "scale",
id: "scale",
}}
onChange={this.props.handleChange}
/>
);
};

renderSaveAsTypeSelector = () => {
const { saveAsType, handleChange } = this.props;
return (
<Select
variant="standard"
value={saveAsType}
onChange={handleChange}
inputProps={{
name: "saveAsType",
id: "saveAsType",
}}
>
<MenuItem value={"PDF"}>PDF</MenuItem>
<MenuItem value={"PNG"}>PNG</MenuItem>
</Select>
);
};

render() {
const {
useMargin,
orientation,
format,
scale,
scales,
handleChange,
model,
saveAsType,
printOptionsOk,
} = this.props;
const { printOptionsOk } = this.props;
return (
<>
<Root>
<StyledFormControl>
<InputLabel variant="standard" htmlFor="format">
Format
</InputLabel>
<Select
variant="standard"
value={format}
onChange={handleChange}
inputProps={{
name: "format",
id: "format",
}}
>
{this.props.options.paperFormats.map((value, index) => {
return (
<MenuItem key={"paperFormat_" + index} value={value}>
{value.toUpperCase()}
</MenuItem>
);
})}
</Select>
{this.renderPaperSizeSelector()}
</StyledFormControl>
<StyledFormControl>
<InputLabel variant="standard" htmlFor="useMargin">
Marginaler runt kartbilden
</InputLabel>
<Select
variant="standard"
value={useMargin}
onChange={handleChange}
inputProps={{
name: "useMargin",
id: "useMargin",
}}
>
<MenuItem value={true}>Ja</MenuItem>
<MenuItem value={false}>Nej</MenuItem>
</Select>
{this.renderUseMarginSelector()}
</StyledFormControl>
<StyledFormControl>
<InputLabel variant="standard" htmlFor="orientation">
Orientering
</InputLabel>
<Select
variant="standard"
value={orientation}
onChange={handleChange}
inputProps={{
name: "orientation",
id: "orientation",
}}
>
<MenuItem value={"landscape"}>Liggande</MenuItem>
<MenuItem value={"portrait"}>Stående</MenuItem>
</Select>
{this.renderOrientationSelector()}
</StyledFormControl>

<StyledFormControl error={!printOptionsOk}>
<InputLabel variant="standard" htmlFor="scale">
Skala
</InputLabel>
<Select
variant="standard"
value={scale}
onChange={handleChange}
inputProps={{
name: "scale",
id: "scale",
}}
>
{scales.map((scale, i) => {
// Note: it is crucial to keep the scale value (in state) divided by 1000 from what is shown to user!
return (
<MenuItem key={i} value={scale}>
{model.getUserFriendlyScale(scale)}
</MenuItem>
);
})}
</Select>
{this.state.useCustomScale
? this.renderScaleInput()
: this.renderScaleSelector()}
{!printOptionsOk && (
<FormHelperText>
Bilden kommer inte kunna skrivas ut korrekt. Testa med en lägre
Expand All @@ -145,21 +255,10 @@ class GeneralOptions extends React.PureComponent {
)}
</StyledFormControl>
<StyledFormControl>
<InputLabel variant="standard" htmlFor="orientation">
<InputLabel variant="standard" htmlFor="saveAsType">
Spara som
</InputLabel>
<Select
variant="standard"
value={saveAsType}
onChange={handleChange}
inputProps={{
name: "saveAsType",
id: "saveAsType",
}}
>
<MenuItem value={"PDF"}>PDF</MenuItem>
<MenuItem value={"PNG"}>PNG</MenuItem>
</Select>
{this.renderSaveAsTypeSelector()}
</StyledFormControl>
</Root>
</>
Expand Down