Add javadoc to buttons

This commit is contained in:
Felix Koppe
2024-12-01 13:56:45 +01:00
parent c3ad8fe79a
commit 6758abd60e
12 changed files with 682 additions and 71 deletions

View File

@@ -57,7 +57,7 @@ public void simpleInitApp() {
gameView = new GameView(this); gameView = new GameView(this);
ceremonyView = new CeremonyView(this); ceremonyView = new CeremonyView(this);
enter(MdgaState.LOBBY); enter(MdgaState.MAIN);
} }
@Override @Override

View File

@@ -7,34 +7,117 @@
import com.jme3.ui.Picture; import com.jme3.ui.Picture;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents an abstract base class for creating customizable button components in a graphical user interface.
* This class provides the framework for rendering buttons with different visual states, such as normal and pressed,
* and supports position adjustments and font customization.
*
* <p>Subclasses must implement the {@link #show()} and {@link #hide()} methods to define how the button
* is displayed and hidden in the application.</p>
*/
public abstract class AbstractButton { public abstract class AbstractButton {
/**
* Color representing the normal state of the button.
*/
public static final ColorRGBA BUTTON_NORMAL = ColorRGBA.fromRGBA255(233, 236, 239, 255); public static final ColorRGBA BUTTON_NORMAL = ColorRGBA.fromRGBA255(233, 236, 239, 255);
/**
* Color representing the pressed state of the button.
*/
public static final ColorRGBA BUTTON_PRESSED = ColorRGBA.fromRGBA255(105, 117, 89, 255); public static final ColorRGBA BUTTON_PRESSED = ColorRGBA.fromRGBA255(105, 117, 89, 255);
/**
* Color representing the normal state of the button text.
*/
public static final ColorRGBA TEXT_NORMAL = ColorRGBA.Black; public static final ColorRGBA TEXT_NORMAL = ColorRGBA.Black;
/**
* Color representing the pressed state of the button text.
*/
public static final ColorRGBA TEXT_PRESSED = ColorRGBA.fromRGBA255(180, 195, 191, 255); public static final ColorRGBA TEXT_PRESSED = ColorRGBA.fromRGBA255(180, 195, 191, 255);
/**
* The image representing the normal state of the button.
*/
protected Picture pictureNormal = new Picture("normalButton"); protected Picture pictureNormal = new Picture("normalButton");
/**
* The image representing the hover state of the button.
*/
protected Picture pictureHover = new Picture("normalButton"); protected Picture pictureHover = new Picture("normalButton");
/**
* The number of horizontal divisions for calculating relative sizes.
*/
public static final float HORIZONTAL = 16; public static final float HORIZONTAL = 16;
/**
* The number of vertical divisions for calculating relative sizes.
*/
public static final float VERTICAL = 9; public static final float VERTICAL = 9;
/**
* The font used for rendering text on the button.
*/
protected BitmapFont font; protected BitmapFont font;
/**
* Reference to the application instance for accessing assets and settings.
*/
protected final MdgaApp app; protected final MdgaApp app;
/**
* Node in the scene graph to which the button belongs.
*/
protected final Node node; protected final Node node;
/**
* The position of the button in 2D space.
*/
protected Vector2f pos; protected Vector2f pos;
/**
* Factor for scaling the font size.
*/
protected float fontSizeFactor = 1.0f; protected float fontSizeFactor = 1.0f;
/**
* Computed font size based on scaling factor and screen dimensions.
*/
protected float fontSize; protected float fontSize;
/**
* Computed horizontal step size based on screen dimensions.
*/
protected float horizontalStep; protected float horizontalStep;
/**
* Computed vertical step size based on screen dimensions.
*/
protected float verticalStep; protected float verticalStep;
/**
* Computed height step size based on vertical steps.
*/
protected float heightStep; protected float heightStep;
/**
* Computed width step size based on horizontal steps.
*/
protected float widthStep; protected float widthStep;
/**
* Flag indicating whether adjustments are applied to the button.
*/
protected boolean adjust = false; protected boolean adjust = false;
/**
* Constructs an AbstractButton instance with the specified application context and scene node.
* Initializes the button's visual elements and font.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button is attached
*/
public AbstractButton(MdgaApp app, Node node) { public AbstractButton(MdgaApp app, Node node) {
this.app = app; this.app = app;
this.node = node; this.node = node;
@@ -45,13 +128,28 @@ public AbstractButton(MdgaApp app, Node node) {
font = app.getAssetManager().loadFont("Fonts/Gunplay.fnt"); font = app.getAssetManager().loadFont("Fonts/Gunplay.fnt");
} }
/**
* Displays the button. Implementation must define how the button is rendered on the screen.
*/
public abstract void show(); public abstract void show();
/**
* Hides the button. Implementation must define how the button is removed from the screen.
*/
public abstract void hide(); public abstract void hide();
/**
* Sets the position of the button in 2D space.
*
* @param pos the position to set
*/
public void setPos(Vector2f pos) { public void setPos(Vector2f pos) {
this.pos = pos; this.pos = pos;
} }
/**
* Calculates relative sizes and dimensions for the button based on the screen resolution.
*/
protected void calculateRelative() { protected void calculateRelative() {
fontSize = fontSizeFactor * 15 * (float) app.getCamera().getWidth() / 720; fontSize = fontSizeFactor * 15 * (float) app.getCamera().getWidth() / 720;

View File

@@ -5,18 +5,42 @@
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import com.jme3.ui.Picture; import com.jme3.ui.Picture;
/**
* Represents a specific implementation of a clickable button positioned on the left side.
* This class extends {@link ClickButton} and provides a predefined position and size for the button.
* It also includes placeholder methods for handling hover events, which can be customized as needed.
*/
public class ButtonLeft extends ClickButton { public class ButtonLeft extends ClickButton {
/**
* Constructs a ButtonLeft instance with the specified properties.
*
* @param app the application instance for accessing resources and settings
* @param node the node in the scene graph to which the button belongs
* @param action the action to execute when the button is clicked
* @param label the text label to display on the button
* @param narrowFactor a factor to adjust position of the button
*/
public ButtonLeft(MdgaApp app, Node node, Runnable action, String label, int narrowFactor) { public ButtonLeft(MdgaApp app, Node node, Runnable action, String label, int narrowFactor) {
super(app, node, action, label, new Vector2f(5, 2), new Vector2f(0.5f * narrowFactor, 1.8f)); super(app, node, action, label, new Vector2f(5, 2), new Vector2f(0.5f * narrowFactor, 1.8f));
} }
/**
* Called when the button is hovered over by the pointer.
* Subclasses can override this method to define specific hover behavior.
*/
@Override @Override
public void onHover() { public void onHover() {
// Placeholder for hover behavior
} }
/**
* Called when the pointer stops hovering over the button.
* Subclasses can override this method to define specific unhover behavior.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
// Placeholder for unhover behavior
}
}
}
}

View File

@@ -4,20 +4,45 @@
import com.jme3.scene.Node; import com.jme3.scene.Node;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents a specific implementation of a clickable button positioned on the right side.
* This class extends {@link ClickButton} and provides a predefined position and size for the button.
* It includes placeholder methods for handling hover events, which can be customized as needed.
*/
public class ButtonRight extends ClickButton { public class ButtonRight extends ClickButton {
/**
* Constructs a ButtonRight instance with the specified properties.
*
* @param app the application instance for accessing resources and settings
* @param node the node in the scene graph to which the button belongs
* @param action the action to execute when the button is clicked
* @param label the text label to display on the button
* @param narrowFactor a factor to adjust the position of the button
*/
public ButtonRight(MdgaApp app, Node node, Runnable action, String label, int narrowFactor) { public ButtonRight(MdgaApp app, Node node, Runnable action, String label, int narrowFactor) {
super(app, node, action, label, new Vector2f(5, 2), new Vector2f(HORIZONTAL - 0.5f * narrowFactor, 1.8f)); super(app, node, action, label, new Vector2f(5, 2), new Vector2f(HORIZONTAL - 0.5f * narrowFactor, 1.8f));
// Enable adjustments specific to this button
adjust = true; adjust = true;
} }
/**
* Called when the button is hovered over by the pointer.
* Subclasses can override this method to define specific hover behavior.
*/
@Override @Override
public void onHover() { public void onHover() {
// Placeholder for hover behavior
} }
/**
* Called when the pointer stops hovering over the button.
* Subclasses can override this method to define specific unhover behavior.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
// Placeholder for unhover behavior
}
}
}
}

View File

@@ -13,7 +13,16 @@
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.game.Color; import pp.mdga.game.Color;
/**
* Represents a button used in a ceremony screen, with 3D model integration, customizable
* appearance based on type, and interactive behavior. The button can rotate and display
* different positions such as FIRST, SECOND, THIRD, and LOST.
*/
public class CeremonyButton extends ClickButton { public class CeremonyButton extends ClickButton {
/**
* Enum representing the possible positions of the button in the ceremony screen.
*/
public enum Pos { public enum Pos {
FIRST, FIRST,
SECOND, SECOND,
@@ -21,18 +30,52 @@ public enum Pos {
LOST, LOST,
} }
/**
* Fixed width of the button in the UI layout.
*/
static final float WIDTH = 4.0f; static final float WIDTH = 4.0f;
/**
* Node to which the 3D model associated with this button is attached.
*/
private final Node node3d; private final Node node3d;
/**
* Flag to determine if the button's 3D model should rotate.
*/
private boolean rotate = false; private boolean rotate = false;
/**
* The 3D model associated with the button.
*/
private Spatial model; private Spatial model;
/**
* Current rotation angle of the button's 3D model.
*/
private float rot = 180; private float rot = 180;
/**
* The taken state of the button (default is NOT taken).
*/
private LobbyButton.Taken taken = LobbyButton.Taken.NOT; private LobbyButton.Taken taken = LobbyButton.Taken.NOT;
/**
* A label associated with the button for displaying additional information.
*/
private LabelButton label; private LabelButton label;
/**
* Constructs a CeremonyButton with specified attributes such as type, position, and label.
* The button supports both 2D and 3D components for UI and visual effects.
*
* @param app the application instance for accessing resources and settings
* @param node the node in the scene graph to which the button belongs
* @param node3d the node for 3D scene components associated with this button
* @param tsk the type/color associated with the button
* @param pos the position of the button in the ceremony layout
* @param name the label or name displayed on the button
*/
public CeremonyButton(MdgaApp app, Node node, Node node3d, Color tsk, Pos pos, String name) { public CeremonyButton(MdgaApp app, Node node, Node node3d, Color tsk, Pos pos, String name) {
super(app, node, () -> {}, "", new Vector2f(WIDTH, 7), new Vector2f(0, 0)); super(app, node, () -> {}, "", new Vector2f(WIDTH, 7), new Vector2f(0, 0));
@@ -73,8 +116,6 @@ public CeremonyButton(MdgaApp app, Node node, Node node3d, Color tsk, Pos pos, S
case FIRST: case FIRST:
rotate = true; rotate = true;
uiX = 0; uiX = 0;
uiY -= 0;
figX = 0;
figY -= 1 * figSpacingY; figY -= 1 * figSpacingY;
break; break;
case SECOND: case SECOND:
@@ -110,6 +151,9 @@ public CeremonyButton(MdgaApp app, Node node, Node node3d, Color tsk, Pos pos, S
createModel(asset, new Vector3f(figX, figY, 6)); createModel(asset, new Vector3f(figX, figY, 6));
} }
/**
* Handles hover behavior by changing the button's background appearance.
*/
@Override @Override
public void onHover() { public void onHover() {
ColorRGBA buttonNormal = BUTTON_NORMAL.clone(); ColorRGBA buttonNormal = BUTTON_NORMAL.clone();
@@ -119,6 +163,9 @@ public void onHover() {
instance.setBackground(background); instance.setBackground(background);
} }
/**
* Handles unhover behavior by resetting the button's background appearance.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
ColorRGBA buttonNormal = BUTTON_NORMAL.clone(); ColorRGBA buttonNormal = BUTTON_NORMAL.clone();
@@ -128,6 +175,9 @@ public void onUnHover() {
instance.setBackground(background); instance.setBackground(background);
} }
/**
* Displays the button along with its 3D model and associated label.
*/
@Override @Override
public void show() { public void show() {
release(); release();
@@ -141,6 +191,9 @@ public void show() {
label.show(); label.show();
} }
/**
* Hides the button along with its 3D model and associated label.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(instance); node.detachChild(instance);
@@ -149,6 +202,11 @@ public void hide() {
label.hide(); label.hide();
} }
/**
* Updates the rotation of the button's 3D model over time.
*
* @param tpf time per frame, used for smooth rotation calculations
*/
public void update(float tpf) { public void update(float tpf) {
if (rotate) { if (rotate) {
rot += 140.0f * tpf; rot += 140.0f * tpf;
@@ -157,16 +215,30 @@ public void update(float tpf) {
rot = 180; rot = 180;
} }
model.setLocalRotation(new Quaternion().fromAngles((float) Math.toRadians(90), (float) Math.toRadians(rot), (float) Math.toRadians(180))); model.setLocalRotation(new Quaternion().fromAngles(
(float) Math.toRadians(90),
(float) Math.toRadians(rot),
(float) Math.toRadians(180)
));
} }
/**
* Creates a 3D model associated with the button and applies its materials and position.
*
* @param asset the asset representing the 3D model and texture
* @param pos the initial position of the model in 3D space
*/
private void createModel(Asset asset, Vector3f pos) { private void createModel(Asset asset, Vector3f pos) {
String modelName = asset.getModelPath(); String modelName = asset.getModelPath();
String texName = asset.getDiffPath(); String texName = asset.getDiffPath();
model = app.getAssetManager().loadModel(modelName); model = app.getAssetManager().loadModel(modelName);
model.scale(asset.getSize() / 2); model.scale(asset.getSize() / 2);
model.rotate((float) Math.toRadians(90), (float) Math.toRadians(rot), (float) Math.toRadians(180)); model.rotate(
(float) Math.toRadians(90),
(float) Math.toRadians(rot),
(float) Math.toRadians(180)
);
model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
model.setLocalTranslation(pos); model.setLocalTranslation(pos);

View File

@@ -11,14 +11,43 @@
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound; import pp.mdga.client.acoustic.MdgaSound;
/**
* Abstract base class for creating interactive buttons with click functionality.
* This class extends {@link AbstractButton} and provides additional behavior such as
* click handling, hover effects, and alignment management.
*/
public abstract class ClickButton extends AbstractButton { public abstract class ClickButton extends AbstractButton {
/**
* The action to be executed when the button is clicked.
*/
protected final Runnable action; protected final Runnable action;
/**
* The label or text displayed on the button.
*/
protected String label; protected String label;
/**
* The size of the button in relative units.
*/
protected Vector2f size; protected Vector2f size;
/**
* The instance of the button being managed.
*/
protected Button instance; protected Button instance;
/**
* Constructs a ClickButton with the specified properties.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button belongs
* @param action the action to execute on button click
* @param label the text label displayed on the button
* @param size the size of the button
* @param pos the position of the button in relative units
*/
ClickButton(MdgaApp app, Node node, Runnable action, String label, Vector2f size, Vector2f pos) { ClickButton(MdgaApp app, Node node, Runnable action, String label, Vector2f size, Vector2f pos) {
super(app, node); super(app, node);
@@ -29,13 +58,21 @@ public abstract class ClickButton extends AbstractButton {
instance = new Button(label); instance = new Button(label);
instance.addClickCommands((button) -> { app.getAcousticHandler().playSound(MdgaSound.BUTTON_PRESSED); action.run(); }); // Add click behavior
instance.addClickCommands((button) -> {
app.getAcousticHandler().playSound(MdgaSound.BUTTON_PRESSED);
action.run();
});
// Set text alignment
instance.setTextHAlignment(HAlignment.Center); instance.setTextHAlignment(HAlignment.Center);
instance.setTextVAlignment(VAlignment.Center); instance.setTextVAlignment(VAlignment.Center);
// Add hover commands
instance.addCommands(Button.ButtonAction.HighlightOn, (button) -> click()); instance.addCommands(Button.ButtonAction.HighlightOn, (button) -> click());
instance.addCommands(Button.ButtonAction.HighlightOff, (button) -> release()); instance.addCommands(Button.ButtonAction.HighlightOff, (button) -> release());
// Set font and colors
instance.setFont(font); instance.setFont(font);
instance.setFocusColor(TEXT_NORMAL); instance.setFocusColor(TEXT_NORMAL);
@@ -43,6 +80,9 @@ public abstract class ClickButton extends AbstractButton {
setRelative(); setRelative();
} }
/**
* Displays the button by attaching it and its background image to the node.
*/
@Override @Override
public void show() { public void show() {
node.attachChild(pictureNormal); node.attachChild(pictureNormal);
@@ -55,6 +95,9 @@ public void show() {
node.attachChild(instance); node.attachChild(instance);
} }
/**
* Hides the button by detaching it and its background images from the node.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(instance); node.detachChild(instance);
@@ -67,9 +110,19 @@ public void hide() {
} }
} }
/**
* Abstract method to define hover behavior. Must be implemented by subclasses.
*/
protected abstract void onHover(); protected abstract void onHover();
/**
* Abstract method to define unhover behavior. Must be implemented by subclasses.
*/
protected abstract void onUnHover(); protected abstract void onUnHover();
/**
* Handles the button click behavior, including visual feedback and sound effects.
*/
protected void click() { protected void click() {
instance.setColor(TEXT_PRESSED); instance.setColor(TEXT_PRESSED);
instance.setHighlightColor(TEXT_PRESSED); instance.setHighlightColor(TEXT_PRESSED);
@@ -86,8 +139,11 @@ protected void click() {
} }
onHover(); onHover();
}; }
/**
* Resets the button to its normal state after a click or hover event.
*/
protected void release() { protected void release() {
instance.setColor(TEXT_NORMAL); instance.setColor(TEXT_NORMAL);
instance.setHighlightColor(TEXT_NORMAL); instance.setHighlightColor(TEXT_NORMAL);
@@ -102,8 +158,11 @@ protected void release() {
} }
onUnHover(); onUnHover();
}; }
/**
* Sets the relative size and position of the button based on screen dimensions.
*/
protected void setRelative() { protected void setRelative() {
instance.setFontSize(fontSize); instance.setFontSize(fontSize);
@@ -128,6 +187,11 @@ protected void setRelative() {
} }
} }
/**
* Sets the relative size and position of the button's background image.
*
* @param picture the background image to set
*/
protected void setImageRelative(Picture picture) { protected void setImageRelative(Picture picture) {
if (null == picture) { if (null == picture) {
return; return;
@@ -145,3 +209,4 @@ protected void setImageRelative(Picture picture) {
); );
} }
} }

View File

@@ -7,42 +7,81 @@
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents an input button with a label and a text field, allowing users to input text.
* The button is designed for graphical user interfaces and supports configurable
* size, position, and character limit.
*/
public class InputButton extends AbstractButton { public class InputButton extends AbstractButton {
/**
* The label associated with the input field, displayed above or beside the text field.
*/
private Label label; private Label label;
/**
* The text field where users input their text.
*/
private TextField field; private TextField field;
/**
* A container to hold the label and the text field for layout management.
*/
private Container container = new Container(); private Container container = new Container();
/**
* The maximum allowed length of the input text.
*/
private final int maxLenght; private final int maxLenght;
/**
* The size of the input button in relative units.
*/
protected Vector2f size; protected Vector2f size;
/**
* Constructs an InputButton with the specified label, character limit, and other properties.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the input button belongs
* @param label the label displayed with the input field
* @param maxLenght the maximum number of characters allowed in the input field
*/
public InputButton(MdgaApp app, Node node, String label, int maxLenght) { public InputButton(MdgaApp app, Node node, String label, int maxLenght) {
super(app, node); super(app, node);
this.label = new Label(label); this.label = new Label(label);
this.maxLenght = maxLenght; this.maxLenght = maxLenght;
// Configure label properties
this.label.setColor(TEXT_NORMAL); this.label.setColor(TEXT_NORMAL);
// Configure text field properties
field = new TextField(""); field = new TextField("");
field.setColor(TEXT_NORMAL); field.setColor(TEXT_NORMAL);
field.setTextHAlignment(HAlignment.Left); field.setTextHAlignment(HAlignment.Left);
field.setTextVAlignment(VAlignment.Center); field.setTextVAlignment(VAlignment.Center);
// Set background for the text field
QuadBackgroundComponent grayBackground = new QuadBackgroundComponent(BUTTON_NORMAL); QuadBackgroundComponent grayBackground = new QuadBackgroundComponent(BUTTON_NORMAL);
field.setBackground(grayBackground); field.setBackground(grayBackground);
// Set fonts for label and text field
this.label.setFont(font); this.label.setFont(font);
field.setFont(font); field.setFont(font);
// Default position and size
pos = new Vector2f(0, 0); pos = new Vector2f(0, 0);
size = new Vector2f(5.5f, 1); size = new Vector2f(5.5f, 1);
// Add components to the container
container.addChild(this.label); container.addChild(this.label);
container.addChild(field); container.addChild(field);
} }
/**
* Displays the input button by attaching it to the scene graph node.
*/
@Override @Override
public void show() { public void show() {
calculateRelative(); calculateRelative();
@@ -51,11 +90,18 @@ public void show() {
node.attachChild(container); node.attachChild(container);
} }
/**
* Hides the input button by detaching it from the scene graph node.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(container); node.detachChild(container);
} }
/**
* Updates the input field, enforcing the character limit.
* Trims the text if it exceeds the maximum allowed length.
*/
public void update() { public void update() {
String text = field.getText(); String text = field.getText();
int length = text.length(); int length = text.length();
@@ -65,6 +111,9 @@ public void update() {
} }
} }
/**
* Adjusts the relative size and position of the input button based on the screen resolution.
*/
protected void setRelative() { protected void setRelative() {
this.label.setFontSize(fontSize); this.label.setFontSize(fontSize);
field.setFontSize(fontSize); field.setFontSize(fontSize);
@@ -90,12 +139,27 @@ protected void setRelative() {
} }
} }
/**
* Retrieves the text currently entered in the input field.
*
* @return the current text in the input field
*/
public String getString() { public String getString() {
return field.getText(); return field.getText();
} }
public void setString(String string) { field.setText(string); } /**
* Sets the text of the input field to the specified string.
*
* @param string the text to set in the input field
*/
public void setString(String string) {
field.setText(string);
}
/**
* Resets the input field by clearing its text.
*/
public void reset() { public void reset() {
field.setText(""); field.setText("");
} }

View File

@@ -6,20 +6,50 @@
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* A specialized button that can function as a label or a clickable button.
* It inherits from {@link ClickButton} and allows for flexible usage with or without button-like behavior.
*/
public class LabelButton extends ClickButton { public class LabelButton extends ClickButton {
/**
* The color of the text displayed on the label or button.
*/
private ColorRGBA text = TEXT_NORMAL; private ColorRGBA text = TEXT_NORMAL;
/**
* The color of the button's background.
*/
private ColorRGBA button = BUTTON_NORMAL; private ColorRGBA button = BUTTON_NORMAL;
/**
* Flag indicating whether this component functions as a button.
*/
private boolean isButton; private boolean isButton;
/**
* Constructs a LabelButton with specified properties.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button belongs
* @param label the text displayed on the label or button
* @param size the size of the label or button
* @param pos the position of the label or button in relative units
* @param isButton whether this component acts as a button or a simple label
*/
public LabelButton(MdgaApp app, Node node, String label, Vector2f size, Vector2f pos, boolean isButton) { public LabelButton(MdgaApp app, Node node, String label, Vector2f size, Vector2f pos, boolean isButton) {
super(app, node, () -> {}, label, size, pos); super(app, node, () -> {}, label, size, pos);
this.isButton = isButton; this.isButton = isButton;
// Use the same image for hover and normal states
pictureHover = pictureNormal; pictureHover = pictureNormal;
} }
/**
* Displays the label or button, attaching it to the scene graph.
* If the component is a button, it also attaches the background image.
*/
@Override @Override
public void show() { public void show() {
if (isButton) { if (isButton) {
@@ -36,6 +66,9 @@ public void show() {
node.attachChild(instance); node.attachChild(instance);
} }
/**
* Hides the label or button, detaching it from the scene graph.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(instance); node.detachChild(instance);
@@ -48,6 +81,9 @@ public void hide() {
} }
} }
/**
* Handles hover behavior, updating the colors of the text and background.
*/
@Override @Override
public void onHover() { public void onHover() {
instance.setColor(text); instance.setColor(text);
@@ -57,6 +93,9 @@ public void onHover() {
instance.setBackground(background); instance.setBackground(background);
} }
/**
* Handles unhover behavior, restoring the colors of the text and background.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
instance.setColor(text); instance.setColor(text);
@@ -66,10 +105,21 @@ public void onUnHover() {
instance.setBackground(background); instance.setBackground(background);
} }
/**
* Sets the text displayed on the label or button.
*
* @param text the text to display
*/
public void setText(String text) { public void setText(String text) {
instance.setText(text); instance.setText(text);
} }
/**
* Sets the colors of the text and background, and refreshes the label or button.
*
* @param text the color of the text
* @param button the color of the button's background
*/
public void setColor(ColorRGBA text, ColorRGBA button) { public void setColor(ColorRGBA text, ColorRGBA button) {
this.text = text; this.text = text;
this.button = button; this.button = button;
@@ -78,3 +128,4 @@ public void setColor(ColorRGBA text, ColorRGBA button) {
show(); show();
} }
} }

View File

@@ -17,35 +17,96 @@
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.game.Color; import pp.mdga.game.Color;
/**
* Represents a button in a multiplayer lobby screen. The button supports multiple states
* (not taken, self, other) and displays a 3D model alongside its label. It can also indicate readiness
* and interactively respond to hover and click events.
*/
public class LobbyButton extends ClickButton { public class LobbyButton extends ClickButton {
/**
* Enum representing the possible ownership states of the lobby button.
*/
public enum Taken { public enum Taken {
NOT, NOT, // The button is not taken
SELF, SELF, // The button is taken by the user
OTHER, OTHER // The button is taken by another user
} }
/**
* Color for a lobby button that is taken by another user.
*/
static final ColorRGBA LOBBY_TAKEN = ColorRGBA.fromRGBA255(193, 58, 59, 100); static final ColorRGBA LOBBY_TAKEN = ColorRGBA.fromRGBA255(193, 58, 59, 100);
/**
* Color for a lobby button that is ready but not hovered.
*/
static final ColorRGBA LOBBY_READY = ColorRGBA.fromRGBA255(55, 172, 190, 100); static final ColorRGBA LOBBY_READY = ColorRGBA.fromRGBA255(55, 172, 190, 100);
/**
* Color for a lobby button that is ready and hovered.
*/
static final ColorRGBA LOBBY_READY_HOVER = ColorRGBA.fromRGBA255(17, 211, 218, 100); static final ColorRGBA LOBBY_READY_HOVER = ColorRGBA.fromRGBA255(17, 211, 218, 100);
/**
* Color for a lobby button owned by the user in normal state.
*/
static final ColorRGBA LOBBY_SELF_NORMAL = ColorRGBA.fromRGBA255(0, 151, 19, 100); static final ColorRGBA LOBBY_SELF_NORMAL = ColorRGBA.fromRGBA255(0, 151, 19, 100);
/**
* Color for a lobby button owned by the user when hovered.
*/
static final ColorRGBA LOBBY_SELF_HOVER = ColorRGBA.fromRGBA255(0, 230, 19, 100); static final ColorRGBA LOBBY_SELF_HOVER = ColorRGBA.fromRGBA255(0, 230, 19, 100);
/**
* Fixed width for the lobby button.
*/
static final float WIDTH = 4.0f; static final float WIDTH = 4.0f;
/**
* Node to which the 3D model associated with this button is attached.
*/
private final Node node3d; private final Node node3d;
/**
* Indicates whether the 3D model should rotate.
*/
private boolean rotate = false; private boolean rotate = false;
/**
* The 3D model displayed alongside the button.
*/
private Spatial model; private Spatial model;
/**
* The rotation angle of the 3D model.
*/
private float rot = 180; private float rot = 180;
/**
* The current ownership state of the lobby button.
*/
private Taken taken = Taken.NOT; private Taken taken = Taken.NOT;
/**
* Label displayed on the lobby button.
*/
private LabelButton label; private LabelButton label;
/**
* Indicates whether the button represents a ready state.
*/
private boolean isReady = false; private boolean isReady = false;
/**
* Constructs a LobbyButton with specified properties, including a 3D model and label.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button belongs
* @param node3d the node for 3D scene components associated with this button
* @param action the action to execute when the button is clicked
* @param tsk the type or category of the button (e.g., CYBER, AIRFORCE)
*/
public LobbyButton(MdgaApp app, Node node, Node node3d, Runnable action, Color tsk) { public LobbyButton(MdgaApp app, Node node, Node node3d, Runnable action, Color tsk) {
super(app, node, action, "", new Vector2f(WIDTH, 7), new Vector2f(0, 0)); super(app, node, action, "", new Vector2f(WIDTH, 7), new Vector2f(0, 0));
@@ -61,6 +122,7 @@ public LobbyButton(MdgaApp app, Node node, Node node3d, Runnable action, Color t
float figX = 0; float figX = 0;
Asset asset = null; Asset asset = null;
// Configure the button based on its type
switch (tsk) { switch (tsk) {
case CYBER: case CYBER:
adjust = true; adjust = true;
@@ -100,6 +162,9 @@ public LobbyButton(MdgaApp app, Node node, Node node3d, Runnable action, Color t
createModel(asset, new Vector3f(figX, -0.55f, 6)); createModel(asset, new Vector3f(figX, -0.55f, 6));
} }
/**
* Handles hover behavior, updating the button's color and enabling rotation.
*/
@Override @Override
public void onHover() { public void onHover() {
ColorRGBA buttonPressed = BUTTON_PRESSED.clone(); ColorRGBA buttonPressed = BUTTON_PRESSED.clone();
@@ -126,6 +191,9 @@ public void onHover() {
rotate = true; rotate = true;
} }
/**
* Handles unhover behavior, restoring the button's color and disabling rotation.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
ColorRGBA buttonNormal = BUTTON_NORMAL.clone(); ColorRGBA buttonNormal = BUTTON_NORMAL.clone();
@@ -152,6 +220,9 @@ public void onUnHover() {
rotate = false; rotate = false;
} }
/**
* Displays the lobby button and its associated components.
*/
@Override @Override
public void show() { public void show() {
release(); release();
@@ -165,6 +236,9 @@ public void show() {
label.show(); label.show();
} }
/**
* Hides the lobby button and its associated components.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(instance); node.detachChild(instance);
@@ -173,6 +247,11 @@ public void hide() {
label.hide(); label.hide();
} }
/**
* Updates the 3D model's rotation if the button is being hovered.
*
* @param tpf time per frame, used for smooth rotation calculations
*/
public void update(float tpf) { public void update(float tpf) {
if (rotate) { if (rotate) {
rot += 140.0f * tpf; rot += 140.0f * tpf;
@@ -181,16 +260,30 @@ public void update(float tpf) {
rot = 180; rot = 180;
} }
model.setLocalRotation(new Quaternion().fromAngles((float) Math.toRadians(90), (float) Math.toRadians(rot), (float) Math.toRadians(180))); model.setLocalRotation(new Quaternion().fromAngles(
(float) Math.toRadians(90),
(float) Math.toRadians(rot),
(float) Math.toRadians(180)
));
} }
/**
* Creates the 3D model associated with the lobby button and applies textures and positioning.
*
* @param asset the asset representing the 3D model
* @param pos the initial position of the 3D model
*/
private void createModel(Asset asset, Vector3f pos) { private void createModel(Asset asset, Vector3f pos) {
String modelName = asset.getModelPath(); String modelName = asset.getModelPath();
String texName = asset.getDiffPath(); String texName = asset.getDiffPath();
model = app.getAssetManager().loadModel(modelName); model = app.getAssetManager().loadModel(modelName);
model.scale(asset.getSize() / 2); model.scale(asset.getSize() / 2);
model.rotate((float) Math.toRadians(90), (float) Math.toRadians(rot), (float) Math.toRadians(180)); model.rotate(
(float) Math.toRadians(90),
(float) Math.toRadians(rot),
(float) Math.toRadians(180)
);
model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
model.setLocalTranslation(pos); model.setLocalTranslation(pos);
@@ -200,10 +293,21 @@ private void createModel(Asset asset, Vector3f pos) {
model.setMaterial(mat); model.setMaterial(mat);
} }
/**
* Gets the current ownership state of the lobby button.
*
* @return the current state of the button
*/
public Taken getTaken() { public Taken getTaken() {
return taken; return taken;
} }
/**
* Sets the ownership state of the lobby button and updates its label accordingly.
*
* @param taken the new ownership state
* @param name the name to display on the button
*/
public void setTaken(Taken taken, String name) { public void setTaken(Taken taken, String name) {
this.taken = taken; this.taken = taken;
@@ -217,8 +321,14 @@ public void setTaken(Taken taken, String name) {
onUnHover(); onUnHover();
} }
/**
* Sets the ready state of the lobby button and updates its appearance.
*
* @param isReady whether the button represents a ready state
*/
public void setReady(boolean isReady) { public void setReady(boolean isReady) {
this.isReady = isReady; this.isReady = isReady;
onUnHover(); onUnHover();
} }
} }

View File

@@ -4,18 +4,40 @@
import com.jme3.scene.Node; import com.jme3.scene.Node;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents a button used in menu screens for navigation or executing actions.
* Inherits from {@link ClickButton} and provides customizable text and actions.
*/
public class MenuButton extends ClickButton { public class MenuButton extends ClickButton {
/**
* Constructs a MenuButton with specified properties.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button belongs
* @param action the action to execute when the button is clicked
* @param label the text label displayed on the button
*/
public MenuButton(MdgaApp app, Node node, Runnable action, String label) { public MenuButton(MdgaApp app, Node node, Runnable action, String label) {
super(app, node, action, label, new Vector2f(5.5f, 2), new Vector2f(0, 0)); super(app, node, action, label, new Vector2f(5.5f, 2), new Vector2f(0, 0));
} }
/**
* Called when the button is hovered over. Can be overridden to define hover-specific behavior.
* Currently, no additional behavior is implemented.
*/
@Override @Override
public void onHover() { public void onHover() {
// Placeholder for hover behavior
} }
/**
* Called when the pointer stops hovering over the button. Can be overridden to define unhover-specific behavior.
* Currently, no additional behavior is implemented.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
// Placeholder for unhover behavior
}
}
}
}

View File

@@ -7,15 +7,34 @@
import com.simsilica.lemur.component.IconComponent; import com.simsilica.lemur.component.IconComponent;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents a button in the settings menu, designed to display an icon and handle hover effects.
* Inherits from {@link ClickButton} and customizes its behavior for settings functionality.
*/
public class SettingsButton extends ClickButton { public class SettingsButton extends ClickButton {
/**
* The icon displayed on the button, which changes based on hover state.
*/
private IconComponent icon; private IconComponent icon;
/**
* Constructs a SettingsButton with a predefined size and position.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the button belongs
* @param action the action to execute when the button is clicked
*/
public SettingsButton(MdgaApp app, Node node, Runnable action) { public SettingsButton(MdgaApp app, Node node, Runnable action) {
super(app, node, action, "", new Vector2f(2, 2), new Vector2f(HORIZONTAL - 0.5f, VERTICAL - 0.5f)); super(app, node, action, "", new Vector2f(2, 2), new Vector2f(HORIZONTAL - 0.5f, VERTICAL - 0.5f));
// Enable adjustment for positioning
adjust = true; adjust = true;
} }
/**
* Displays the settings button by attaching it to the scene graph.
*/
@Override @Override
public void show() { public void show() {
release(); release();
@@ -27,6 +46,9 @@ public void show() {
node.attachChild(instance); node.attachChild(instance);
} }
/**
* Handles hover behavior by changing the icon to the hover state.
*/
@Override @Override
public void onHover() { public void onHover() {
icon = new IconComponent("Images/Settings_Button_hover.png"); icon = new IconComponent("Images/Settings_Button_hover.png");
@@ -37,6 +59,9 @@ public void onHover() {
instance.setIcon(icon); instance.setIcon(icon);
} }
/**
* Handles unhover behavior by restoring the icon to the normal state.
*/
@Override @Override
public void onUnHover() { public void onUnHover() {
icon = new IconComponent("Images/Settings_Button_normal.png"); icon = new IconComponent("Images/Settings_Button_normal.png");
@@ -47,3 +72,4 @@ public void onUnHover() {
instance.setIcon(icon); instance.setIcon(icon);
} }
} }

View File

@@ -7,24 +7,50 @@
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
/**
* Represents a slider button component with a label, providing functionality for
* adjusting values in a graphical user interface. It includes increment, decrement,
* and thumb buttons, allowing for interactive adjustments.
*/
public class SliderButton extends AbstractButton { public class SliderButton extends AbstractButton {
/**
* The label displayed next to the slider.
*/
private Label label; private Label label;
/**
* The slider component for adjusting values.
*/
private Slider slider; private Slider slider;
/**
* A container to hold the label and slider for layout management.
*/
private Container container = new Container(); private Container container = new Container();
/**
* The size of the slider button in relative units.
*/
protected Vector2f size; protected Vector2f size;
/**
* Constructs a SliderButton with the specified label.
*
* @param app the application instance for accessing resources
* @param node the node in the scene graph to which the slider button belongs
* @param label the text label displayed alongside the slider
*/
public SliderButton(MdgaApp app, Node node, String label) { public SliderButton(MdgaApp app, Node node, String label) {
super(app, node); super(app, node);
this.label = new Label(label); this.label = new Label(label);
this.label.setColor(TEXT_NORMAL); this.label.setColor(TEXT_NORMAL);
// Configure the slider
slider = new Slider("slider"); slider = new Slider("slider");
// Configure decrement button
slider.getDecrementButton().setText(" - "); slider.getDecrementButton().setText(" - ");
slider.getDecrementButton().setFont(font); slider.getDecrementButton().setFont(font);
slider.getDecrementButton().setFocusColor(TEXT_NORMAL); slider.getDecrementButton().setFocusColor(TEXT_NORMAL);
@@ -32,6 +58,7 @@ public SliderButton(MdgaApp app, Node node, String label) {
slider.getDecrementButton().setColor(TEXT_NORMAL); slider.getDecrementButton().setColor(TEXT_NORMAL);
slider.getDecrementButton().setHighlightColor(TEXT_NORMAL); slider.getDecrementButton().setHighlightColor(TEXT_NORMAL);
// Configure increment button
slider.getIncrementButton().setText(" + "); slider.getIncrementButton().setText(" + ");
slider.getIncrementButton().setFont(font); slider.getIncrementButton().setFont(font);
slider.getIncrementButton().setFocusColor(TEXT_NORMAL); slider.getIncrementButton().setFocusColor(TEXT_NORMAL);
@@ -39,25 +66,32 @@ public SliderButton(MdgaApp app, Node node, String label) {
slider.getIncrementButton().setColor(TEXT_NORMAL); slider.getIncrementButton().setColor(TEXT_NORMAL);
slider.getIncrementButton().setHighlightColor(TEXT_NORMAL); slider.getIncrementButton().setHighlightColor(TEXT_NORMAL);
// Configure thumb button
slider.getThumbButton().setText("X"); slider.getThumbButton().setText("X");
slider.getThumbButton().setFont(font); slider.getThumbButton().setFont(font);
slider.getThumbButton().setFocusColor(TEXT_NORMAL); slider.getThumbButton().setFocusColor(TEXT_NORMAL);
slider.getThumbButton().setColor(TEXT_NORMAL); slider.getThumbButton().setColor(TEXT_NORMAL);
slider.getThumbButton().setHighlightColor(TEXT_NORMAL); slider.getThumbButton().setHighlightColor(TEXT_NORMAL);
// Set slider background
QuadBackgroundComponent background = new QuadBackgroundComponent(BUTTON_NORMAL); QuadBackgroundComponent background = new QuadBackgroundComponent(BUTTON_NORMAL);
slider.setBackground(background); slider.setBackground(background);
// Configure the label font
this.label.setFont(font); this.label.setFont(font);
// Default position and size
pos = new Vector2f(0, 0); pos = new Vector2f(0, 0);
size = new Vector2f(5.5f, 1); size = new Vector2f(5.5f, 1);
// Add label and slider to container
container.addChild(this.label); container.addChild(this.label);
container.addChild(slider); container.addChild(slider);
} }
/**
* Displays the slider button by attaching its container to the scene graph.
*/
@Override @Override
public void show() { public void show() {
calculateRelative(); calculateRelative();
@@ -66,18 +100,26 @@ public void show() {
node.attachChild(container); node.attachChild(container);
} }
/**
* Hides the slider button by detaching its container from the scene graph.
*/
@Override @Override
public void hide() { public void hide() {
node.detachChild(container); node.detachChild(container);
} }
/**
* Sets the relative size and position of the slider button based on screen resolution.
*/
protected void setRelative() { protected void setRelative() {
this.label.setFontSize(fontSize); this.label.setFontSize(fontSize);
// Set font sizes for slider components
slider.getDecrementButton().setFontSize(fontSize); slider.getDecrementButton().setFontSize(fontSize);
slider.getIncrementButton().setFontSize(fontSize); slider.getIncrementButton().setFontSize(fontSize);
slider.getThumbButton().setFontSize(fontSize); slider.getThumbButton().setFontSize(fontSize);
// Set slider size
slider.setPreferredSize(new Vector3f(size.x * widthStep, size.y * heightStep, 0)); slider.setPreferredSize(new Vector3f(size.x * widthStep, size.y * heightStep, 0));
float xAdjust = 0.0f; float xAdjust = 0.0f;
@@ -85,6 +127,7 @@ protected void setRelative() {
xAdjust = container.getPreferredSize().x; xAdjust = container.getPreferredSize().x;
} }
// Set container position
container.setLocalTranslation(pos.x * horizontalStep - xAdjust, pos.y * verticalStep, -1); container.setLocalTranslation(pos.x * horizontalStep - xAdjust, pos.y * verticalStep, -1);
final float horizontalMid = ((float) app.getCamera().getWidth() / 2) - (container.getPreferredSize().x / 2); final float horizontalMid = ((float) app.getCamera().getWidth() / 2) - (container.getPreferredSize().x / 2);
@@ -99,11 +142,22 @@ protected void setRelative() {
} }
} }
/**
* Retrieves the current percentage value of the slider.
*
* @return the current percentage value as a float
*/
public float getPercent() { public float getPercent() {
return (float) slider.getModel().getPercent(); return (float) slider.getModel().getPercent();
} }
/**
* Sets the slider to the specified percentage value.
*
* @param percent the percentage value to set
*/
public void setPercent(float percent) { public void setPercent(float percent) {
slider.getModel().setPercent(percent); slider.getModel().setPercent(percent);
} }
} }