FunctionArea.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import React, { useState } from 'react';
  2. import { Button, Flex, Divider } from 'antd';
  3. import '@/themes/truncateText.css';
  4. import { useDispatch } from 'react-redux';
  5. import { setAction } from '@/states/view/functionAreaSlice';
  6. import { switchToMeasurementPanel, switchToMorePanel, switchToAdvancedProcessingPanel, switchToRectCropPanel, switchToMarkPanel } from '@/states/panelSwitchSliceForView';
  7. import Icon from '@/components/Icon';
  8. import { showNotImplemented } from '@/utils/notificationHelper';
  9. import { useAppSelector } from '@/states/store';
  10. import { useButtonAvailability } from '@/utils/useButtonAvailability';
  11. import { theme } from 'antd';
  12. const { useToken } = theme;
  13. // 有状态按钮列表 - 这些按钮代表持续的状态,不应在执行后清理action
  14. const STATEFUL_BUTTON_ACTIONS = new Set([
  15. 'Adjust Brightness and Contrast',
  16. 'Magnifier',
  17. ]);
  18. const FunctionButton = ({
  19. title,
  20. action,
  21. iconName,
  22. }: {
  23. title: string;
  24. action: string;
  25. iconName: string;
  26. }) => {
  27. const dispatch = useDispatch();
  28. const themeType = useAppSelector((state) => state.theme.themeType);
  29. const activeTools = useAppSelector((state) => state.functionArea.activeTools);
  30. const { disabled } = useButtonAvailability(action);
  31. // 对于有状态按钮,基于工具激活状态;对于无状态按钮,基于action
  32. const isActive = STATEFUL_BUTTON_ACTIONS.has(action)
  33. ? activeTools[action] || false
  34. : false; // 无状态按钮不显示激活状态
  35. const [isHovered, setIsHovered] = useState(false);
  36. const colorPrimary = useToken().token.colorPrimary;
  37. // 根据状态计算Icon的样式
  38. const getIconStyle = () => {
  39. const baseStyle = {
  40. /*控制svg图标的大小,暂时使用这种fontSize方式 */
  41. fontSize: '48px',
  42. };
  43. if (disabled) {
  44. return { ...baseStyle, opacity: 0.4, filter: 'grayscale(1)' };
  45. }
  46. if (isActive) {
  47. return { ...baseStyle, color: colorPrimary };
  48. }
  49. if (isHovered) {
  50. return { ...baseStyle };
  51. }
  52. return { ...baseStyle }; // 默认颜色
  53. };
  54. const handleButtonClick = () => {
  55. if (disabled) {
  56. return;
  57. }
  58. if (action === 'Delete Digital Mask' ||
  59. action === 'Crop Selected Area' ||
  60. ['Image Comparison', 'Zoom Image', 'Reset Cursor', 'Pan', 'Snapshot',
  61. ].includes(action)
  62. ) {
  63. showNotImplemented('');
  64. return;
  65. }
  66. if (action === 'Image Measurement') {
  67. // 切换到测量面板
  68. dispatch(switchToMeasurementPanel());
  69. } else if (action === 'Rectangle Crop') {
  70. // 切换到矩形裁剪面板
  71. dispatch(switchToRectCropPanel());
  72. } else if (action === 'More') {
  73. // 切换到更多功能面板
  74. dispatch(switchToMorePanel());
  75. } else if (action === 'Advanced Processing') {
  76. // 切换到高级图像处理面板
  77. dispatch(switchToAdvancedProcessingPanel());
  78. } else if (action === 'AddMark') {
  79. // 切换到标记面板
  80. dispatch(switchToMarkPanel());
  81. } else {
  82. // 其他功能按钮保持原有逻辑
  83. dispatch(setAction(action));
  84. }
  85. };
  86. return (
  87. <Button
  88. onClick={handleButtonClick}
  89. onMouseEnter={() => setIsHovered(true)}
  90. onMouseLeave={() => setIsHovered(false)}
  91. disabled={disabled}
  92. icon={
  93. <Icon
  94. module="module-process"
  95. name={iconName}
  96. userId="base"
  97. theme="default"
  98. size="2x"
  99. state="normal"
  100. style={getIconStyle()}
  101. className={`text-[${useToken().token.colorPrimary}] `}
  102. />
  103. }
  104. style={{
  105. width: '1.5rem',
  106. height: '1.5rem',
  107. padding: 0, // 关键
  108. border: isHovered ? `1px solid ${colorPrimary}` : '1px solid transparent',
  109. //backgroundColor: isHovered ? `${colorPrimary}` : 'transparent',
  110. //minWidth: 44, // 保险
  111. //overflow: 'hidden', // 超出的文字裁掉
  112. }}
  113. title={disabled ? `${title} (多分格模式下不可用)` : title}
  114. className="truncate-text"
  115. >
  116. {/* {title} */}
  117. </Button>
  118. );
  119. };
  120. const FunctionArea = () => {
  121. return (
  122. <Flex wrap gap="small" align="center" justify="start" className="p-1">
  123. <FunctionButton title="Add L Mark" action="Add L Mark" iconName="LMark" />
  124. <FunctionButton title="Add R Mark" action="Add R Mark" iconName="RMark" />
  125. <FunctionButton title="Add Mark" action="AddMark" iconName="AddMark" />
  126. <FunctionButton
  127. title="Delete Selected Mark"
  128. action="Delete Selected Mark"
  129. iconName="EraseMark"
  130. />
  131. <FunctionButton
  132. title="Horizontal Flip"
  133. action="Horizontal Flip"
  134. iconName="HReverse"
  135. />
  136. <FunctionButton
  137. title="Vertical Flip"
  138. action="Vertical Flip"
  139. iconName="VReverse"
  140. />
  141. <FunctionButton
  142. title="Rotate Counterclockwise 90°"
  143. action="Rotate Counterclockwise 90"
  144. iconName="RotateL90"
  145. />
  146. <FunctionButton
  147. title="Rotate Clockwise 90°"
  148. action="Rotate Clockwise 90"
  149. iconName="RotateR90"
  150. />
  151. <FunctionButton
  152. title="Rotate Any Angle"
  153. action="Rotate Any Angle"
  154. iconName="RotateAnyDegree"
  155. />
  156. <FunctionButton
  157. title="Crop Selected Area"
  158. action="Crop Selected Area"
  159. iconName="Crop"
  160. />
  161. <FunctionButton
  162. title="删除数字遮线框"
  163. action="Delete Digital Mask"
  164. iconName="btn_RemoveCrop"
  165. />
  166. <FunctionButton
  167. title="Adjust Brightness and Contrast"
  168. action="Adjust Brightness and Contrast"
  169. iconName="btn_BrightnessContrast"
  170. />
  171. <FunctionButton
  172. title="Add Mask"
  173. action="Add Mask"
  174. iconName="AddMask"
  175. />
  176. <FunctionButton
  177. title="Delete Mask"
  178. action="Delete Mask"
  179. iconName="DeleteMask"
  180. />
  181. <FunctionButton
  182. title="Image Comparison"
  183. action="Image Comparison"
  184. iconName="btn_Compare"
  185. />
  186. <FunctionButton
  187. title="反色对比"
  188. action="Invert Contrast"
  189. iconName="btn_ReverseColour"
  190. />
  191. <FunctionButton
  192. title="1x1 Layout"
  193. action="1x1 Layout"
  194. iconName="1x1_normal"
  195. />
  196. <FunctionButton
  197. title="1x2 Layout"
  198. action="1x2 Layout"
  199. iconName="1x2_normal"
  200. />
  201. <FunctionButton
  202. title="2x2 Layout"
  203. action="2x2 Layout"
  204. iconName="2x1_normal"
  205. />
  206. <FunctionButton
  207. title="4x4 Layout"
  208. action="4x4 Layout"
  209. iconName="2x2_normal"
  210. />
  211. <FunctionButton
  212. title="Magnifier"
  213. action="Magnifier"
  214. iconName="Magnifier"
  215. />
  216. <FunctionButton
  217. title="Fit Size"
  218. action="Fit Size"
  219. iconName="FitInWindow"
  220. />
  221. <FunctionButton
  222. title="Original Size"
  223. action="Original Size"
  224. iconName="1by1_normal"
  225. />
  226. <FunctionButton title="Zoom Image" action="Zoom Image" iconName="Zoom" />
  227. <FunctionButton
  228. title="Reset Cursor"
  229. action="Reset Cursor"
  230. iconName="btn_pointer"
  231. />
  232. <FunctionButton title="Pan" action="Pan" iconName="Pan" />
  233. <FunctionButton
  234. title="Invert Image"
  235. action="Invert Image"
  236. iconName="Invert"
  237. />
  238. <FunctionButton
  239. title="Reset Image"
  240. action="Reset Image"
  241. iconName="Reset"
  242. />
  243. <FunctionButton
  244. title="Snapshot"
  245. action="Snapshot"
  246. iconName="imgsnapshot"
  247. />
  248. <Divider type="horizontal" style={{ height: 'auto', margin: '8px' }} />
  249. <FunctionButton
  250. title="Advanced Processing"
  251. action="Advanced Processing"
  252. iconName="btn_Imageprocess"
  253. />
  254. <FunctionButton
  255. title="Image Measurement"
  256. action="Image Measurement"
  257. iconName="btn_Measurements"
  258. />
  259. <FunctionButton
  260. title="矩形裁剪"
  261. action="Rectangle Crop"
  262. iconName="rectangle-crop"
  263. />
  264. <FunctionButton title="More" action="More" iconName="btn_OtherSetting" />
  265. </Flex>
  266. );
  267. };
  268. export default FunctionArea;