Skip to content

Commit

Permalink
Merge pull request #20 from frostoven/dev-reborn
Browse files Browse the repository at this point in the history
Split components into seperate files & clean up
  • Loading branch information
aggregate1166877 authored May 8, 2023
2 parents ff73008 + b9df9e4 commit d1bfd38
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 274 deletions.
24 changes: 24 additions & 0 deletions app/react/components/AxisInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {Segment} from "semantic-ui-react";
import React from "react";

const AxisInfo = ({axisValue, index}) => {
return (
<Segment className="axis-container">
Axis {index}: {axisValue.toFixed(2)}
<div
className="negative-axis-bar"
style={{
height: axisValue >= 0 ? `${axisValue * 50}%` : '0%'
}}
></div>
<div
className="positive-axis-bar"
style={{
height: axisValue < 0 ? `${Math.abs(axisValue) * 50}%` : '0%'
}}
></div>
</Segment>
);
};

export default AxisInfo;
36 changes: 36 additions & 0 deletions app/react/components/ButtonInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {Input, Popup, Segment} from "semantic-ui-react";
import React from "react";

const ButtonInfo = ({button, buttonName, onRenameButtonClick}) => {
return (
<Popup
trigger={
<Segment className="button-container">
{buttonName}: {button.value.toFixed(2)}
<div
className="bar"
style={{height: `${button.value * 100}%`}}
></div>
</Segment>
}
on="click"
hideOnScroll
position="top center"
content={
<div>
<Input
placeholder="Enter new name"
defaultValue={buttonName}
onKeyDown={(e) => {
if (e.key === "Enter") {
onRenameButtonClick(e.target.value);
}
}}
/>
</div>
}
/>
);
};

export default ButtonInfo;
175 changes: 175 additions & 0 deletions app/react/components/ControllerInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React, {useState, useEffect, useRef} from 'react';
import {Segment, Grid, List, Checkbox} from 'semantic-ui-react';
import AxisInfo from "./AxisInfo";
import ButtonInfo from "./ButtonInfo";

// displays information about a specific gamepad
const ControllerInfo = ({ gamepad }) => {
const [buttons, setButtons] = useState([]);
const [axes, setAxes] = useState([]);
const [deadzoneEnabled, setDeadzoneEnabled] = useState(false);
const [deadzoneValue, setDeadzoneValue] = useState(0.15);
const [buttonNames, setButtonNames] = useState(
Array(gamepad?.buttons.length).fill("")
);
const buttonCache = useRef({});
const axisCache = useRef({});

const processGamepadData = () => {
// console.log("processGamepadData called");
if (!gamepad) return;

let buttonChanged = false;

// Process buttons
gamepad.buttons.forEach((button, index) => {
// console.log(`Button ${index}: current value: ${button.value}, cached value: ${buttonCache.current[index]}`);
if (buttonCache.current[index] !== button.value) {
buttonChanged = true;
buttonCache.current[index] = button.value;
}
});

// Process axes (same logic as for buttons)
let axisChanged = false;

gamepad.axes.forEach((axis, index) => {
const axisValue = deadzoneEnabled && Math.abs(axis) < deadzoneValue ? 0 : axis;
// console.log(`Axis ${index}: current value: ${axisValue}, cached value: ${axisCache.current[index]}`);

if (axisCache.current[index] !== axisValue) {
axisChanged = true;
axisCache.current[index] = axisValue;
}
});
};

const handleRenameButtonClick = (index, newName) => {
setButtonNames((prevButtonNames) => {
const newButtonNames = [...prevButtonNames];
newButtonNames[index] = newName;
return newButtonNames;
});
};

const handleDeadzoneToggle = () => {
setDeadzoneEnabled(!deadzoneEnabled);
};

const handleDeadzoneValueChange = (event) => {
const newValue = parseFloat(event.target.value);
if (newValue >= 0 && newValue <= 1) {
setDeadzoneValue(newValue);
}
};

// useEffect hook used to update the buttons and axes state variables
useEffect(() => {
// checks if there is a gamepad connected before updating state variables
if (!gamepad) return;

setButtons([...gamepad.buttons]);
setAxes(
gamepad.axes.map((axis) =>
deadzoneEnabled && Math.abs(axis) < deadzoneValue ? 0 : axis
)
);
processGamepadData();
}, [gamepad, deadzoneEnabled, deadzoneValue]);

// displays message if no gamepad is connected
if (!gamepad) {
return (
<Segment basic>
<p>Press a button or move an analog stick to connect the controller.</p>
</Segment>
);
}

// displays information about buttons, axis and other misc
return (
<Grid stackable>
<Grid.Row>
<Grid.Column>
<List horizontal>
<List.Item>
<Segment>
<h3>Index</h3>
<p>{gamepad.index}</p>
</Segment>
</List.Item>
<List.Item>
<Segment>
<h3>Connected</h3>
<p>{gamepad.connected ? 'Yes' : 'No'}</p>
</Segment>
</List.Item>
<List.Item>
<Segment>
<h3>Timestamp</h3>
<p>{gamepad.timestamp.toFixed(5)}</p>
</Segment>
</List.Item>
</List>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<h3>Buttons</h3>
<List horizontal>
{
buttons.map((button, index) => (
<List.Item key={index}>
<ButtonInfo
button={button}
buttonName={buttonNames[index] || `Button ${index}`}
onRenameButtonClick={(newName) => handleRenameButtonClick(index, newName)}
/>
</List.Item>
))
}
</List>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<h3>Axes</h3>
<List horizontal>
{
axes.map((axis, index) => (
<List.Item key={index}>
<AxisInfo axisValue={axis} index={index}/>
</List.Item>
))
}
</List>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column width={8}>
<Checkbox
toggle
label="Enable Deadzone"
checked={deadzoneEnabled}
onChange={handleDeadzoneToggle}
/>
</Grid.Column>
<Grid.Column width={8}>
<label>
Deadzone Value:
<input
type="number"
min="0"
max="1"
step="0.01"
value={deadzoneValue}
onChange={handleDeadzoneValueChange}
/>
</label>
</Grid.Column>
</Grid.Row>
</Grid>
);
};

export default ControllerInfo;
20 changes: 20 additions & 0 deletions app/react/components/ControllerTabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Menu} from "semantic-ui-react";
import React from "react";

const ControllerTabs = ({panes, activeIndex, setActiveIndex}) => {
return (
<Menu stackable>
{panes.map((pane, index) => (
<Menu.Item
key={index}
active={activeIndex === index}
onClick={() => setActiveIndex(index)}
>
{pane.truncatedTabName}
</Menu.Item>
))}
</Menu>
);
};

export default ControllerTabs;
Loading

0 comments on commit d1bfd38

Please sign in to comment.