mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-07 08:53:25 +01:00
improve history timeline scroll
This commit is contained in:
parent
b8053c5e25
commit
6f95b5ae80
8 changed files with 160 additions and 36 deletions
|
|
@ -14,9 +14,17 @@ import {EMPTY_OBJECT} from '../../../../../modules/gems/objects';
|
|||
import {VIEWER_SELECTOR} from '../../dom/components/View3d';
|
||||
import {aboveElement} from '../../../../../modules/ui/positionUtils';
|
||||
|
||||
function HistoryTimeline({history, pointer, setHistoryPointer, remove, getOperation}) {
|
||||
return <div className={ls.root}>
|
||||
<Controls pointer={pointer} eoh={history.length-1} setHistoryPointer={setHistoryPointer}/>
|
||||
|
||||
|
||||
class HistoryTimeline extends React.Component {
|
||||
|
||||
render() {
|
||||
let {history, pointer, setHistoryPointer, remove, getOperation} = this.props;
|
||||
let scrolly;
|
||||
return <div className={ls.root} ref={this.keepRef}>
|
||||
<Controls pointer={pointer} eoh={history.length-1} setHistoryPointer={this.setHistoryPointerAndRequestScroll}/>
|
||||
<div className={ls.scroller} onClick={e => scrolly.scrollLeft -= 60}><Fa icon='caret-left'/></div>
|
||||
<div className={ls.history} ref={el => scrolly = el}>
|
||||
{history.map((m, i) => <React.Fragment key={i}>
|
||||
<Timesplitter active={i-1 === pointer} onClick={() => setHistoryPointer(i-1)} />
|
||||
<HistoryItem index={i} modification={m} getOperation={getOperation}
|
||||
|
|
@ -24,11 +32,36 @@ function HistoryTimeline({history, pointer, setHistoryPointer, remove, getOperat
|
|||
inProgress={pointer === i-1} />
|
||||
</React.Fragment>)}
|
||||
<Timesplitter eoh active={history.length-1 === pointer} onClick={() => setHistoryPointer(history.length-1)}/>
|
||||
</div>
|
||||
<div className={ls.scroller} onClick={e => scrolly.scrollLeft += 60}><Fa icon='caret-right'/></div>
|
||||
<InProgressOperation getOperation={getOperation}/>
|
||||
<AddButton />
|
||||
</div>;
|
||||
}
|
||||
|
||||
// scrollInProgressToVisibleRequest = false;
|
||||
|
||||
setHistoryPointerAndRequestScroll = (pointer) => {
|
||||
// this.scrollInProgressToVisibleRequest = true;
|
||||
this.props.setHistoryPointer(pointer);
|
||||
};
|
||||
|
||||
keepRef = el => this.el = el;
|
||||
|
||||
componentDidUpdate() {
|
||||
// this.scrollInProgressToVisibleRequest = false;
|
||||
setTimeout(() => {
|
||||
let item = this.el.querySelector(`.${ls.historyItem}.${ls.inProgress}`);
|
||||
if (item) {
|
||||
item.scrollIntoView({behavior: "smooth", inline: "center"});
|
||||
} else {
|
||||
let history = this.el.querySelector(`.${ls.history}`);
|
||||
history.scrollLeft = history.scrollWidth;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const InProgressOperation = connect(streams => streams.wizard.map(wizard => ({wizard})))(
|
||||
function InProgressOperation({wizard, getOperation}) {
|
||||
if (!wizard) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
.root {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
height: 34px;
|
||||
|
||||
align-items: flex-end;
|
||||
height: 48px;
|
||||
//&:hover .timesplitter .handlePoly {
|
||||
// visibility: visible;
|
||||
//}
|
||||
|
|
@ -14,13 +15,37 @@
|
|||
width: 4px;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
align-items: flex-end;
|
||||
.handle {
|
||||
margin-top: -15px;
|
||||
//margin-top: -15px;
|
||||
margin-left: -4px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.history {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.scroller {
|
||||
padding: 0 5px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #BFBFBF;
|
||||
}
|
||||
&:active {
|
||||
background-color: #7e7e7e;
|
||||
transition: 100ms;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.timesplitter.active:not(.eoh) {
|
||||
background-color: #ff940b;
|
||||
|
||||
|
|
@ -50,6 +75,8 @@
|
|||
//ITEMS
|
||||
|
||||
.item {
|
||||
height: 30px;
|
||||
flex-shrink: 0;
|
||||
margin: 2px 0;
|
||||
padding: 2px;
|
||||
border: #2e2e2e 1px solid;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
background-color: #780000;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
& .buttons {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
.buttons {
|
||||
display: none;
|
||||
font-size: 13px;
|
||||
margin-left: auto;
|
||||
& > * {
|
||||
padding: 0 3px;
|
||||
&.danger:hover {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import decoratorChain from '../../../../../modules/ui/decoratorChain';
|
|||
import {combine, merger} from '../../../../../modules/lstream';
|
||||
import ls from './SelectedModificationInfo.less';
|
||||
import ImgIcon from 'ui/components/ImgIcon';
|
||||
import YAML from 'yamljs';
|
||||
import mapContext from 'ui/mapContext';
|
||||
import {EMPTY_OBJECT} from '../../../../../modules/gems/objects';
|
||||
import ButtonGroup from '../../../../../modules/ui/components/controls/ButtonGroup';
|
||||
|
|
|
|||
|
|
@ -1,16 +1,45 @@
|
|||
import React, {Fragment} from 'react';
|
||||
import React from 'react';
|
||||
import ObjectExplorer from '../../craft/ui/ObjectExplorer';
|
||||
import OperationHistory from '../../craft/ui/OperationHistory';
|
||||
import Folder from 'ui/components/Folder';
|
||||
import Fa from '../../../../../modules/ui/components/Fa';
|
||||
import ls from './FloatView.less';
|
||||
import cx from 'classnames';
|
||||
|
||||
export default function FloatView() {
|
||||
return <Fragment>
|
||||
<Folder title={<span> <Fa fw icon='cubes' /> Model</span>}>
|
||||
export default class FloatView extends React.Component {
|
||||
|
||||
state = {
|
||||
selected: null
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div className={ls.root}>
|
||||
<div className={ls.tabs}>
|
||||
{['project', 'history'].map(tabId => <Tab selected={this.state.selected === tabId} key={tabId}
|
||||
onClick={() => this.setState({selected: this.state.selected === tabId ? null : tabId})}>{getIcon(tabId)}</Tab>)}
|
||||
</div>
|
||||
|
||||
{this.state.selected && <div className={ls.main}>
|
||||
{this.state.selected === 'project' && <Folder title={<span> <Fa fw icon='cubes'/> Model</span>}>
|
||||
<ObjectExplorer/>
|
||||
</Folder>
|
||||
<Folder title={<span> <Fa fw icon='history' /> Modifications</span>}>
|
||||
</Folder>}
|
||||
{this.state.selected === 'history' && <Folder title={<span> <Fa fw icon='history'/> Modifications</span>}>
|
||||
<OperationHistory/>
|
||||
</Folder>
|
||||
</Fragment>;
|
||||
</Folder>}
|
||||
|
||||
</div>}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
function Tab({children, selected, onClick}) {
|
||||
return <div className={cx(ls.tab, selected && ls.selected)} onClick={onClick}>{children}</div>;
|
||||
}
|
||||
|
||||
function getIcon(id) {
|
||||
if (id === 'history') {
|
||||
return <Fa fw icon='history'/>;
|
||||
} else if (id === 'project') {
|
||||
return <Fa fw icon='file-o'/>;
|
||||
}
|
||||
}
|
||||
42
web/app/cad/dom/components/FloatView.less
Normal file
42
web/app/cad/dom/components/FloatView.less
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
@import "~ui/styles/theme.less";
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
position: relative;
|
||||
border-right: 1px solid @border-color;
|
||||
background-color: @bg-color-alt;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 235px;
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.tab {
|
||||
|
||||
border: 1px solid @bg-color;
|
||||
margin: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
padding: 5px 2px;
|
||||
cursor: pointer;
|
||||
background-color: @bg-color;
|
||||
|
||||
&:hover {
|
||||
background-color: #9c9c9c !important;
|
||||
}
|
||||
&:active {
|
||||
transition: 200ms;
|
||||
background-color: #BFBFBF !important;
|
||||
}
|
||||
&.selected {
|
||||
background-color: #7d7d7d;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,9 +20,7 @@ export default class View3d extends React.Component {
|
|||
|
||||
render() {
|
||||
return <UISystem className={ls.root}>
|
||||
<div className={ls.sideBar}>
|
||||
<FloatView />
|
||||
</div>
|
||||
<div className={ls.viewer} id='viewer-container'>
|
||||
<Abs left='0.8em' top='0.8em'>
|
||||
<HeadsUpToolbar/>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,3 @@
|
|||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sideBar {
|
||||
flex-basis: 250px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue