You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tools-panel.tsx 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import {
  2. ArrowTopRightIcon,
  3. CircleIcon,
  4. CursorArrowIcon,
  5. DividerHorizontalIcon,
  6. DotIcon,
  7. LockClosedIcon,
  8. LockOpen1Icon,
  9. Pencil1Icon,
  10. Pencil2Icon,
  11. SewingPinIcon,
  12. SquareIcon,
  13. } from '@radix-ui/react-icons'
  14. import { IconButton } from 'components/shared'
  15. import React from 'react'
  16. import state, { useSelector } from 'state'
  17. import styled from 'styles'
  18. import { ShapeType } from 'types'
  19. import UndoRedo from './undo-redo'
  20. import Zoom from './zoom'
  21. import Tooltip from '../tooltip'
  22. const selectArrowTool = () => state.send('SELECTED_ARROW_TOOL')
  23. const selectCircleTool = () => state.send('SELECTED_CIRCLE_TOOL')
  24. const selectDotTool = () => state.send('SELECTED_DOT_TOOL')
  25. const selectDrawTool = () => state.send('SELECTED_DRAW_TOOL')
  26. const selectEllipseTool = () => state.send('SELECTED_ELLIPSE_TOOL')
  27. const selectLineTool = () => state.send('SELECTED_LINE_TOOL')
  28. const selectPolylineTool = () => state.send('SELECTED_POLYLINE_TOOL')
  29. const selectRayTool = () => state.send('SELECTED_RAY_TOOL')
  30. const selectRectangleTool = () => state.send('SELECTED_RECTANGLE_TOOL')
  31. const selectSelectTool = () => state.send('SELECTED_SELECT_TOOL')
  32. const selectToolLock = () => state.send('TOGGLED_TOOL_LOCK')
  33. export default function ToolsPanel() {
  34. const activeTool = useSelector((s) => s.data.activeTool)
  35. const isToolLocked = useSelector((s) => s.data.settings.isToolLocked)
  36. const isPenLocked = useSelector((s) => s.data.settings.isPenLocked)
  37. return (
  38. <OuterContainer>
  39. <Zoom />
  40. <Flex size={{ '@sm': 'small' }}>
  41. <Container>
  42. <Tooltip label="Select">
  43. <IconButton
  44. name="select"
  45. size={{ '@initial': 'small', '@sm': 'small', '@md': 'large' }}
  46. onClick={selectSelectTool}
  47. isActive={activeTool === 'select'}
  48. >
  49. <CursorArrowIcon />
  50. </IconButton>
  51. </Tooltip>
  52. </Container>
  53. <Container>
  54. <Tooltip label="Draw">
  55. <IconButton
  56. name={ShapeType.Draw}
  57. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  58. onClick={selectDrawTool}
  59. isActive={activeTool === ShapeType.Draw}
  60. >
  61. <Pencil1Icon />
  62. </IconButton>
  63. </Tooltip>
  64. <Tooltip label="Rectangle">
  65. <IconButton
  66. name={ShapeType.Rectangle}
  67. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  68. onClick={selectRectangleTool}
  69. isActive={activeTool === ShapeType.Rectangle}
  70. >
  71. <SquareIcon />
  72. </IconButton>
  73. </Tooltip>
  74. <Tooltip label="Ellipse">
  75. <IconButton
  76. name={ShapeType.Circle}
  77. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  78. onClick={selectEllipseTool}
  79. isActive={activeTool === ShapeType.Ellipse}
  80. >
  81. <CircleIcon />
  82. </IconButton>
  83. </Tooltip>
  84. <Tooltip label="Arrow">
  85. <IconButton
  86. name={ShapeType.Arrow}
  87. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  88. onClick={selectArrowTool}
  89. isActive={activeTool === ShapeType.Arrow}
  90. >
  91. <ArrowTopRightIcon />
  92. </IconButton>
  93. </Tooltip>
  94. {/* <IconButton
  95. name={ShapeType.Circle}
  96. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  97. onClick={selectCircleTool}
  98. isActive={activeTool === ShapeType.Circle}
  99. >
  100. <CircleIcon />
  101. </IconButton> */}
  102. {/* <IconButton
  103. name={ShapeType.Line}
  104. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  105. onClick={selectLineTool}
  106. isActive={activeTool === ShapeType.Line}
  107. >
  108. <DividerHorizontalIcon transform="rotate(-45)" />
  109. </IconButton>
  110. <IconButton
  111. name={ShapeType.Ray}
  112. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  113. onClick={selectRayTool}
  114. isActive={activeTool === ShapeType.Ray}
  115. >
  116. <SewingPinIcon transform="rotate(-135)" />
  117. </IconButton>
  118. <IconButton
  119. name={ShapeType.Dot}
  120. size={{ '@initial': 'medium', '@sm': 'small', '@md': 'large' }}
  121. onClick={selectDotTool}
  122. isActive={activeTool === ShapeType.Dot}
  123. >
  124. <DotIcon />
  125. </IconButton> */}
  126. </Container>
  127. <Container>
  128. <Tooltip label="Lock Tool">
  129. <IconButton
  130. size={{ '@initial': 'small', '@sm': 'small', '@md': 'large' }}
  131. onClick={selectToolLock}
  132. >
  133. {isToolLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
  134. </IconButton>
  135. </Tooltip>
  136. {isPenLocked && (
  137. <Tooltip label="Unlock Pen">
  138. <IconButton
  139. size={{ '@initial': 'small', '@sm': 'small', '@md': 'large' }}
  140. onClick={selectToolLock}
  141. >
  142. <Pencil2Icon />
  143. </IconButton>
  144. </Tooltip>
  145. )}
  146. </Container>
  147. </Flex>
  148. <UndoRedo />
  149. </OuterContainer>
  150. )
  151. }
  152. const OuterContainer = styled('div', {
  153. position: 'fixed',
  154. bottom: 40,
  155. left: 0,
  156. right: 0,
  157. padding: '0 8px 12px 8px',
  158. width: '100%',
  159. display: 'flex',
  160. alignItems: 'flex-end',
  161. justifyContent: 'center',
  162. flexWrap: 'wrap',
  163. gap: 16,
  164. zIndex: 200,
  165. })
  166. const Flex = styled('div', {
  167. display: 'flex',
  168. width: '100%',
  169. padding: '0 4px',
  170. justifyContent: 'space-between',
  171. alignItems: 'flex-end',
  172. variants: {
  173. size: {
  174. small: {
  175. width: 'auto',
  176. padding: '0',
  177. justifyContent: 'center',
  178. '& > *:nth-child(n+2)': {
  179. marginLeft: 16,
  180. },
  181. },
  182. },
  183. },
  184. })
  185. const Container = styled('div', {
  186. position: 'relative',
  187. backgroundColor: '$panel',
  188. borderRadius: '4px',
  189. overflow: 'hidden',
  190. border: '1px solid $panel',
  191. pointerEvents: 'all',
  192. userSelect: 'none',
  193. height: '100%',
  194. display: 'flex',
  195. padding: 4,
  196. boxShadow: '0px 2px 4px rgba(0,0,0,.12)',
  197. '& svg': {
  198. strokeWidth: 0,
  199. },
  200. })