mirror of
				https://github.com/SikongJueluo/cc-utils.git
				synced 2025-11-04 19:27:50 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			101 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { UIComponent } from "./UIComponent";
 | 
						|
import { Signal } from "./signal";
 | 
						|
import { KeyEvent } from "../event";
 | 
						|
 | 
						|
/**
 | 
						|
 * Button component
 | 
						|
 */
 | 
						|
export class Button extends UIComponent {
 | 
						|
  private text: string;
 | 
						|
  private textColor: number;
 | 
						|
  private bgColor: number;
 | 
						|
  private pressed = false;
 | 
						|
 | 
						|
  // Signal for when button is clicked
 | 
						|
  public onClick = new Signal<void>();
 | 
						|
 | 
						|
  constructor(
 | 
						|
    objectName: string,
 | 
						|
    x: number,
 | 
						|
    y: number,
 | 
						|
    text: string,
 | 
						|
    textColor: number = colors.white,
 | 
						|
    bgColor: number = colors.black,
 | 
						|
  ) {
 | 
						|
    // Width is based on text length plus 2 for the brackets ( [text] )
 | 
						|
    super(objectName, x, y, text.length + 2, 1);
 | 
						|
    this.text = text;
 | 
						|
    this.textColor = textColor;
 | 
						|
    this.bgColor = bgColor;
 | 
						|
  }
 | 
						|
 | 
						|
  render(): void {
 | 
						|
    if (!this.visible) return;
 | 
						|
 | 
						|
    const [originalX, originalY] = term.getCursorPos();
 | 
						|
 | 
						|
    // Set colors based on state (normal, focused, or pressed)
 | 
						|
    let textColor = this.textColor;
 | 
						|
    let backgroundColor = this.bgColor;
 | 
						|
 | 
						|
    if (this.pressed) {
 | 
						|
      textColor = this.bgColor; // Swap text and background colors when pressed
 | 
						|
      backgroundColor = this.textColor;
 | 
						|
    } else if (this.focused) {
 | 
						|
      textColor = colors.yellow; // Yellow text when focused
 | 
						|
    }
 | 
						|
 | 
						|
    term.setTextColor(textColor);
 | 
						|
    term.setBackgroundColor(backgroundColor);
 | 
						|
 | 
						|
    // Move cursor to position and draw button
 | 
						|
    term.setCursorPos(this.x, this.y);
 | 
						|
    term.write(`[${this.text}]`);
 | 
						|
 | 
						|
    // Restore original cursor position
 | 
						|
    term.setCursorPos(originalX, originalY);
 | 
						|
  }
 | 
						|
 | 
						|
  handleKeyInput(event: KeyEvent): void {
 | 
						|
    if (!this.focused) return;
 | 
						|
 | 
						|
    this.onKeyPress.emit(event);
 | 
						|
 | 
						|
    const key = event.key;
 | 
						|
 | 
						|
    // Handle button activation with space or enter
 | 
						|
    if (key === keys.space || key === keys.enter) {
 | 
						|
      this.pressButton();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  handleMouseClick(_event: { x: number; y: number }): void {
 | 
						|
    // Button was clicked, trigger press
 | 
						|
    this.pressButton();
 | 
						|
  }
 | 
						|
 | 
						|
  private pressButton(): void {
 | 
						|
    // Set pressed state and render
 | 
						|
    this.pressed = true;
 | 
						|
    this.render();
 | 
						|
 | 
						|
    // Trigger click signal
 | 
						|
    this.onClick.emit();
 | 
						|
 | 
						|
    // Reset pressed state after a short delay to show visual feedback
 | 
						|
    this.startTimer(() => {
 | 
						|
      this.pressed = false;
 | 
						|
      this.render();
 | 
						|
    }, 100);
 | 
						|
  }
 | 
						|
 | 
						|
  setText(newText: string): void {
 | 
						|
    this.text = newText;
 | 
						|
    this.width = newText.length + 2; // Update width based on new text
 | 
						|
  }
 | 
						|
 | 
						|
  getText(): string {
 | 
						|
    return this.text;
 | 
						|
  }
 | 
						|
}
 |