Use IconSources and override IconButton.onClicked

This commit is contained in:
Fingercomp 2025-08-12 02:58:41 +03:00
parent 055671abc1
commit b759846505
No known key found for this signature in database
GPG Key ID: BBC71CEE45D86E37
36 changed files with 244 additions and 165 deletions

View File

@ -138,66 +138,77 @@ object IconSource {
// ----------------------- Ocelot interface icons -----------------------
val Notification: NotificationType => IconSource = { notificationType =>
IconSource(s"icons/Notification$notificationType")
object Icons {
val Notification: NotificationType => IconSource = { notificationType =>
IconSource(s"icons/Notification$notificationType")
}
val Loading: IconSource = IconSource(
"Loading",
animation = Some(Animation(
Size2D(48, 32),
(0, 0.7f),
(1, 0.7f),
(2, 0.7f),
(3, 0.7f),
(4, 0.7f),
(5, 0.7f),
(6, 0.7f),
(7, 0.7f),
(8, 0.7f),
(9, 0.7f),
(10, 0.7f),
(11, 0.7f),
(12, 0.7f),
(13, 0.7f),
)),
)
val SettingsKeymap: IconSource = IconSource("icons/SettingsKeymap")
val SettingsSystem: IconSource = IconSource("icons/SettingsSystem")
val SettingsSound: IconSource = IconSource("icons/SettingsSound")
val SettingsUI: IconSource = IconSource("icons/SettingsUI")
val Delete: IconSource = IconSource("icons/Delete")
val Label: IconSource = IconSource("icons/Label")
val Copy: IconSource = IconSource("icons/Copy")
val AspectRatio: IconSource = IconSource("icons/AspectRatio")
val Eject: IconSource = IconSource("icons/Eject")
val Restart: IconSource = IconSource("icons/Restart")
val Edit: IconSource = IconSource("icons/Edit")
val Folder: IconSource = IconSource("icons/Folder")
val FolderSlash: IconSource = IconSource("icons/FolderSlash")
val Code: IconSource = IconSource("icons/Code")
val File: IconSource = IconSource("icons/File")
val Link: IconSource = IconSource("icons/Link")
val LinkSlash: IconSource = IconSource("icons/LinkSlash")
val Power: IconSource = IconSource("icons/Power")
val Save: IconSource = IconSource("icons/Save")
val SaveAs: IconSource = IconSource("icons/SaveAs")
val Plus: IconSource = IconSource("icons/Plus")
val Cross: IconSource = IconSource("icons/Cross")
val Microchip: IconSource = IconSource("icons/Microchip")
val Antenna: IconSource = IconSource("icons/Antenna")
val Window: IconSource = IconSource("icons/Window")
val Tiers: IconSource = IconSource("icons/Tiers")
val LinesHorizontal: IconSource = IconSource("icons/LinesHorizontal")
val ArrowRight: IconSource = IconSource("icons/ArrowRight")
val Book: IconSource = IconSource("icons/Book")
val Help: IconSource = IconSource("icons/Help")
val Ocelot: IconSource = IconSource("icons/Ocelot")
val Guitar: IconSource = IconSource("icons/Guitar")
val Keyboard: IconSource = IconSource("icons/Keyboard")
val KeyboardOff: IconSource = IconSource("icons/KeyboardOff")
val ButtonRandomize: IconSource = IconSource("icons/ButtonRandomize")
val ButtonClipboard: IconSource = IconSource("icons/ButtonClipboard")
val ButtonCheck: IconSource = IconSource("icons/ButtonCheck")
val Home: IconSource = IconSource("icons/Home")
val Pin: IconSource = IconSource("icons/Pin")
val Unpin: IconSource = IconSource("icons/Unpin")
val Close: IconSource = IconSource("icons/Close")
val Grid: IconSource = IconSource("icons/Grid")
val GridOff: IconSource = IconSource("icons/GridOff")
}
val Loading: IconSource = IconSource(
"Loading",
animation = Some(Animation(
Size2D(48, 32),
(0, 0.7f),
(1, 0.7f),
(2, 0.7f),
(3, 0.7f),
(4, 0.7f),
(5, 0.7f),
(6, 0.7f),
(7, 0.7f),
(8, 0.7f),
(9, 0.7f),
(10, 0.7f),
(11, 0.7f),
(12, 0.7f),
(13, 0.7f),
)),
)
val SettingsKeymap: IconSource = IconSource("icons/SettingsKeymap")
val SettingsSystem: IconSource = IconSource("icons/SettingsSystem")
val SettingsSound: IconSource = IconSource("icons/SettingsSound")
val SettingsUI: IconSource = IconSource("icons/SettingsUI")
val Delete: IconSource = IconSource("icons/Delete")
val Label: IconSource = IconSource("icons/Label")
val Copy: IconSource = IconSource("icons/Copy")
val AspectRatio: IconSource = IconSource("icons/AspectRatio")
val Eject: IconSource = IconSource("icons/Eject")
val Restart: IconSource = IconSource("icons/Restart")
val Edit: IconSource = IconSource("icons/Edit")
val Folder: IconSource = IconSource("icons/Folder")
val FolderSlash: IconSource = IconSource("icons/FolderSlash")
val Code: IconSource = IconSource("icons/Code")
val File: IconSource = IconSource("icons/File")
val Link: IconSource = IconSource("icons/Link")
val LinkSlash: IconSource = IconSource("icons/LinkSlash")
val Power: IconSource = IconSource("icons/Power")
val Save: IconSource = IconSource("icons/Save")
val SaveAs: IconSource = IconSource("icons/SaveAs")
val Plus: IconSource = IconSource("icons/Plus")
val Cross: IconSource = IconSource("icons/Cross")
val Microchip: IconSource = IconSource("icons/Microchip")
val Antenna: IconSource = IconSource("icons/Antenna")
val Window: IconSource = IconSource("icons/Window")
val Tiers: IconSource = IconSource("icons/Tiers")
val LinesHorizontal: IconSource = IconSource("icons/LinesHorizontal")
val ArrowRight: IconSource = IconSource("icons/ArrowRight")
val Book: IconSource = IconSource("icons/Book")
val Help: IconSource = IconSource("icons/Help")
val Ocelot: IconSource = IconSource("icons/Ocelot")
val Guitar: IconSource = IconSource("icons/Guitar")
val Keyboard: IconSource = IconSource("icons/Keyboard")
val KeyboardOff: IconSource = IconSource("icons/KeyboardOff")
// ----------------------- Node icons -----------------------
val NA: IconSource = IconSource("icons/NA")
@ -371,6 +382,60 @@ object IconSource {
// ----------------------- Particles -----------------------
object Particles {
val Smoke: IconSource = IconSource("particles/Smoke")
protected val prefix: String = "particles"
val Smoke: IconSource = IconSource(s"$prefix/Smoke")
}
// ----------------------- Buttons -----------------------
object Buttons {
protected val prefix: String = "buttons"
val BottomDrawerOpen: IconSource = IconSource(s"$prefix/BottomDrawerOpen")
val BottomDrawerClose: IconSource = IconSource(s"$prefix/BottomDrawerClose")
val PowerOff: IconSource = IconSource(s"$prefix/PowerOff")
val PowerOn: IconSource = IconSource(s"$prefix/PowerOn")
val OpenFMRadioVolumeOff: Boolean => IconSource = { isUp =>
IconSource(s"$prefix/OpenFMRadioVolume${if (isUp) "Up" else "Down"}Off")
}
val OpenFMRadioVolumeOn: Boolean => IconSource = { isUp =>
IconSource(s"$prefix/OpenFMRadioVolume${if (isUp) "Up" else "Down"}On")
}
val OpenFMRadioRedstoneOff: IconSource = IconSource(s"$prefix/OpenFMRadioRedstoneOff")
val OpenFMRadioRedstoneOn: IconSource = IconSource(s"$prefix/OpenFMRadioRedstoneOn")
val OpenFMRadioCloseOff: IconSource = IconSource(s"$prefix/OpenFMRadioCloseOff")
val OpenFMRadioCloseOn: IconSource = IconSource(s"$prefix/OpenFMRadioCloseOn")
val OpenFMRadioStartOff: IconSource = IconSource(s"$prefix/OpenFMRadioStartOff")
val OpenFMRadioStopOn: IconSource = IconSource(s"$prefix/OpenFMRadioStopOn")
val RackRelayOff: IconSource = IconSource(s"$prefix/RackRelayOff")
val RackRelayOn: IconSource = IconSource(s"$prefix/RackRelayOn")
}
// ----------------------- Window icons -----------------------
object Window {
protected val prefix: String = "window"
object Tape {
protected val prefix: String = s"${Window.prefix}/tape"
abstract class TapeButtonIconSource private[Tape] (sprite: String) {
val Released: IconSource = IconSource(s"$prefix/$sprite")
val Pressed: IconSource = IconSource(s"$prefix/${sprite}Pressed")
}
object Back extends TapeButtonIconSource("Back")
object Play extends TapeButtonIconSource("Play")
object Stop extends TapeButtonIconSource("Stop")
object Forward extends TapeButtonIconSource("Forward")
}
}
}

View File

@ -45,8 +45,8 @@ class EepromItem(val eeprom: EEPROM) extends Item with ComponentItem with Persis
}
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(new ContextMenuSubmenu("External data source", Some(ContextMenuIcon(IconSource.Code))) {
addEntry(ContextMenuEntry("Local file", IconSource.File) {
menu.addEntry(new ContextMenuSubmenu("External data source", Some(ContextMenuIcon(IconSource.Icons.Code))) {
addEntry(ContextMenuEntry("Local file", IconSource.Icons.File) {
OcelotDesktop.showFileChooserDialog(JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY) { file =>
Try {
for (file <- file) {
@ -56,7 +56,7 @@ class EepromItem(val eeprom: EEPROM) extends Item with ComponentItem with Persis
}
})
addEntry(ContextMenuEntry("File via URL", IconSource.Link) {
addEntry(ContextMenuEntry("File via URL", IconSource.Icons.Link) {
new InputDialog(
title = "File via URL",
onConfirmed = { text =>
@ -74,7 +74,7 @@ class EepromItem(val eeprom: EEPROM) extends Item with ComponentItem with Persis
})
if (eeprom.codePath.nonEmpty || eeprom.codeURL.nonEmpty) {
addEntry(ContextMenuEntry("Detach", IconSource.LinkSlash) {
addEntry(ContextMenuEntry("Detach", IconSource.Icons.LinkSlash) {
eeprom.codeBytes = Some(Array.empty)
})
}

View File

@ -22,7 +22,7 @@ class LinkedCardItem(val linkedCard: LinkedCard) extends Item with ComponentItem
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(
ContextMenuEntry("Set channel", IconSource.Antenna) {
ContextMenuEntry("Set channel", IconSource.Icons.Antenna) {
new TunnelDialog(
tunnel => linkedCard.tunnel = tunnel,
linkedCard.tunnel,

View File

@ -23,7 +23,7 @@ class OcelotCardItem(val ocelotCard: OcelotCard)
override def tooltipNameColor: Color = ColorScheme("OcelotCardTooltip")
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(ContextMenuEntry("Open console", IconSource.Window) {
menu.addEntry(ContextMenuEntry("Open console", IconSource.Icons.Window) {
window.open()
})

View File

@ -43,7 +43,7 @@ object RedstoneCardItem {
}
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(ContextMenuEntry("Redstone I/O", IconSource.ArrowRight) {
menu.addEntry(ContextMenuEntry("Redstone I/O", IconSource.Icons.ArrowRight) {
windowed.window.open()
})
@ -93,7 +93,7 @@ object RedstoneCardItem {
}
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(ContextMenuEntry("Bundled I/O", IconSource.LinesHorizontal) {
menu.addEntry(ContextMenuEntry("Bundled I/O", IconSource.Icons.LinesHorizontal) {
windowed.window.open()
})

View File

@ -46,7 +46,7 @@ class SoundCardItem(val soundCard: SoundCard)
}
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(ContextMenuEntry("Open card interface", IconSource.Window) {
menu.addEntry(ContextMenuEntry("Open card interface", IconSource.Icons.Window) {
window.open()
})

View File

@ -22,7 +22,7 @@ trait ComponentItem extends EntityItem {
}
}
private val copyAddressEntry = ContextMenuEntry("Copy address", IconSource.Copy) {
private val copyAddressEntry = ContextMenuEntry("Copy address", IconSource.Icons.Copy) {
UiHandler.clipboard = entity.node.address
}

View File

@ -13,7 +13,7 @@ trait CpuLikeItem extends ComponentItem {
override def entity: Entity with GenericCPU
override def fillRmbMenu(menu: ContextMenu): Unit = {
menu.addEntry(new ContextMenuSubmenu("Set architecture", Some(ContextMenuIcon(IconSource.Microchip))) {
menu.addEntry(new ContextMenuSubmenu("Set architecture", Some(ContextMenuIcon(IconSource.Icons.Microchip))) {
for (arch <- entity.allArchitectures) {
val name = MachineAPI.getArchitectureName(arch) +
(if (arch == entity.architecture) " (current)" else "")

View File

@ -97,7 +97,7 @@ object DiskItem {
realPathSetter: (() => Unit) => Unit): Unit = {
menu.addEntry(ContextMenuEntry(
if (diskRealPathAware.customRealPath.isDefined) "Change directory" else "Set directory",
IconSource.Folder,
IconSource.Icons.Folder,
) {
OcelotDesktop.showFileChooserDialog(JFileChooser.OPEN_DIALOG, JFileChooser.DIRECTORIES_ONLY) { dir =>
Try {
@ -112,7 +112,7 @@ object DiskItem {
})
if (diskRealPathAware.customRealPath.isDefined) {
menu.addEntry(ContextMenuEntry("Reset directory", IconSource.FolderSlash) {
menu.addEntry(ContextMenuEntry("Reset directory", IconSource.Icons.FolderSlash) {
realPathSetter(() => {
// trigger component_removed / component_added signals
diskRealPathAware.customRealPath = None
@ -122,7 +122,7 @@ object DiskItem {
}
def addEditDiskContextMenuEntries[T <: Window](menu: ContextMenu, windowed: Windowed[T]): Unit = {
menu.addEntry(ContextMenuEntry("Edit disk", IconSource.Edit) {
menu.addEntry(ContextMenuEntry("Edit disk", IconSource.Icons.Edit) {
windowed.window.open()
})
}

View File

@ -35,7 +35,7 @@ abstract class EntityNode(val entity: Entity with Environment) extends Node {
override def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
if (exposeAddress && entity.node != null && entity.node.address != null) {
menu.addEntry(
ContextMenuEntry("Copy address", IconSource.Copy) {
ContextMenuEntry("Copy address", IconSource.Icons.Copy) {
UiHandler.clipboard = entity.node.address
}
)

View File

@ -26,7 +26,7 @@ trait LabeledNode extends Node {
}
override def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
menu.addEntry(ContextMenuEntry("Set label", IconSource.Label) {
menu.addEntry(ContextMenuEntry("Set label", IconSource.Icons.Label) {
new InputDialog(
"Set label",
text => {

View File

@ -90,12 +90,12 @@ abstract class Node extends Widget with MouseHandler with HoverHandler with Pers
def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
if (ports.nonEmpty) {
menu.addEntry(ContextMenuEntry("Disconnect", IconSource.LinkSlash, SoundSource.InterfaceClickLow) {
menu.addEntry(ContextMenuEntry("Disconnect", IconSource.Icons.LinkSlash, SoundSource.InterfaceClickLow) {
disconnectFromAll()
})
}
menu.addEntry(ContextMenuEntry("Remove", IconSource.Delete, SoundSource.InterfaceClickLow) {
menu.addEntry(ContextMenuEntry("Remove", IconSource.Icons.Delete, SoundSource.InterfaceClickLow) {
destroy()
})
}

View File

@ -12,7 +12,7 @@ class NoteBlockNode(val noteBlock: NoteBlock) extends NoteBlockNodeBase(noteBloc
override def rotatable: Boolean = false
override def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
menu.addEntry(new ContextMenuSubmenu("Instrument", Some(ContextMenuIcon(IconSource.Guitar))) {
menu.addEntry(new ContextMenuSubmenu("Instrument", Some(ContextMenuIcon(IconSource.Icons.Guitar))) {
{
val maxLen = NoteBlockNode.Instruments.map(_._2.length).max

View File

@ -194,7 +194,7 @@ object RackNode {
def addContextMenuEntriesOfMountable(menu: ContextMenu, item: Option[RackMountableItem]): Unit = {
item match {
case Some(serverItem: ServerItem) =>
menu.addEntry(ContextMenuEntry("Set up", IconSource.Window) {
menu.addEntry(ContextMenuEntry("Set up", IconSource.Icons.Window) {
serverItem.window.open()
})
@ -217,7 +217,7 @@ object RackNode {
"Change floppy"
else
"Set floppy",
IconSource.Save,
IconSource.Icons.Save,
) {
diskDriveMountableItem.window.open()
})

View File

@ -100,25 +100,25 @@ class ScreenNode(val screen: Screen)
override def setupContextMenu(menu: ContextMenu, event: ClickEvent): Unit = {
// no synchronization here: the methods to turn the screen on/off are indirect.
if (screen.getPowerState) {
menu.addEntry(ContextMenuEntry("Turn off", IconSource.Power) {
menu.addEntry(ContextMenuEntry("Turn off", IconSource.Icons.Power) {
screen.setPowerState(false)
})
} else {
menu.addEntry(ContextMenuEntry("Turn on", IconSource.Power) {
menu.addEntry(ContextMenuEntry("Turn on", IconSource.Icons.Power) {
screen.setPowerState(true)
})
}
menu.addEntry(ContextMenuEntry("Set aspect ratio", IconSource.AspectRatio) {
menu.addEntry(ContextMenuEntry("Set aspect ratio", IconSource.Icons.AspectRatio) {
new ScreenAspectRatioDialog(this).show()
})
if (keyboard.isDefined) {
menu.addEntry(ContextMenuEntry("Remove keyboard", IconSource.KeyboardOff) {
menu.addEntry(ContextMenuEntry("Remove keyboard", IconSource.Icons.KeyboardOff) {
detachKeyboard()
})
} else {
menu.addEntry(ContextMenuEntry("Add keyboard", IconSource.Keyboard) {
menu.addEntry(ContextMenuEntry("Add keyboard", IconSource.Icons.Keyboard) {
attachKeyboard()
})
}

View File

@ -79,7 +79,7 @@ class DiskEditWindow(item: DiskItem) extends PanelWindow {
for (dyeColor <- row) {
def isColorSelected: Boolean = dyeColor == item.color.get
val floppyIcon = IconSource.Items.FloppyDisk(dyeColor).path
val floppyIcon = IconSource.Items.FloppyDisk(dyeColor)
children :+= new IconButton(
floppyIcon,
floppyIcon,

View File

@ -4,7 +4,7 @@ import ocelot.desktop.ColorScheme
import ocelot.desktop.audio.{ClickSoundSource, SoundSource}
import ocelot.desktop.color.Color
import ocelot.desktop.geometry.Size2D
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.ui.event.handlers.{HoverHandler, MouseHandler}
import ocelot.desktop.ui.event.{ClickEvent, HoverEvent, MouseEvent}
import ocelot.desktop.ui.widget.IconButton.{AnimationSpeed, Mode}
@ -14,8 +14,8 @@ import ocelot.desktop.util.animation.{ColorAnimation, ValueAnimation}
import ocelot.desktop.util.{DrawUtils, Spritesheet}
class IconButton(
releasedIcon: String,
pressedIcon: String,
releasedIconSource: IconSource,
pressedIconSource: IconSource,
releasedColor: Color = Color.White,
pressedColor: Color = Color.White,
sizeMultiplier: Float = 1,
@ -135,9 +135,9 @@ class IconButton(
size = minimumSize
private def releasedIconSize: Size2D = Spritesheet.spriteSize(releasedIcon) * sizeMultiplier
private def releasedIconSize: Size2D = Spritesheet.spriteSize(releasedIconSource) * sizeMultiplier
private def pressedIconSize: Size2D = Spritesheet.spriteSize(pressedIcon) * sizeMultiplier
private def pressedIconSize: Size2D = Spritesheet.spriteSize(pressedIconSource) * sizeMultiplier
override def minimumSize: Size2D = releasedIconSize.max(pressedIconSize) + (padding * 2.0f)
override def maximumSize: Size2D = minimumSize
@ -154,7 +154,7 @@ class IconButton(
if (iconMixAnimation.value < 1f) {
g.sprite(
releasedIcon,
releasedIconSource,
position + (size - releasedIconSize) / 2f,
releasedIconSize,
releasedColorAnimation.color.toRGBANorm.mapA(_ * (1f - iconMixAnimation.value)),
@ -163,7 +163,7 @@ class IconButton(
if (iconMixAnimation.value > 0f) {
g.sprite(
pressedIcon,
pressedIconSource,
position + (size - pressedIconSize) / 2f,
pressedIconSize,
pressedColorAnimation.color.toRGBANorm.mapA(_ * iconMixAnimation.value),

View File

@ -23,28 +23,28 @@ class MenuBar extends Widget {
addEntry(new MenuBarSubmenu(
"File",
menu => {
menu.addEntry(ContextMenuEntry("New", IconSource.Plus) { OcelotDesktop.newWorkspace() })
menu.addEntry(ContextMenuEntry("Open", IconSource.Folder) { OcelotDesktop.showOpenDialog() })
menu.addEntry(ContextMenuEntry("Save", IconSource.Save) { OcelotDesktop.save() })
menu.addEntry(ContextMenuEntry("Save as", IconSource.SaveAs) { OcelotDesktop.saveAs() })
menu.addEntry(ContextMenuEntry("New", IconSource.Icons.Plus) { OcelotDesktop.newWorkspace() })
menu.addEntry(ContextMenuEntry("Open", IconSource.Icons.Folder) { OcelotDesktop.showOpenDialog() })
menu.addEntry(ContextMenuEntry("Save", IconSource.Icons.Save) { OcelotDesktop.save() })
menu.addEntry(ContextMenuEntry("Save as", IconSource.Icons.SaveAs) { OcelotDesktop.saveAs() })
menu.addSeparator()
menu.addEntry(ContextMenuEntry("Exit", IconSource.Cross, SoundSource.InterfaceClickLow) { OcelotDesktop.exit() })
menu.addEntry(ContextMenuEntry("Exit", IconSource.Icons.Cross, SoundSource.InterfaceClickLow) { OcelotDesktop.exit() })
},
))
addEntry(new MenuBarSubmenu(
"Player",
menu => {
menu.addEntry(ContextMenuEntry("Create new", IconSource.Plus) { OcelotDesktop.showAddPlayerDialog() })
menu.addEntry(ContextMenuEntry("Create new", IconSource.Icons.Plus) { OcelotDesktop.showAddPlayerDialog() })
menu.addSeparator()
OcelotDesktop.players.foreach(player => {
menu.addEntry(new ContextMenuSubmenu(
s"${if (player == OcelotDesktop.players.head) "● " else " "}${player.nickname}",
onClick = () => OcelotDesktop.selectPlayer(player.nickname),
) {
addEntry(ContextMenuEntry("Remove", IconSource.Delete, SoundSource.InterfaceClickLow) {
addEntry(ContextMenuEntry("Remove", IconSource.Icons.Delete, SoundSource.InterfaceClickLow) {
OcelotDesktop.removePlayer(player.nickname)
})
})
@ -57,12 +57,12 @@ class MenuBar extends Widget {
addEntry(new MenuBarSubmenu(
"Help",
menu => {
menu.addEntry(ContextMenuEntry("Check for Updates", IconSource.Help) {
menu.addEntry(ContextMenuEntry("Check for Updates", IconSource.Icons.Help) {
new UpdateCheckerDialog().show()
})
menu.addSeparator()
menu.addEntry(ContextMenuEntry("Manual", IconSource.Book) {}.setEnabled(false))
menu.addEntry(ContextMenuEntry("About", IconSource.Ocelot) { new AboutDialog().show() })
menu.addEntry(ContextMenuEntry("Manual", IconSource.Icons.Book) {}.setEnabled(false))
menu.addEntry(ContextMenuEntry("About", IconSource.Icons.Ocelot) { new AboutDialog().show() })
},
))

View File

@ -3,6 +3,7 @@ package ocelot.desktop.ui.widget
import ocelot.desktop.ColorScheme
import ocelot.desktop.audio.{ClickSoundSource, SoundSource}
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.layout.LinearLayout
import ocelot.desktop.ui.widget.modal.ModalDialog
@ -37,27 +38,27 @@ class TunnelDialog(
children :+= input
children :+= new PaddingBox(
new IconButton(
"icons/ButtonRandomize",
"icons/ButtonRandomize",
IconSource.Icons.ButtonRandomize,
IconSource.Icons.ButtonRandomize,
drawBackground = true,
releasedColor = ColorScheme("ButtonForeground"),
padding = 3.5f,
tooltip = Some("Generate random channel name"),
) {
override def onPressed(): Unit = input.text = UUID.randomUUID().toString
override def onClicked(): Unit = input.text = UUID.randomUUID().toString
},
new Padding2D(left = 8, right = 8),
)
children :+= new IconButton(
"icons/ButtonClipboard",
"icons/ButtonCheck",
IconSource.Icons.ButtonClipboard,
IconSource.Icons.ButtonCheck,
drawBackground = true,
releasedColor = ColorScheme("ButtonForeground"),
pressedColor = ColorScheme("ButtonConfirm"),
padding = 3.5f,
tooltip = Some("Copy channel name to the clipboard"),
) {
override def onPressed(): Unit = UiHandler.clipboard = input.text
override def onClicked(): Unit = UiHandler.clipboard = input.text
}
}

View File

@ -4,7 +4,7 @@ import ocelot.desktop.color.Color
import ocelot.desktop.geometry.FloatUtils.ExtendedFloat
import ocelot.desktop.geometry._
import ocelot.desktop.graphics.scene.{Camera3D, Scene3D}
import ocelot.desktop.graphics.{Graphics, Viewport3D}
import ocelot.desktop.graphics.{Graphics, IconSource, Viewport3D}
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.handlers.{HoverHandler, MouseHandler}
import ocelot.desktop.ui.event.sources.KeyEvents
@ -92,13 +92,13 @@ abstract class Viewport3DWidget extends Widget with MouseHandler with HoverHandl
protected def setupToolbar(toolbar: Widget): Unit = {
toolbar.children :+= new IconButton(
"icons/Home",
"icons/Home",
IconSource.Icons.Home,
IconSource.Icons.Home,
pressedColor = Color.White.withAlpha(0.5f),
releasedColor = Color.White.withAlpha(0.2f),
darkenActiveColorFactor = 0.5f,
) {
override def onPressed(): Unit = {
override def onClicked(): Unit = {
cameraFinalTarget = HomeTarget
cameraFinalRotation = HomeRotation
cameraFinalDistance = HomeDistance

View File

@ -46,7 +46,7 @@ class UpdateCheckerDialog extends ModalDialog with Logging {
// loading screen
container.children :+= new Label("Checking development news...")
container.children :+= new PaddingBox(new Icon(IconSource.Loading, color = ColorScheme("Label")),
container.children :+= new PaddingBox(new Icon(IconSource.Icons.Loading, color = ColorScheme("Label")),
Padding2D(16, 0, 0, 90))
// check the API

View File

@ -31,7 +31,7 @@ class NotificationDialog(message: String, notificationType: NotificationType = N
// Icon
children :+= new PaddingBox(
new Icon(IconSource.Notification(notificationType), Size2D(22, 22)),
new Icon(IconSource.Icons.Notification(notificationType), Size2D(22, 22)),
Padding2D.equal(10),
)

View File

@ -15,7 +15,7 @@ import org.lwjgl.input.Keyboard
class KeymapSettingsTab extends SettingsTab {
override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 8)
override val icon: IconSource = IconSource.SettingsKeymap
override val icon: IconSource = IconSource.Icons.SettingsKeymap
override val label: String = "Keymap"
private def section(title: String, keybinds: Seq[Keybind]): Widget = new PaddingBox(new Widget {

View File

@ -10,7 +10,7 @@ import ocelot.desktop.util.Orientation
class SoundSettingsTab extends SettingsTab {
override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 8)
override val icon: IconSource = IconSource.SettingsSound
override val icon: IconSource = IconSource.Icons.SettingsSound
override val label: String = "Sound"
private def addSlider(name: String, value: Float, valueSetter: Float => Unit): Unit = {

View File

@ -17,7 +17,7 @@ import scala.util.{Failure, Success}
class SystemSettingsTab extends SettingsTab with Logging {
private val OpenComputersConfigResource = "/application.conf"
override val icon: IconSource = IconSource.SettingsSystem
override val icon: IconSource = IconSource.Icons.SettingsSystem
override val label: String = "System"
override def applySettings(): Unit = {
@ -43,15 +43,15 @@ class SystemSettingsTab extends SettingsTab with Logging {
children :+= new PaddingBox(textInput, Padding2D(right = 8))
children :+= new IconButton(
"icons/Folder",
"icons/Folder",
IconSource.Icons.Folder,
IconSource.Icons.Folder,
releasedColor = ColorScheme("ButtonForeground"),
pressedColor = ColorScheme("ButtonForegroundPressed"),
drawBackground = true,
padding = 3.5f,
tooltip = Some("Search for OpenComputers configuration file"),
) {
override def onPressed(): Unit = {
override def onClicked(): Unit = {
OcelotDesktop.showFileChooserDialog(JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY) {
case Some(dir) =>
setConfigPath(dir.getCanonicalPath)

View File

@ -9,7 +9,7 @@ import ocelot.desktop.ui.widget.{Checkbox, Label, PaddingBox, Slider, Widget}
import ocelot.desktop.util.MathUtils.roundAt
class UISettingsTab extends SettingsTab {
override val icon: IconSource = IconSource.SettingsUI
override val icon: IconSource = IconSource.Icons.SettingsUI
override val label: String = "UI"
override def applySettings(): Unit = {

View File

@ -109,7 +109,7 @@ class SlotWidget[I <: Item](private val slot: Inventory#Slot)(implicit slotItemT
for (item <- item) {
item.fillRmbMenu(menu)
menu.addEntry(
ContextMenuEntry("Remove", IconSource.Delete, SoundSource.InterfaceClickLow) {
ContextMenuEntry("Remove", IconSource.Icons.Delete, SoundSource.InterfaceClickLow) {
slot.remove()
}
)

View File

@ -67,13 +67,13 @@ class StatusBar extends Widget {
case ClickEvent(MouseEvent.Button.Right, pos) =>
val menu = new ContextMenu
menu.addEntry(
ContextMenuEntry("Change simulation speed", IconSource.Edit) {
ContextMenuEntry("Change simulation speed", IconSource.Icons.Edit) {
new ChangeSimulationSpeedDialog().show()
}
)
menu.addEntry(
ContextMenuEntry("Reset simulation speed", IconSource.Restart) {
ContextMenuEntry("Reset simulation speed", IconSource.Icons.Restart) {
OcelotDesktop.ticker.tickInterval = 50.millis
}
)

View File

@ -1,5 +1,6 @@
package ocelot.desktop.ui.widget.window
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.ui.layout.{AlignItems, Layout, LinearLayout}
import ocelot.desktop.ui.widget.{IconButton, Label, Widget}
import ocelot.desktop.util.Orientation
@ -27,8 +28,8 @@ class TitleBar(val window: Window) extends Widget {
}
children :+= new IconButton(
"icons/Pin",
"icons/Unpin",
IconSource.Icons.Pin,
IconSource.Icons.Unpin,
mode = IconButton.Mode.Switch,
darkenActiveColorFactor = 0.5f,
model = IconButton.ReadOnlyModel(isPinned),
@ -39,10 +40,10 @@ class TitleBar(val window: Window) extends Widget {
}
children :+= new IconButton(
"icons/Close",
"icons/Close",
IconSource.Icons.Close,
IconSource.Icons.Close,
darkenActiveColorFactor = 0.5f,
) {
override def onPressed(): Unit = onCloseRequested()
override def onClicked(): Unit = onCloseRequested()
}
}

View File

@ -48,16 +48,16 @@ trait ComputerAware
def addPowerContextMenuEntries(menu: ContextMenu): Unit = {
if (computer.machine.isRunning) {
menu.addEntry(ContextMenuEntry("Turn off", IconSource.Power) {
menu.addEntry(ContextMenuEntry("Turn off", IconSource.Icons.Power) {
turnOff()
})
menu.addEntry(ContextMenuEntry("Reboot", IconSource.Restart) {
menu.addEntry(ContextMenuEntry("Reboot", IconSource.Icons.Restart) {
turnOff()
turnOn()
})
} else {
menu.addEntry(ContextMenuEntry("Turn on", IconSource.Power) {
menu.addEntry(ContextMenuEntry("Turn on", IconSource.Icons.Power) {
turnOn()
})
}
@ -65,7 +65,7 @@ trait ComputerAware
def addTierContextMenuEntries(menu: ContextMenu, maxNonCreativeTier: Tier = Tier.Three): Unit = {
menu.addEntry(
new ContextMenuSubmenu("Change tier", Some(ContextMenuIcon(IconSource.Tiers))) {
new ContextMenuSubmenu("Change tier", Some(ContextMenuIcon(IconSource.Icons.Tiers))) {
def addTierEntry(tier: Tier): Unit = {
val entry = ContextMenuEntry(s"${tier.label}${if (tier == computer.tier) " (current)" else ""}") {
changeTier(tier)

View File

@ -61,7 +61,7 @@ trait DiskDriveAware extends Logging with SyncedInventory with DefaultSlotItemsF
}
def addEjectContextMenuEntry(menu: ContextMenu): Unit = {
menu.addEntry(ContextMenuEntry("Eject", IconSource.Eject) {
menu.addEntry(ContextMenuEntry("Eject", IconSource.Icons.Eject) {
eject()
})
}

View File

@ -2,7 +2,7 @@ package ocelot.desktop.windows
import ocelot.desktop.audio.{ClickSoundSource, SoundSource}
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.inventory.item.ServerItem
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
import ocelot.desktop.ui.widget._
@ -24,8 +24,8 @@ class ComputerWindow(computerAware: ComputerAware) extends BasicWindow {
bottomDrawerAnimation.goDown()
private val drawerButton = new IconButton(
"buttons/BottomDrawerOpen",
"buttons/BottomDrawerClose",
IconSource.Buttons.BottomDrawerOpen,
IconSource.Buttons.BottomDrawerClose,
mode = IconButton.Mode.Switch,
darkenActiveColorFactor = 0.2f,
tooltip = Some("Toggle computer usage histogram"),
@ -200,8 +200,8 @@ class ComputerWindow(computerAware: ComputerAware) extends BasicWindow {
// Power button
children :+= new IconButton(
"buttons/PowerOff",
"buttons/PowerOn",
IconSource.Buttons.PowerOff,
IconSource.Buttons.PowerOn,
mode = IconButton.Mode.Switch,
sizeMultiplier = 2,
model = IconButton.ReadOnlyModel(computerAware.computer.machine.isRunning),

View File

@ -4,6 +4,7 @@ import ocelot.desktop.OcelotDesktop
import ocelot.desktop.color.{Color, IntColor}
import ocelot.desktop.geometry.FloatUtils.ExtendedFloat
import ocelot.desktop.geometry._
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.graphics.mesh.{Mesh3D, MeshBuilder3D}
import ocelot.desktop.graphics.scene.{Scene3D, SceneMesh3D}
import ocelot.desktop.node.nodes.HologramProjectorNode
@ -138,8 +139,8 @@ class HologramProjectorWindow(val hologramProjectorNode: HologramProjectorNode)
super.setupToolbar(toolbar)
toolbar.children :+= new IconButton(
"icons/GridOff",
"icons/Grid",
IconSource.Icons.GridOff,
IconSource.Icons.Grid,
pressedColor = Color.White.withAlpha(0.5f),
releasedColor = Color.White.withAlpha(0.2f),
mode = IconButton.Mode.Switch,

View File

@ -3,7 +3,7 @@ package ocelot.desktop.windows
import ocelot.desktop.color.{Color, IntColor}
import ocelot.desktop.entity.OpenFMRadio
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.node.nodes.OpenFMRadioNode
import ocelot.desktop.ui.layout.{AlignItems, Layout, LinearLayout}
import ocelot.desktop.ui.widget._
@ -28,11 +28,11 @@ class OpenFMRadioWindow(radioNode: OpenFMRadioNode) extends BasicWindow {
private def addVolumeUpOrDownButton(isUp: Boolean, x: Float): Unit = {
children :+= new PaddingBox(
new IconButton(
s"buttons/OpenFMRadioVolume${if (isUp) "Up" else "Down"}Off",
s"buttons/OpenFMRadioVolume${if (isUp) "Up" else "Down"}On",
IconSource.Buttons.OpenFMRadioVolumeOff(isUp),
IconSource.Buttons.OpenFMRadioVolumeOn(isUp),
sizeMultiplier = scale,
) {
override def onPressed(): Unit = {
override def onClicked(): Unit = {
if (isUp)
radio.volUp()
else
@ -60,8 +60,8 @@ class OpenFMRadioWindow(radioNode: OpenFMRadioNode) extends BasicWindow {
// Redstone button
children :+= new PaddingBox(
new IconButton(
"buttons/OpenFMRadioRedstoneOff",
"buttons/OpenFMRadioRedstoneOn",
IconSource.Buttons.OpenFMRadioRedstoneOff,
IconSource.Buttons.OpenFMRadioRedstoneOn,
mode = IconButton.Mode.Switch,
sizeMultiplier = scale,
model = new IconButton.Model { override var pressed: Boolean = radio.isListenRedstone },
@ -72,11 +72,11 @@ class OpenFMRadioWindow(radioNode: OpenFMRadioNode) extends BasicWindow {
// Close button
children :+= new PaddingBox(
new IconButton(
"buttons/OpenFMRadioCloseOff",
"buttons/OpenFMRadioCloseOn",
IconSource.Buttons.OpenFMRadioCloseOff,
IconSource.Buttons.OpenFMRadioCloseOn,
sizeMultiplier = scale,
) {
override def onPressed(): Unit = close()
override def onClicked(): Unit = close()
},
Padding2D(0, 0, 0, 10),
)
@ -101,8 +101,8 @@ class OpenFMRadioWindow(radioNode: OpenFMRadioNode) extends BasicWindow {
// Start/stop button
children :+= new PaddingBox(
new IconButton(
"buttons/OpenFMRadioStartOff",
"buttons/OpenFMRadioStopOn",
IconSource.Buttons.OpenFMRadioStartOff,
IconSource.Buttons.OpenFMRadioStopOn,
mode = IconButton.Mode.Switch,
sizeMultiplier = scale,
model = IconButton.ReadOnlyModel(radio.isPlaying),

View File

@ -4,7 +4,7 @@ import ocelot.desktop.ColorScheme
import ocelot.desktop.audio.{ClickSoundSource, SoundSource}
import ocelot.desktop.color.Color
import ocelot.desktop.geometry.{Padding2D, Rect2D, Size2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.inventory.item.{NetworkCardItem, ServerItem}
import ocelot.desktop.node.nodes.RackNode
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
@ -256,8 +256,8 @@ class RackWindow(rackNode: RackNode) extends PanelWindow {
// Relay enable button
children :+= new PaddingBox(
new IconButton(
"buttons/RackRelayOff",
"buttons/RackRelayOn",
IconSource.Buttons.RackRelayOff,
IconSource.Buttons.RackRelayOn,
mode = IconButton.Mode.Switch,
sizeMultiplier = 2,
model = IconButton.ReadOnlyModel(rackNode.rack.isRelayEnabled),

View File

@ -3,7 +3,8 @@ package ocelot.desktop.windows
import ocelot.desktop.audio.{Audio, ClickSoundSource, SoundBuffers, SoundCategory, SoundSource}
import ocelot.desktop.color.{Color, RGBAColorNorm}
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.graphics.IconSource.Window.Tape.TapeButtonIconSource
import ocelot.desktop.inventory.item.TapeItem
import ocelot.desktop.node.nodes.TapeDriveNode
import ocelot.desktop.ui.layout.{AlignItems, Layout, LinearLayout}
@ -110,13 +111,13 @@ class TapeDriveWindow(val tapeDriveNode: TapeDriveNode) extends PanelWindow {
override protected val layout: Layout = new LinearLayout(this, gap = 0)
def addButton(
sprite: String,
source: TapeButtonIconSource,
pressedState: TapeDriveState.State,
isToggle: Boolean = true,
): Unit = {
children :+= new IconButton(
s"window/tape/$sprite",
s"window/tape/${sprite}Pressed",
source.Released,
source.Pressed,
sizeMultiplier = 2,
mode =
if (isToggle)
@ -130,16 +131,26 @@ class TapeDriveWindow(val tapeDriveNode: TapeDriveNode) extends PanelWindow {
DefaultModel(false)
},
) with HoverHighlight {
override def onPressed(): Unit = tapeDriveNode.tapeDrive.state.switchState(pressedState)
override def onPressed(): Unit = {
if (isToggle) {
tapeDriveNode.tapeDrive.state.switchState(pressedState)
}
}
override def onClicked(): Unit = {
if (!isToggle) {
tapeDriveNode.tapeDrive.state.switchState(pressedState)
}
}
override protected def clickSoundSource: ClickSoundSource = TapeButtonSound
}
}
addButton("Back", TapeDriveState.State.Rewinding)
addButton("Play", TapeDriveState.State.Playing)
addButton("Stop", TapeDriveState.State.Stopped, isToggle = false)
addButton("Forward", TapeDriveState.State.Forwarding)
addButton(IconSource.Window.Tape.Back, TapeDriveState.State.Rewinding)
addButton(IconSource.Window.Tape.Play, TapeDriveState.State.Playing)
addButton(IconSource.Window.Tape.Stop, TapeDriveState.State.Stopped, isToggle = false)
addButton(IconSource.Window.Tape.Forward, TapeDriveState.State.Forwarding)
}
},
Padding2D(top = 10, left = 18),