Skip to content

Commit

Permalink
reimplement the tilemap palette page controls
Browse files Browse the repository at this point in the history
  • Loading branch information
riknoll committed Dec 11, 2024
1 parent 06fde1b commit e1864b4
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 70 deletions.
62 changes: 62 additions & 0 deletions react-common/components/controls/CarouselNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { classList } from "../util";
import { Button } from "./Button";

export interface CarouselNavProps {
pages: number;
selected: number;
maxDisplayed?: number;
onPageSelected: (page: number) => void;
}

export const CarouselNav = (props: CarouselNavProps) => {
const { pages, selected, maxDisplayed, onPageSelected } = props;

const displayedPages: number[] = [];
let start = 0;
let end = pages;

if (maxDisplayed) {
start = Math.min(
Math.max(0, selected - (maxDisplayed >> 1)),
Math.max(0, start + pages - maxDisplayed)
);
end = Math.min(start + maxDisplayed, pages);
}

for (let i = start; i < end; i++) {
displayedPages.push(i);
}

return (
<div className="common-carousel-nav">
<Button
className="common-carousel-nav-arrow"
title={lf("Previous page")}
leftIcon="fas fa-chevron-circle-left"
onClick={() => onPageSelected(selected - 1)}
disabled={selected === 0}
/>
<ul className="common-carousel-nav">
{displayedPages.map(page =>
<li key={page} onClick={() => onPageSelected(page)}>
<Button
className={classList(selected === page && "selected")}
title={lf("Jump to page {0}", page + 1)}
onClick={() => onPageSelected(page)}
label={
<span className="common-carousel-nav-button-handle" />
}
/>
</li>
)}
</ul>
<Button
className="common-carousel-nav-arrow"
title={lf("Next page")}
leftIcon="fas fa-chevron-circle-right"
onClick={() => onPageSelected(selected + 1)}
disabled={selected === pages - 1}
/>
</div>
)
}
77 changes: 77 additions & 0 deletions react-common/styles/controls/CarouselNav.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.common-carousel-nav {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;

.common-carousel-nav-arrow {
min-height: 1rem;
min-width: 1rem;
padding: 0;
background: none;
color: white;
width: 1.25rem;
height: 1.25rem;

margin: 0;

i.fas {
width: 1.25rem;
}

&.disabled {
opacity: 0.5;
}
}

ul {
list-style: none;
margin: 0;
margin-left: 0.125rem;
margin-right: 0.125rem;
margin-block: 0;
padding-inline: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 1.25rem;
}

li {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 1rem;
width: 1rem;

.common-button {
width: 1rem;
height: 1rem;
padding: 0.3rem;
background: none;

.common-carousel-nav-button-handle {
background-color: white;
border-radius: 100%;
height: 0.4rem;
width: 0.4rem;
display: block;
}

&.selected {
padding: 0.125rem;

.common-carousel-nav-button-handle {
height: 0.75rem;
width: 0.75rem;
}
}
}
}

.common-button:focus-visible::after {
inset: -1px;
}
}
1 change: 1 addition & 0 deletions react-common/styles/react-common.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
@import "controls/VerticalResizeContainer.less";
@import "controls/VerticalSlider.less";
@import "controls/Accordion.less";
@import "controls/CarouselNav.less";
@import "./react-common-variables.less";

@import "fontawesome-free/less/solid.less";
Expand Down
68 changes: 29 additions & 39 deletions theme/image-editor/tilePalette.less
Original file line number Diff line number Diff line change
Expand Up @@ -105,45 +105,7 @@
.tile-canvas-controls {
width: 100%;
text-align: center;
margin-top: -0.5rem;
}

.tile-palette-pages {
height: 1.75rem;
display: inline-block;
}

.tile-palette-page-arrow {
fill: var(--sidebar-icon-inactive-color);
stroke: var(--sidebar-icon-inactive-color);
stroke-linejoin: round;
cursor: pointer;

transition: fill 0.1s, stroke 0.1s;
}

.tile-palette-page-dot {
fill: var(--sidebar-icon-inactive-color);
cursor: pointer;
transition: fill 0.1s;
}

.tile-palette-pages:not(.disabled) {
.tile-palette-page-arrow:hover {
fill: var(--sidebar-icon-active-color);
stroke: var(--sidebar-icon-active-color);
}

.tile-palette-page-dot:hover {
fill: var(--sidebar-icon-active-color);
}
}

.tile-palette-pages.disabled {
.tile-palette-page-arrow,
.tile-palette-page-dot {
opacity: 0.5;
}
margin-top: -0.25rem;
}

.tile-canvas {
Expand Down Expand Up @@ -173,6 +135,34 @@
height: 2rem;
}

.tile-canvas-controls .common-carousel-nav {
.common-carousel-nav-arrow {
color: var(--sidebar-icon-inactive-color);
transition: color 0.1s;

&:hover {
color: var(--sidebar-icon-active-color);
filter: none;
}
}

li .common-button {
.common-carousel-nav-button-handle {
background-color: var(--sidebar-icon-inactive-color);
transition: background-color 0.1s;
}

&:hover {
filter: none;

.common-carousel-nav-button-handle {
background-color: var(--sidebar-icon-active-color);
}
}
}
}



@media screen and (max-height: 720px) {
.image-editor-tilemap-minimap {
Expand Down
39 changes: 8 additions & 31 deletions webapp/src/components/ImageEditor/tilemap/TilePalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { IconButton } from '../Button';
import { AlertOption } from '../Alert';
import { createTile } from '../../../assets';

import { CarouselNav } from "../../../../../react-common/components/controls/CarouselNav";

export interface TilePaletteProps {
colors: string[];
tileset: pxt.TileSet;
Expand Down Expand Up @@ -235,7 +237,12 @@ class TilePaletteImpl extends React.Component<TilePaletteProps,{}> {
}
</div>
<div className="tile-canvas-controls">
{ pageControls(totalPages, page, this.pageHandler) }
<CarouselNav
selected={page}
pages={totalPages}
onPageSelected={this.pageHandler}
maxDisplayed={5}
/>
</div>
</div>
</div>;
Expand Down Expand Up @@ -512,36 +519,6 @@ class TilePaletteImpl extends React.Component<TilePaletteProps,{}> {
}
}


function pageControls(pages: number, selected: number, onClick: (index: number) => void) {
const width = 16 + (pages - 1) * 5;
const pageMap: boolean[] = [];
for (let i = 0; i < pages; i++) pageMap[i] = i === selected;

return <svg xmlns="http://www.w3.org/2000/svg" viewBox={`0 0 ${width} 10`} className={`tile-palette-pages ${pages < 2 ? 'disabled' : ''}`}>
<polygon
className="tile-palette-page-arrow"
points="1,5 4,3 4,7"
onClick={selected ? () => onClick(selected - 1) : undefined} />
{
pageMap.map((isSelected, index) =>
<circle
className="tile-palette-page-dot"
key={index}
cx={8 + index * 5}
cy="5"
r={isSelected ? 2 : 1}
onClick={!isSelected ? () => onClick(index) : undefined}/>
)
}
<polygon
className="tile-palette-page-arrow"
points={`${width - 1},5 ${width - 4},3 ${width - 4},7`}
onClick={(selected < pages - 1) ? () => onClick(selected + 1) : undefined} />
</svg>
}


function mapStateToProps({ store: { present }, editor }: ImageEditorStore, ownProps: any) {
let state = (present as TilemapState);
if (!state) return {};
Expand Down

0 comments on commit e1864b4

Please sign in to comment.