|
@@ -14,7 +14,16 @@
|
|
|
@mousedown="$event => handleMousedownColHandler($event, index)"
|
|
@mousedown="$event => handleMousedownColHandler($event, index)"
|
|
|
></div>
|
|
></div>
|
|
|
</div>
|
|
</div>
|
|
|
- <table>
|
|
|
|
|
|
|
+ <table
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ 'theme': theme,
|
|
|
|
|
+ 'row-header': theme?.rowHeader,
|
|
|
|
|
+ 'row-footer': theme?.rowFooter,
|
|
|
|
|
+ 'col-header': theme?.colHeader,
|
|
|
|
|
+ 'col-footer': theme?.colFooter,
|
|
|
|
|
+ }"
|
|
|
|
|
+ :style="`--themeColor: ${theme?.color}; --subThemeColor1: ${subThemeColor[0]}; --subThemeColor2: ${subThemeColor[1]}`"
|
|
|
|
|
+ >
|
|
|
<colgroup>
|
|
<colgroup>
|
|
|
<col span="1" v-for="(width, index) in colSizeList" :key="index" :width="width">
|
|
<col span="1" v-for="(width, index) in colSizeList" :key="index" :width="width">
|
|
|
</colgroup>
|
|
</colgroup>
|
|
@@ -33,6 +42,7 @@
|
|
|
borderStyle: outline.style,
|
|
borderStyle: outline.style,
|
|
|
borderColor: outline.color,
|
|
borderColor: outline.color,
|
|
|
borderWidth: outline.width + 'px',
|
|
borderWidth: outline.width + 'px',
|
|
|
|
|
+ ...getTextStyle(cell.style),
|
|
|
}"
|
|
}"
|
|
|
v-for="(cell, colIndex) in rowCells"
|
|
v-for="(cell, colIndex) in rowCells"
|
|
|
:key="cell.id"
|
|
:key="cell.id"
|
|
@@ -61,7 +71,8 @@
|
|
|
<script lang="ts">
|
|
<script lang="ts">
|
|
|
import { computed, defineComponent, nextTick, onMounted, onUnmounted, PropType, ref, watch } from 'vue'
|
|
import { computed, defineComponent, nextTick, onMounted, onUnmounted, PropType, ref, watch } from 'vue'
|
|
|
import debounce from 'lodash/debounce'
|
|
import debounce from 'lodash/debounce'
|
|
|
-import { PPTElementOutline, TableCell } from '@/types/slides'
|
|
|
|
|
|
|
+import tinycolor from 'tinycolor2'
|
|
|
|
|
+import { PPTElementOutline, TableCell, TableCellStyle, TableTheme } from '@/types/slides'
|
|
|
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
|
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
|
|
import { KEYS } from '@/configs/hotkey'
|
|
import { KEYS } from '@/configs/hotkey'
|
|
|
import { createRandomCode } from '@/utils/common'
|
|
import { createRandomCode } from '@/utils/common'
|
|
@@ -92,6 +103,9 @@ export default defineComponent({
|
|
|
type: Object as PropType<PPTElementOutline>,
|
|
type: Object as PropType<PPTElementOutline>,
|
|
|
required: true,
|
|
required: true,
|
|
|
},
|
|
},
|
|
|
|
|
+ theme: {
|
|
|
|
|
+ type: Object as PropType<TableTheme>,
|
|
|
|
|
+ },
|
|
|
editable: {
|
|
editable: {
|
|
|
type: Boolean,
|
|
type: Boolean,
|
|
|
default: true,
|
|
default: true,
|
|
@@ -101,6 +115,19 @@ export default defineComponent({
|
|
|
const store = useStore<State>()
|
|
const store = useStore<State>()
|
|
|
const canvasScale = computed(() => store.state.canvasScale)
|
|
const canvasScale = computed(() => store.state.canvasScale)
|
|
|
|
|
|
|
|
|
|
+ const subThemeColor = ref(['', ''])
|
|
|
|
|
+ watch(() => props.theme, () => {
|
|
|
|
|
+ if(props.theme) {
|
|
|
|
|
+ const rgba = tinycolor(props.theme.color).toRgb()
|
|
|
|
|
+ const subRgba1 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.3 }
|
|
|
|
|
+ const subRgba2 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.1 }
|
|
|
|
|
+ subThemeColor.value = [
|
|
|
|
|
+ `rgba(${[subRgba1.r, subRgba1.g, subRgba1.b, subRgba1.a].join(',')})`,
|
|
|
|
|
+ `rgba(${[subRgba2.r, subRgba2.g, subRgba2.b, subRgba2.a].join(',')})`,
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ }, { immediate: true })
|
|
|
|
|
+
|
|
|
const tableCells = computed<TableCell[][]>({
|
|
const tableCells = computed<TableCell[][]>({
|
|
|
get() {
|
|
get() {
|
|
|
return props.data
|
|
return props.data
|
|
@@ -187,6 +214,10 @@ export default defineComponent({
|
|
|
return selectedCells
|
|
return selectedCells
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ watch(selectedCells, () => {
|
|
|
|
|
+ emit('changeSelectedCells', selectedCells.value)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
const activedCell = computed(() => {
|
|
const activedCell = computed(() => {
|
|
|
if(selectedCells.value.length > 1) return null
|
|
if(selectedCells.value.length > 1) return null
|
|
|
return selectedCells.value[0]
|
|
return selectedCells.value[0]
|
|
@@ -446,6 +477,36 @@ export default defineComponent({
|
|
|
document.removeEventListener('keydown', keydownListener)
|
|
document.removeEventListener('keydown', keydownListener)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ const getTextStyle = (style?: TableCellStyle) => {
|
|
|
|
|
+ if(!style) return {}
|
|
|
|
|
+ const {
|
|
|
|
|
+ bold,
|
|
|
|
|
+ em,
|
|
|
|
|
+ underline,
|
|
|
|
|
+ strikethrough,
|
|
|
|
|
+ color,
|
|
|
|
|
+ backcolor,
|
|
|
|
|
+ fontsize,
|
|
|
|
|
+ fontname,
|
|
|
|
|
+ align,
|
|
|
|
|
+ } = style
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ fontWeight: bold ? 'bold' : 'normal',
|
|
|
|
|
+ fontStyle: em ? 'italic' : 'normal',
|
|
|
|
|
+ textDecoration: `${underline ? 'underline' : ''} ${strikethrough ? 'line-through' : ''}`,
|
|
|
|
|
+ color: color || '#000',
|
|
|
|
|
+ backgroundColor: backcolor || '',
|
|
|
|
|
+ fontSize: fontsize || '14px',
|
|
|
|
|
+ fontFamily: fontname || '微软雅黑',
|
|
|
|
|
+ textAlign: align || 'left',
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const handleInput = debounce(function() {
|
|
|
|
|
+ emit('change', tableCells.value)
|
|
|
|
|
+ }, 300, { trailing: true })
|
|
|
|
|
+
|
|
|
const getEffectiveTableCells = () => {
|
|
const getEffectiveTableCells = () => {
|
|
|
const effectiveTableCells = []
|
|
const effectiveTableCells = []
|
|
|
|
|
|
|
@@ -532,11 +593,8 @@ export default defineComponent({
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const handleInput = debounce(function() {
|
|
|
|
|
- emit('change', tableCells.value)
|
|
|
|
|
- }, 300, { trailing: true })
|
|
|
|
|
-
|
|
|
|
|
return {
|
|
return {
|
|
|
|
|
+ getTextStyle,
|
|
|
dragLinePosition,
|
|
dragLinePosition,
|
|
|
tableCells,
|
|
tableCells,
|
|
|
colSizeList,
|
|
colSizeList,
|
|
@@ -552,6 +610,7 @@ export default defineComponent({
|
|
|
handleMousedownColHandler,
|
|
handleMousedownColHandler,
|
|
|
contextmenus,
|
|
contextmenus,
|
|
|
handleInput,
|
|
handleInput,
|
|
|
|
|
+ subThemeColor,
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
@@ -572,6 +631,40 @@ table {
|
|
|
word-wrap: break-word;
|
|
word-wrap: break-word;
|
|
|
user-select: none;
|
|
user-select: none;
|
|
|
|
|
|
|
|
|
|
+ --themeColor: $themeColor;
|
|
|
|
|
+ --subThemeColor1: $themeColor;
|
|
|
|
|
+ --subThemeColor2: $themeColor;
|
|
|
|
|
+
|
|
|
|
|
+ &.theme {
|
|
|
|
|
+ tr:nth-child(2n) .cell {
|
|
|
|
|
+ background-color: var(--subThemeColor1);
|
|
|
|
|
+ }
|
|
|
|
|
+ tr:nth-child(2n + 1) .cell {
|
|
|
|
|
+ background-color: var(--subThemeColor2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.row-header {
|
|
|
|
|
+ tr:first-child .cell {
|
|
|
|
|
+ background-color: var(--themeColor);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ &.row-footer {
|
|
|
|
|
+ tr:last-child .cell {
|
|
|
|
|
+ background-color: var(--themeColor);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ &.col-header {
|
|
|
|
|
+ tr .cell:first-child {
|
|
|
|
|
+ background-color: var(--themeColor);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ &.col-footer {
|
|
|
|
|
+ tr .cell:last-child {
|
|
|
|
|
+ background-color: var(--themeColor);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
tr {
|
|
tr {
|
|
|
height: 36px;
|
|
height: 36px;
|
|
|
}
|
|
}
|
|
@@ -581,6 +674,7 @@ table {
|
|
|
white-space: normal;
|
|
white-space: normal;
|
|
|
word-wrap: break-word;
|
|
word-wrap: break-word;
|
|
|
vertical-align: middle;
|
|
vertical-align: middle;
|
|
|
|
|
+ font-size: 14px;
|
|
|
cursor: default;
|
|
cursor: default;
|
|
|
|
|
|
|
|
&.selected::after {
|
|
&.selected::after {
|
|
@@ -590,7 +684,7 @@ table {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 0;
|
|
top: 0;
|
|
|
left: 0;
|
|
left: 0;
|
|
|
- background-color: rgba($color: #888, $alpha: .1);
|
|
|
|
|
|
|
+ background-color: rgba($color: $themeColor, $alpha: .3);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -600,7 +694,6 @@ table {
|
|
|
border: 0;
|
|
border: 0;
|
|
|
outline: 0;
|
|
outline: 0;
|
|
|
line-height: 1.5;
|
|
line-height: 1.5;
|
|
|
- font-size: 14px;
|
|
|
|
|
user-select: none;
|
|
user-select: none;
|
|
|
cursor: text;
|
|
cursor: text;
|
|
|
|
|
|