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.

shapes-functions.tsx 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import tld from 'utils/tld'
  2. import state, { useSelector } from 'state'
  3. import { IconButton, ButtonsRow, breakpoints } from 'components/shared'
  4. import { memo } from 'react'
  5. import { MoveType, ShapeType } from 'types'
  6. import { Trash2 } from 'react-feather'
  7. import Tooltip from 'components/tooltip'
  8. import {
  9. ArrowDownIcon,
  10. ArrowUpIcon,
  11. AspectRatioIcon,
  12. CopyIcon,
  13. GroupIcon,
  14. LockClosedIcon,
  15. LockOpen1Icon,
  16. PinBottomIcon,
  17. PinTopIcon,
  18. RotateCounterClockwiseIcon,
  19. } from '@radix-ui/react-icons'
  20. import { commandKey } from 'utils'
  21. function handleRotateCcw() {
  22. state.send('ROTATED_CCW')
  23. }
  24. function handleDuplicate() {
  25. state.send('DUPLICATED')
  26. }
  27. function handleGroup() {
  28. state.send('GROUPED')
  29. }
  30. function handleUngroup() {
  31. state.send('UNGROUPED')
  32. }
  33. function handleLock() {
  34. state.send('TOGGLED_SHAPE_LOCK')
  35. }
  36. function handleAspectLock() {
  37. state.send('TOGGLED_SHAPE_ASPECT_LOCK')
  38. }
  39. function handleMoveToBack() {
  40. state.send('MOVED', { type: MoveType.ToBack })
  41. }
  42. function handleMoveBackward() {
  43. state.send('MOVED', { type: MoveType.Backward })
  44. }
  45. function handleMoveForward() {
  46. state.send('MOVED', { type: MoveType.Forward })
  47. }
  48. function handleMoveToFront() {
  49. state.send('MOVED', { type: MoveType.ToFront })
  50. }
  51. function handleDelete() {
  52. state.send('DELETED')
  53. }
  54. function ShapesFunctions() {
  55. const isAllLocked = useSelector((s) => {
  56. const page = tld.getPage(s.data)
  57. return s.values.selectedIds.every((id) => page.shapes[id].isLocked)
  58. })
  59. const isAllAspectLocked = useSelector((s) => {
  60. const page = tld.getPage(s.data)
  61. return s.values.selectedIds.every(
  62. (id) => page.shapes[id].isAspectRatioLocked
  63. )
  64. })
  65. const isAllGrouped = useSelector((s) => {
  66. const selectedShapes = tld.getSelectedShapes(s.data)
  67. return selectedShapes.every(
  68. (shape) =>
  69. shape.type === ShapeType.Group ||
  70. (shape.parentId === selectedShapes[0].parentId &&
  71. selectedShapes[0].parentId !== s.data.currentPageId)
  72. )
  73. })
  74. const hasSelection = useSelector((s) => {
  75. return tld.getSelectedIds(s.data).length > 0
  76. })
  77. const hasMultipleSelection = useSelector((s) => {
  78. return tld.getSelectedIds(s.data).length > 1
  79. })
  80. return (
  81. <>
  82. <ButtonsRow>
  83. <IconButton
  84. bp={breakpoints}
  85. disabled={!hasSelection}
  86. size="small"
  87. onClick={handleDuplicate}
  88. >
  89. <Tooltip label="Duplicate" kbd={`${commandKey()}D`}>
  90. <CopyIcon />
  91. </Tooltip>
  92. </IconButton>
  93. <IconButton
  94. disabled={!hasSelection}
  95. size="small"
  96. onClick={handleRotateCcw}
  97. >
  98. <Tooltip label="Rotate">
  99. <RotateCounterClockwiseIcon />
  100. </Tooltip>
  101. </IconButton>
  102. <IconButton
  103. bp={breakpoints}
  104. disabled={!hasSelection}
  105. size="small"
  106. onClick={handleLock}
  107. >
  108. <Tooltip label="Toogle Locked" kbd={`${commandKey()}L`}>
  109. {isAllLocked ? <LockClosedIcon /> : <LockOpen1Icon opacity={0.4} />}
  110. </Tooltip>
  111. </IconButton>
  112. <IconButton
  113. bp={breakpoints}
  114. disabled={!hasSelection}
  115. size="small"
  116. onClick={handleAspectLock}
  117. >
  118. <Tooltip label="Toogle Aspect Ratio Lock">
  119. <AspectRatioIcon opacity={isAllAspectLocked ? 1 : 0.4} />
  120. </Tooltip>
  121. </IconButton>
  122. <IconButton
  123. bp={breakpoints}
  124. disabled={!isAllGrouped && !hasMultipleSelection}
  125. size="small"
  126. onClick={isAllGrouped ? handleUngroup : handleGroup}
  127. >
  128. <Tooltip label="Group" kbd={`${commandKey()}G`}>
  129. <GroupIcon opacity={isAllGrouped ? 1 : 0.4} />
  130. </Tooltip>
  131. </IconButton>
  132. </ButtonsRow>
  133. <ButtonsRow>
  134. <IconButton
  135. bp={breakpoints}
  136. disabled={!hasSelection}
  137. size="small"
  138. onClick={handleMoveToBack}
  139. >
  140. <Tooltip label="Move to Back" kbd={`${commandKey()}⇧[`}>
  141. <PinBottomIcon />
  142. </Tooltip>
  143. </IconButton>
  144. <IconButton
  145. bp={breakpoints}
  146. disabled={!hasSelection}
  147. size="small"
  148. onClick={handleMoveBackward}
  149. >
  150. <Tooltip label="Move Backward" kbd={`${commandKey()}[`}>
  151. <ArrowDownIcon />
  152. </Tooltip>
  153. </IconButton>
  154. <IconButton
  155. bp={breakpoints}
  156. disabled={!hasSelection}
  157. size="small"
  158. onClick={handleMoveForward}
  159. >
  160. <Tooltip label="Move Forward" kbd={`${commandKey()}]`}>
  161. <ArrowUpIcon />
  162. </Tooltip>
  163. </IconButton>
  164. <IconButton
  165. bp={breakpoints}
  166. disabled={!hasSelection}
  167. size="small"
  168. onClick={handleMoveToFront}
  169. >
  170. <Tooltip label="More to Front" kbd={`${commandKey()}⇧]`}>
  171. <PinTopIcon />
  172. </Tooltip>
  173. </IconButton>
  174. <IconButton
  175. bp={breakpoints}
  176. disabled={!hasSelection}
  177. size="small"
  178. onClick={handleDelete}
  179. >
  180. <Tooltip label="Delete" kbd="⌫">
  181. <Trash2 size="15" />
  182. </Tooltip>
  183. </IconButton>
  184. </ButtonsRow>
  185. </>
  186. )
  187. }
  188. export default memo(ShapesFunctions)