Merge branch 'feature/check-for-updates' into 'develop'
Allow to check for updates See merge request cc-ru/ocelot/ocelot-desktop!73
@ -1 +1 @@
|
|||||||
Subproject commit 6fc005d04d785d76fd3330ac304cc717eb99e752
|
Subproject commit ece53729967381bc1278479242a147539f33c60a
|
||||||
BIN
sprites/Loading.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
sprites/Logo.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
sprites/icons/Book.png
Normal file
|
After Width: | Height: | Size: 533 B |
BIN
sprites/icons/Help.png
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
sprites/icons/Ocelot.png
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
sprites/loading.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
sprites/logo.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@ -1,3 +1,12 @@
|
|||||||
|
Accent = #bd353e
|
||||||
|
|
||||||
|
AboutLogo = #ffffffee
|
||||||
|
AboutForeground = #eeeeee
|
||||||
|
AboutForegroundSubtle = #eeeeeeee
|
||||||
|
AboutButtonForeground = #222222
|
||||||
|
AboutButtonBorder = #444444
|
||||||
|
AboutButtonBackground = #777777
|
||||||
|
|
||||||
PortDown = #8382d8
|
PortDown = #8382d8
|
||||||
PortUp = #75bdc1
|
PortUp = #75bdc1
|
||||||
PortNorth = #c8ca5f
|
PortNorth = #c8ca5f
|
||||||
@ -23,7 +32,7 @@ ConnectionDel = #7f3333
|
|||||||
Connection = #909090
|
Connection = #909090
|
||||||
|
|
||||||
NodeSelectorRing = #4c7f66
|
NodeSelectorRing = #4c7f66
|
||||||
NodeSelectorBackground = #000000BB
|
NodeSelectorBackground = #000000bb
|
||||||
|
|
||||||
ContextMenuBackground = #222222ee
|
ContextMenuBackground = #222222ee
|
||||||
ContextMenuBorder = #444444
|
ContextMenuBorder = #444444
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 140 KiB |
@ -1,295 +1,300 @@
|
|||||||
BackgroundPattern 0 0 304 304
|
BackgroundPattern 0 0 304 304
|
||||||
BarSegment 29 499 16 4
|
BarSegment 385 434 16 4
|
||||||
Empty 278 351 16 16
|
Empty 327 572 16 16
|
||||||
EmptySlot 256 376 18 18
|
EmptySlot 305 597 18 18
|
||||||
Knob 692 0 50 50
|
Knob 203 434 50 50
|
||||||
KnobCenter 743 0 50 50
|
KnobCenter 254 434 50 50
|
||||||
KnobLimits 794 0 50 50
|
KnobLimits 305 434 50 50
|
||||||
ShadowBorder 0 538 1 24
|
Loading 0 305 48 448
|
||||||
ShadowCorner 153 351 24 24
|
Logo 305 0 168 200
|
||||||
TabArrow 0 484 8 14
|
ShadowBorder 49 720 1 24
|
||||||
blocks/Generic 295 351 16 16
|
ShadowCorner 202 572 24 24
|
||||||
blocks/HologramEffect 8 547 4 4
|
TabArrow 49 705 8 14
|
||||||
blocks/HologramProjector1Top 312 351 16 16
|
blocks/Generic 344 572 16 16
|
||||||
blocks/HologramProjector2Top 329 351 16 16
|
blocks/HologramEffect 57 729 4 4
|
||||||
blocks/HologramProjectorSide 346 351 16 16
|
blocks/HologramProjector1Top 361 572 16 16
|
||||||
buttons/BottomDrawerClose 275 376 18 18
|
blocks/HologramProjector2Top 378 572 16 16
|
||||||
buttons/BottomDrawerOpen 294 376 18 18
|
blocks/HologramProjectorSide 395 572 16 16
|
||||||
buttons/OpenFMRadioCloseOff 48 510 7 8
|
buttons/BottomDrawerClose 324 597 18 18
|
||||||
buttons/OpenFMRadioCloseOn 56 510 7 8
|
buttons/BottomDrawerOpen 343 597 18 18
|
||||||
buttons/OpenFMRadioRedstoneOff 3 510 8 8
|
buttons/OpenFMRadioCloseOff 404 445 7 8
|
||||||
buttons/OpenFMRadioRedstoneOn 12 510 8 8
|
buttons/OpenFMRadioCloseOn 412 445 7 8
|
||||||
buttons/OpenFMRadioStartOff 178 351 24 24
|
buttons/OpenFMRadioRedstoneOff 359 445 8 8
|
||||||
buttons/OpenFMRadioStartOn 203 351 24 24
|
buttons/OpenFMRadioRedstoneOn 368 445 8 8
|
||||||
buttons/OpenFMRadioStopOff 228 351 24 24
|
buttons/OpenFMRadioStartOff 227 572 24 24
|
||||||
buttons/OpenFMRadioStopOn 253 351 24 24
|
buttons/OpenFMRadioStartOn 252 572 24 24
|
||||||
buttons/OpenFMRadioVolumeDownOff 9 484 10 10
|
buttons/OpenFMRadioStopOff 277 572 24 24
|
||||||
buttons/OpenFMRadioVolumeDownOn 20 484 10 10
|
buttons/OpenFMRadioStopOn 302 572 24 24
|
||||||
buttons/OpenFMRadioVolumeUpOff 31 484 10 10
|
buttons/OpenFMRadioVolumeDownOff 58 705 10 10
|
||||||
buttons/OpenFMRadioVolumeUpOn 42 484 10 10
|
buttons/OpenFMRadioVolumeDownOn 69 705 10 10
|
||||||
buttons/PowerOff 313 376 18 18
|
buttons/OpenFMRadioVolumeUpOff 80 705 10 10
|
||||||
buttons/PowerOn 332 376 18 18
|
buttons/OpenFMRadioVolumeUpOn 91 705 10 10
|
||||||
buttons/RackRelayOff 153 332 65 18
|
buttons/PowerOff 362 597 18 18
|
||||||
buttons/RackRelayOn 219 332 65 18
|
buttons/PowerOn 381 597 18 18
|
||||||
icons/Antenna 363 351 16 16
|
buttons/RackRelayOff 202 553 65 18
|
||||||
icons/ArrowRight 380 351 16 16
|
buttons/RackRelayOn 268 553 65 18
|
||||||
icons/AspectRatio 397 351 16 16
|
icons/Antenna 412 572 16 16
|
||||||
icons/ButtonCheck 153 409 17 17
|
icons/ArrowRight 429 572 16 16
|
||||||
icons/ButtonClipboard 171 409 17 17
|
icons/AspectRatio 446 572 16 16
|
||||||
icons/ButtonRandomize 189 409 17 17
|
icons/Book 463 572 16 16
|
||||||
icons/CPU 414 351 16 16
|
icons/ButtonCheck 202 630 17 17
|
||||||
icons/Card 431 351 16 16
|
icons/ButtonClipboard 220 630 17 17
|
||||||
icons/Close 0 451 15 14
|
icons/ButtonRandomize 238 630 17 17
|
||||||
icons/Code 448 351 16 16
|
icons/CPU 480 572 16 16
|
||||||
icons/ComponentBus 465 351 16 16
|
icons/Card 497 572 16 16
|
||||||
icons/Copy 482 351 16 16
|
icons/Close 49 672 15 14
|
||||||
icons/Cross 499 351 16 16
|
icons/Code 514 572 16 16
|
||||||
icons/Delete 516 351 16 16
|
icons/ComponentBus 531 572 16 16
|
||||||
icons/DragLMB 351 376 21 14
|
icons/Copy 548 572 16 16
|
||||||
icons/DragRMB 373 376 21 14
|
icons/Cross 565 572 16 16
|
||||||
icons/EEPROM 533 351 16 16
|
icons/Delete 582 572 16 16
|
||||||
icons/Edit 550 351 16 16
|
icons/DragLMB 400 597 21 14
|
||||||
icons/Eject 567 351 16 16
|
icons/DragRMB 422 597 21 14
|
||||||
icons/File 584 351 16 16
|
icons/EEPROM 599 572 16 16
|
||||||
icons/Floppy 601 351 16 16
|
icons/Edit 616 572 16 16
|
||||||
icons/Folder 618 351 16 16
|
icons/Eject 633 572 16 16
|
||||||
icons/FolderSlash 635 351 16 16
|
icons/File 650 572 16 16
|
||||||
icons/Grid 187 376 22 22
|
icons/Floppy 667 572 16 16
|
||||||
icons/GridOff 210 376 22 22
|
icons/Folder 684 572 16 16
|
||||||
icons/HDD 652 351 16 16
|
icons/FolderSlash 701 572 16 16
|
||||||
icons/Home 233 376 22 22
|
icons/Grid 236 597 22 22
|
||||||
icons/LMB 84 466 11 14
|
icons/GridOff 259 597 22 22
|
||||||
icons/Label 669 351 16 16
|
icons/HDD 718 572 16 16
|
||||||
icons/LinesHorizontal 686 351 16 16
|
icons/Help 735 572 16 16
|
||||||
icons/Link 703 351 16 16
|
icons/Home 282 597 22 22
|
||||||
icons/LinkSlash 720 351 16 16
|
icons/LMB 133 687 11 14
|
||||||
icons/Memory 737 351 16 16
|
icons/Label 752 572 16 16
|
||||||
icons/Microchip 754 351 16 16
|
icons/LinesHorizontal 769 572 16 16
|
||||||
icons/NA 771 351 16 16
|
icons/Link 786 572 16 16
|
||||||
icons/NotificationError 108 466 11 11
|
icons/LinkSlash 803 572 16 16
|
||||||
icons/NotificationInfo 120 466 11 11
|
icons/Memory 820 572 16 16
|
||||||
icons/NotificationWarning 132 466 11 11
|
icons/Microchip 837 572 16 16
|
||||||
icons/Pin 39 466 14 14
|
icons/NA 854 572 16 16
|
||||||
icons/Plus 788 351 16 16
|
icons/NotificationError 157 687 11 11
|
||||||
icons/Power 805 351 16 16
|
icons/NotificationInfo 169 687 11 11
|
||||||
icons/RMB 96 466 11 14
|
icons/NotificationWarning 181 687 11 11
|
||||||
icons/Restart 822 351 16 16
|
icons/Ocelot 871 572 16 16
|
||||||
icons/Save 839 351 16 16
|
icons/Pin 88 687 14 14
|
||||||
icons/SaveAs 856 351 16 16
|
icons/Plus 888 572 16 16
|
||||||
icons/Server 873 351 16 16
|
icons/Power 905 572 16 16
|
||||||
icons/SettingsSound 0 466 12 17
|
icons/RMB 145 687 11 14
|
||||||
icons/SettingsSystem 13 466 12 17
|
icons/Restart 922 572 16 16
|
||||||
icons/SettingsUI 26 466 12 17
|
icons/Save 939 572 16 16
|
||||||
icons/Tier0 890 351 16 16
|
icons/SaveAs 956 572 16 16
|
||||||
icons/Tier1 907 351 16 16
|
icons/Server 973 572 16 16
|
||||||
icons/Tier2 924 351 16 16
|
icons/SettingsSound 49 687 12 17
|
||||||
icons/Tiers 941 351 16 16
|
icons/SettingsSystem 62 687 12 17
|
||||||
icons/Unpin 54 466 14 14
|
icons/SettingsUI 75 687 12 17
|
||||||
icons/WaveLFSR 580 434 24 10
|
icons/Tier0 990 572 16 16
|
||||||
icons/WaveNoise 605 434 24 10
|
icons/Tier1 1007 572 16 16
|
||||||
icons/WaveSawtooth 630 434 24 10
|
icons/Tier2 334 553 16 16
|
||||||
icons/WaveSine 655 434 24 10
|
icons/Tiers 351 553 16 16
|
||||||
icons/WaveSquare 680 434 24 10
|
icons/Unpin 103 687 14 14
|
||||||
icons/WaveTriangle 705 434 24 10
|
icons/WaveLFSR 816 655 24 10
|
||||||
icons/Window 958 351 16 16
|
icons/WaveNoise 841 655 24 10
|
||||||
icons/WireArrowLeft 2 538 4 8
|
icons/WaveSawtooth 866 655 24 10
|
||||||
icons/WireArrowRight 7 538 4 8
|
icons/WaveSine 891 655 24 10
|
||||||
items/APU0 85 332 16 96
|
icons/WaveSquare 916 655 24 10
|
||||||
items/APU1 102 332 16 96
|
icons/WaveTriangle 941 655 24 10
|
||||||
items/APU2 119 332 16 96
|
icons/Window 368 553 16 16
|
||||||
items/CPU0 975 351 16 16
|
icons/WireArrowLeft 51 720 4 8
|
||||||
items/CPU1 992 351 16 16
|
icons/WireArrowRight 56 720 4 8
|
||||||
items/CPU2 285 332 16 16
|
items/APU0 134 553 16 96
|
||||||
items/CardBase 302 332 16 16
|
items/APU1 151 553 16 96
|
||||||
items/CircuitBoard 319 332 16 16
|
items/APU2 168 553 16 96
|
||||||
items/ComponentBus0 336 332 16 16
|
items/CPU0 385 553 16 16
|
||||||
items/ComponentBus1 353 332 16 16
|
items/CPU1 402 553 16 16
|
||||||
items/ComponentBus2 370 332 16 16
|
items/CPU2 419 553 16 16
|
||||||
items/ComponentBus3 387 332 16 16
|
items/CardBase 436 553 16 16
|
||||||
items/DataCard0 0 305 16 128
|
items/CircuitBoard 453 553 16 16
|
||||||
items/DataCard1 17 305 16 128
|
items/ComponentBus0 470 553 16 16
|
||||||
items/DataCard2 34 305 16 128
|
items/ComponentBus1 487 553 16 16
|
||||||
items/DebugCard 404 332 16 16
|
items/ComponentBus2 504 553 16 16
|
||||||
items/DiskDriveMountable 421 332 16 16
|
items/ComponentBus3 521 553 16 16
|
||||||
items/EEPROM 438 332 16 16
|
items/DataCard0 49 526 16 128
|
||||||
items/FloppyDisk_dyeBlack 455 332 16 16
|
items/DataCard1 66 526 16 128
|
||||||
items/FloppyDisk_dyeBlue 472 332 16 16
|
items/DataCard2 83 526 16 128
|
||||||
items/FloppyDisk_dyeBrown 489 332 16 16
|
items/DebugCard 538 553 16 16
|
||||||
items/FloppyDisk_dyeCyan 506 332 16 16
|
items/DiskDriveMountable 555 553 16 16
|
||||||
items/FloppyDisk_dyeGray 523 332 16 16
|
items/EEPROM 572 553 16 16
|
||||||
items/FloppyDisk_dyeGreen 540 332 16 16
|
items/FloppyDisk_dyeBlack 589 553 16 16
|
||||||
items/FloppyDisk_dyeLightBlue 557 332 16 16
|
items/FloppyDisk_dyeBlue 606 553 16 16
|
||||||
items/FloppyDisk_dyeLightGray 574 332 16 16
|
items/FloppyDisk_dyeBrown 623 553 16 16
|
||||||
items/FloppyDisk_dyeLime 591 332 16 16
|
items/FloppyDisk_dyeCyan 640 553 16 16
|
||||||
items/FloppyDisk_dyeMagenta 608 332 16 16
|
items/FloppyDisk_dyeGray 657 553 16 16
|
||||||
items/FloppyDisk_dyeOrange 625 332 16 16
|
items/FloppyDisk_dyeGreen 674 553 16 16
|
||||||
items/FloppyDisk_dyePink 642 332 16 16
|
items/FloppyDisk_dyeLightBlue 691 553 16 16
|
||||||
items/FloppyDisk_dyePurple 659 332 16 16
|
items/FloppyDisk_dyeLightGray 708 553 16 16
|
||||||
items/FloppyDisk_dyeRed 676 332 16 16
|
items/FloppyDisk_dyeLime 725 553 16 16
|
||||||
items/FloppyDisk_dyeWhite 693 332 16 16
|
items/FloppyDisk_dyeMagenta 742 553 16 16
|
||||||
items/FloppyDisk_dyeYellow 710 332 16 16
|
items/FloppyDisk_dyeOrange 759 553 16 16
|
||||||
items/GraphicsCard0 727 332 16 16
|
items/FloppyDisk_dyePink 776 553 16 16
|
||||||
items/GraphicsCard1 744 332 16 16
|
items/FloppyDisk_dyePurple 793 553 16 16
|
||||||
items/GraphicsCard2 761 332 16 16
|
items/FloppyDisk_dyeRed 810 553 16 16
|
||||||
items/HardDiskDrive0 778 332 16 16
|
items/FloppyDisk_dyeWhite 827 553 16 16
|
||||||
items/HardDiskDrive1 795 332 16 16
|
items/FloppyDisk_dyeYellow 844 553 16 16
|
||||||
items/HardDiskDrive2 812 332 16 16
|
items/GraphicsCard0 861 553 16 16
|
||||||
items/InternetCard 153 376 16 32
|
items/GraphicsCard1 878 553 16 16
|
||||||
items/LinkedCard 136 332 16 96
|
items/GraphicsCard2 895 553 16 16
|
||||||
items/Memory0 829 332 16 16
|
items/HardDiskDrive0 912 553 16 16
|
||||||
items/Memory1 846 332 16 16
|
items/HardDiskDrive1 929 553 16 16
|
||||||
items/Memory2 863 332 16 16
|
items/HardDiskDrive2 946 553 16 16
|
||||||
items/Memory3 880 332 16 16
|
items/InternetCard 202 597 16 32
|
||||||
items/Memory4 897 332 16 16
|
items/LinkedCard 185 553 16 96
|
||||||
items/Memory5 914 332 16 16
|
items/Memory0 963 553 16 16
|
||||||
items/Memory6 931 332 16 16
|
items/Memory1 980 553 16 16
|
||||||
items/NetworkCard 948 332 16 16
|
items/Memory2 997 553 16 16
|
||||||
items/OcelotCard 51 305 16 128
|
items/Memory3 201 526 16 16
|
||||||
items/RedstoneCard0 965 332 16 16
|
items/Memory4 218 526 16 16
|
||||||
items/RedstoneCard1 982 332 16 16
|
items/Memory5 235 526 16 16
|
||||||
items/SelfDestructingCard 170 376 16 32
|
items/Memory6 252 526 16 16
|
||||||
items/Server0 999 332 16 16
|
items/NetworkCard 269 526 16 16
|
||||||
items/Server1 152 305 16 16
|
items/OcelotCard 100 526 16 128
|
||||||
items/Server2 169 305 16 16
|
items/RedstoneCard0 286 526 16 16
|
||||||
items/Server3 186 305 16 16
|
items/RedstoneCard1 303 526 16 16
|
||||||
items/SoundCard 68 305 16 128
|
items/SelfDestructingCard 219 597 16 32
|
||||||
items/WirelessNetworkCard0 203 305 16 16
|
items/Server0 320 526 16 16
|
||||||
items/WirelessNetworkCard1 220 305 16 16
|
items/Server1 337 526 16 16
|
||||||
light-panel/BookmarkLeft 561 434 18 14
|
items/Server2 354 526 16 16
|
||||||
light-panel/BookmarkRight 207 409 20 14
|
items/Server3 371 526 16 16
|
||||||
light-panel/BorderB 13 547 4 4
|
items/SoundCard 117 526 16 128
|
||||||
light-panel/BorderL 103 547 4 2
|
items/WirelessNetworkCard0 388 526 16 16
|
||||||
light-panel/BorderR 18 547 4 4
|
items/WirelessNetworkCard1 405 526 16 16
|
||||||
light-panel/BorderT 23 547 4 4
|
light-panel/BookmarkLeft 797 655 18 14
|
||||||
light-panel/CornerBL 28 547 4 4
|
light-panel/BookmarkRight 256 630 20 14
|
||||||
light-panel/CornerBR 33 547 4 4
|
light-panel/BorderB 62 729 4 4
|
||||||
light-panel/CornerTL 38 547 4 4
|
light-panel/BorderL 152 729 4 2
|
||||||
light-panel/CornerTR 43 547 4 4
|
light-panel/BorderR 67 729 4 4
|
||||||
light-panel/Fill 6 558 2 2
|
light-panel/BorderT 72 729 4 4
|
||||||
light-panel/Vent 0 499 2 38
|
light-panel/CornerBL 77 729 4 4
|
||||||
nodes/Cable 21 510 8 8
|
light-panel/CornerBR 82 729 4 4
|
||||||
nodes/Camera 237 305 16 16
|
light-panel/CornerTL 87 729 4 4
|
||||||
nodes/Chest 69 466 14 14
|
light-panel/CornerTR 92 729 4 4
|
||||||
nodes/HologramProjector0 254 305 16 16
|
light-panel/Fill 55 740 2 2
|
||||||
nodes/HologramProjector1 271 305 16 16
|
light-panel/Vent 356 434 2 38
|
||||||
nodes/IronNoteBlock 288 305 16 16
|
nodes/Cable 377 445 8 8
|
||||||
nodes/Lamp 305 305 16 16
|
nodes/Camera 422 526 16 16
|
||||||
nodes/LampFrame 322 305 16 16
|
nodes/Chest 118 687 14 14
|
||||||
nodes/LampGlow 305 106 128 128
|
nodes/HologramProjector0 439 526 16 16
|
||||||
nodes/NewNode 339 305 16 16
|
nodes/HologramProjector1 456 526 16 16
|
||||||
nodes/NoteBlock 356 305 16 16
|
nodes/IronNoteBlock 473 526 16 16
|
||||||
nodes/OpenFMRadio 373 305 16 16
|
nodes/Lamp 490 526 16 16
|
||||||
nodes/Relay 390 305 16 16
|
nodes/LampFrame 507 526 16 16
|
||||||
nodes/computer/Default 407 305 16 16
|
nodes/LampGlow 49 305 128 128
|
||||||
nodes/computer/DiskActivity 424 305 16 16
|
nodes/NewNode 524 526 16 16
|
||||||
nodes/computer/Error 441 305 16 16
|
nodes/NoteBlock 541 526 16 16
|
||||||
nodes/computer/On 458 305 16 16
|
nodes/OpenFMRadio 558 526 16 16
|
||||||
nodes/disk-drive/Default 475 305 16 16
|
nodes/Relay 575 526 16 16
|
||||||
nodes/disk-drive/DiskActivity 492 305 16 16
|
nodes/computer/Default 592 526 16 16
|
||||||
nodes/disk-drive/Floppy 509 305 16 16
|
nodes/computer/DiskActivity 609 526 16 16
|
||||||
nodes/microcontroller/Default 526 305 16 16
|
nodes/computer/Error 626 526 16 16
|
||||||
nodes/microcontroller/Error 543 305 16 16
|
nodes/computer/On 643 526 16 16
|
||||||
nodes/microcontroller/On 560 305 16 16
|
nodes/disk-drive/Default 660 526 16 16
|
||||||
nodes/rack/Default 577 305 16 16
|
nodes/disk-drive/DiskActivity 677 526 16 16
|
||||||
nodes/rack/Empty 594 305 16 16
|
nodes/disk-drive/Floppy 694 526 16 16
|
||||||
nodes/rack/drive/0/Default 611 305 16 16
|
nodes/microcontroller/Default 711 526 16 16
|
||||||
nodes/rack/drive/0/DiskActivity 628 305 16 16
|
nodes/microcontroller/Error 728 526 16 16
|
||||||
nodes/rack/drive/0/Floppy 645 305 16 16
|
nodes/microcontroller/On 745 526 16 16
|
||||||
nodes/rack/drive/1/Default 662 305 16 16
|
nodes/rack/Default 762 526 16 16
|
||||||
nodes/rack/drive/1/DiskActivity 679 305 16 16
|
nodes/rack/Empty 779 526 16 16
|
||||||
nodes/rack/drive/1/Floppy 696 305 16 16
|
nodes/rack/drive/0/Default 796 526 16 16
|
||||||
nodes/rack/drive/2/Default 713 305 16 16
|
nodes/rack/drive/0/DiskActivity 813 526 16 16
|
||||||
nodes/rack/drive/2/DiskActivity 730 305 16 16
|
nodes/rack/drive/0/Floppy 830 526 16 16
|
||||||
nodes/rack/drive/2/Floppy 747 305 16 16
|
nodes/rack/drive/1/Default 847 526 16 16
|
||||||
nodes/rack/drive/3/Default 764 305 16 16
|
nodes/rack/drive/1/DiskActivity 864 526 16 16
|
||||||
nodes/rack/drive/3/DiskActivity 781 305 16 16
|
nodes/rack/drive/1/Floppy 881 526 16 16
|
||||||
nodes/rack/drive/3/Floppy 798 305 16 16
|
nodes/rack/drive/2/Default 898 526 16 16
|
||||||
nodes/rack/drive/Floppy 815 305 16 16
|
nodes/rack/drive/2/DiskActivity 915 526 16 16
|
||||||
nodes/rack/server/0/Default 832 305 16 16
|
nodes/rack/drive/2/Floppy 932 526 16 16
|
||||||
nodes/rack/server/0/DiskActivity 849 305 16 16
|
nodes/rack/drive/3/Default 949 526 16 16
|
||||||
nodes/rack/server/0/Error 866 305 16 16
|
nodes/rack/drive/3/DiskActivity 966 526 16 16
|
||||||
nodes/rack/server/0/NetworkActivity 883 305 16 16
|
nodes/rack/drive/3/Floppy 983 526 16 16
|
||||||
nodes/rack/server/0/On 900 305 16 16
|
nodes/rack/drive/Floppy 1000 526 16 16
|
||||||
nodes/rack/server/1/Default 917 305 16 16
|
nodes/rack/server/0/Default 49 655 16 16
|
||||||
nodes/rack/server/1/DiskActivity 934 305 16 16
|
nodes/rack/server/0/DiskActivity 66 655 16 16
|
||||||
nodes/rack/server/1/Error 951 305 16 16
|
nodes/rack/server/0/Error 83 655 16 16
|
||||||
nodes/rack/server/1/NetworkActivity 968 305 16 16
|
nodes/rack/server/0/NetworkActivity 100 655 16 16
|
||||||
nodes/rack/server/1/On 985 305 16 16
|
nodes/rack/server/0/On 117 655 16 16
|
||||||
nodes/rack/server/2/Default 1002 305 16 16
|
nodes/rack/server/1/Default 134 655 16 16
|
||||||
nodes/rack/server/2/DiskActivity 0 434 16 16
|
nodes/rack/server/1/DiskActivity 151 655 16 16
|
||||||
nodes/rack/server/2/Error 17 434 16 16
|
nodes/rack/server/1/Error 168 655 16 16
|
||||||
nodes/rack/server/2/NetworkActivity 34 434 16 16
|
nodes/rack/server/1/NetworkActivity 185 655 16 16
|
||||||
nodes/rack/server/2/On 51 434 16 16
|
nodes/rack/server/1/On 202 655 16 16
|
||||||
nodes/rack/server/3/Default 68 434 16 16
|
nodes/rack/server/2/Default 219 655 16 16
|
||||||
nodes/rack/server/3/DiskActivity 85 434 16 16
|
nodes/rack/server/2/DiskActivity 236 655 16 16
|
||||||
nodes/rack/server/3/Error 102 434 16 16
|
nodes/rack/server/2/Error 253 655 16 16
|
||||||
nodes/rack/server/3/NetworkActivity 119 434 16 16
|
nodes/rack/server/2/NetworkActivity 270 655 16 16
|
||||||
nodes/rack/server/3/On 136 434 16 16
|
nodes/rack/server/2/On 287 655 16 16
|
||||||
nodes/raid/0/DiskActivity 153 434 16 16
|
nodes/rack/server/3/Default 304 655 16 16
|
||||||
nodes/raid/0/Error 170 434 16 16
|
nodes/rack/server/3/DiskActivity 321 655 16 16
|
||||||
nodes/raid/1/DiskActivity 187 434 16 16
|
nodes/rack/server/3/Error 338 655 16 16
|
||||||
nodes/raid/1/Error 204 434 16 16
|
nodes/rack/server/3/NetworkActivity 355 655 16 16
|
||||||
nodes/raid/2/DiskActivity 221 434 16 16
|
nodes/rack/server/3/On 372 655 16 16
|
||||||
nodes/raid/2/Error 238 434 16 16
|
nodes/raid/0/DiskActivity 389 655 16 16
|
||||||
nodes/raid/Default 255 434 16 16
|
nodes/raid/0/Error 406 655 16 16
|
||||||
nodes/screen/BottomLeft 272 434 16 16
|
nodes/raid/1/DiskActivity 423 655 16 16
|
||||||
nodes/screen/BottomMiddle 289 434 16 16
|
nodes/raid/1/Error 440 655 16 16
|
||||||
nodes/screen/BottomRight 306 434 16 16
|
nodes/raid/2/DiskActivity 457 655 16 16
|
||||||
nodes/screen/ColumnBottom 323 434 16 16
|
nodes/raid/2/Error 474 655 16 16
|
||||||
nodes/screen/ColumnMiddle 340 434 16 16
|
nodes/raid/Default 491 655 16 16
|
||||||
nodes/screen/ColumnTop 357 434 16 16
|
nodes/screen/BottomLeft 508 655 16 16
|
||||||
nodes/screen/Middle 374 434 16 16
|
nodes/screen/BottomMiddle 525 655 16 16
|
||||||
nodes/screen/MiddleLeft 391 434 16 16
|
nodes/screen/BottomRight 542 655 16 16
|
||||||
nodes/screen/MiddleRight 408 434 16 16
|
nodes/screen/ColumnBottom 559 655 16 16
|
||||||
nodes/screen/PowerOnOverlay 425 434 16 16
|
nodes/screen/ColumnMiddle 576 655 16 16
|
||||||
nodes/screen/RowLeft 442 434 16 16
|
nodes/screen/ColumnTop 593 655 16 16
|
||||||
nodes/screen/RowMiddle 459 434 16 16
|
nodes/screen/Middle 610 655 16 16
|
||||||
nodes/screen/RowRight 476 434 16 16
|
nodes/screen/MiddleLeft 627 655 16 16
|
||||||
nodes/screen/Standalone 493 434 16 16
|
nodes/screen/MiddleRight 644 655 16 16
|
||||||
nodes/screen/TopLeft 510 434 16 16
|
nodes/screen/PowerOnOverlay 661 655 16 16
|
||||||
nodes/screen/TopMiddle 527 434 16 16
|
nodes/screen/RowLeft 678 655 16 16
|
||||||
nodes/screen/TopRight 544 434 16 16
|
nodes/screen/RowMiddle 695 655 16 16
|
||||||
panel/BorderB 48 547 4 4
|
nodes/screen/RowRight 712 655 16 16
|
||||||
panel/BorderL 108 547 4 2
|
nodes/screen/Standalone 729 655 16 16
|
||||||
panel/BorderR 53 547 4 4
|
nodes/screen/TopLeft 746 655 16 16
|
||||||
panel/BorderT 58 547 4 4
|
nodes/screen/TopMiddle 763 655 16 16
|
||||||
panel/CornerBL 63 547 4 4
|
nodes/screen/TopRight 780 655 16 16
|
||||||
panel/CornerBR 68 547 4 4
|
panel/BorderB 97 729 4 4
|
||||||
panel/CornerTL 73 547 4 4
|
panel/BorderL 157 729 4 2
|
||||||
panel/CornerTR 78 547 4 4
|
panel/BorderR 102 729 4 4
|
||||||
panel/Fill 9 558 2 2
|
panel/BorderT 107 729 4 4
|
||||||
particles/Note 21 499 7 10
|
panel/CornerBL 112 729 4 4
|
||||||
screen/BorderB 5 547 2 8
|
panel/CornerBR 117 729 4 4
|
||||||
screen/BorderT 2 547 2 10
|
panel/CornerTL 122 729 4 4
|
||||||
screen/CornerBL 30 510 8 8
|
panel/CornerTR 127 729 4 4
|
||||||
screen/CornerBR 39 510 8 8
|
panel/Fill 58 740 2 2
|
||||||
screen/CornerTL 3 499 8 10
|
particles/Note 377 434 7 10
|
||||||
screen/CornerTR 12 499 8 10
|
screen/BorderB 54 729 2 8
|
||||||
window/BorderDark 2 558 1 4
|
screen/BorderT 51 729 2 10
|
||||||
window/BorderLight 4 558 1 4
|
screen/CornerBL 386 445 8 8
|
||||||
window/CornerBL 83 547 4 4
|
screen/CornerBR 395 445 8 8
|
||||||
window/CornerBR 88 547 4 4
|
screen/CornerTL 359 434 8 10
|
||||||
window/CornerTL 93 547 4 4
|
screen/CornerTR 368 434 8 10
|
||||||
window/CornerTR 98 547 4 4
|
window/BorderDark 51 740 1 4
|
||||||
window/OpenFMRadio 305 0 232 105
|
window/BorderLight 53 740 1 4
|
||||||
window/case/Motherboard 612 0 79 70
|
window/CornerBL 132 729 4 4
|
||||||
window/rack/Lines 538 0 73 91
|
window/CornerBR 137 729 4 4
|
||||||
window/rack/Motherboard 434 106 100 78
|
window/CornerTL 142 729 4 4
|
||||||
window/rack/NetworkBack 20 552 1 2
|
window/CornerTR 147 729 4 4
|
||||||
window/rack/NetworkBottom 22 552 1 2
|
window/OpenFMRadio 474 0 232 105
|
||||||
window/rack/NetworkConnector 24 552 1 2
|
window/case/Motherboard 123 434 79 70
|
||||||
window/rack/NetworkLeft 26 552 1 2
|
window/rack/Lines 49 434 73 91
|
||||||
window/rack/NetworkRight 28 552 1 2
|
window/rack/Motherboard 178 305 100 78
|
||||||
window/rack/NetworkTop 30 552 1 2
|
window/rack/NetworkBack 69 734 1 2
|
||||||
window/rack/NodeBack 113 547 5 1
|
window/rack/NetworkBottom 71 734 1 2
|
||||||
window/rack/NodeBottom 119 547 5 1
|
window/rack/NetworkConnector 73 734 1 2
|
||||||
window/rack/NodeLeft 125 547 5 1
|
window/rack/NetworkLeft 75 734 1 2
|
||||||
window/rack/NodeRight 131 547 5 1
|
window/rack/NetworkRight 77 734 1 2
|
||||||
window/rack/NodeTop 137 547 5 1
|
window/rack/NetworkTop 79 734 1 2
|
||||||
window/rack/SideBack 8 552 1 3
|
window/rack/NodeBack 162 729 5 1
|
||||||
window/rack/SideBottom 10 552 1 3
|
window/rack/NodeBottom 168 729 5 1
|
||||||
window/rack/SideConnector 12 552 1 3
|
window/rack/NodeLeft 174 729 5 1
|
||||||
window/rack/SideLeft 14 552 1 3
|
window/rack/NodeRight 180 729 5 1
|
||||||
window/rack/SideRight 16 552 1 3
|
window/rack/NodeTop 186 729 5 1
|
||||||
window/rack/SideTop 18 552 1 3
|
window/rack/SideBack 57 734 1 3
|
||||||
window/raid/Slots 85 305 66 26
|
window/rack/SideBottom 59 734 1 3
|
||||||
|
window/rack/SideConnector 61 734 1 3
|
||||||
|
window/rack/SideLeft 63 734 1 3
|
||||||
|
window/rack/SideRight 65 734 1 3
|
||||||
|
window/rack/SideTop 67 734 1 3
|
||||||
|
window/raid/Slots 134 526 66 26
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import ocelot.desktop.util.Logging
|
|||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.io.Source
|
import scala.io.Source
|
||||||
|
|
||||||
object ColorScheme extends Logging {
|
class ColorScheme extends Logging {
|
||||||
private val entries = new mutable.HashMap[String, RGBAColorNorm]()
|
private val entries = new mutable.HashMap[String, RGBAColorNorm]()
|
||||||
|
|
||||||
def apply(key: String): RGBAColorNorm = entries(key)
|
def apply(key: String): RGBAColorNorm = entries(key)
|
||||||
|
|
||||||
|
def add(key: String, color: RGBAColorNorm): Unit = entries.addOne((key, color))
|
||||||
|
|
||||||
def load(source: Source): Unit = {
|
def load(source: Source): Unit = {
|
||||||
logger.info(s"Loading color scheme")
|
logger.info(s"Loading color scheme")
|
||||||
|
|
||||||
@ -36,3 +38,11 @@ object ColorScheme extends Logging {
|
|||||||
logger.info(s"Loaded ${entries.size - oldSize} colors")
|
logger.info(s"Loaded ${entries.size - oldSize} colors")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ColorScheme {
|
||||||
|
val General = new ColorScheme
|
||||||
|
|
||||||
|
def load(source: Source): Unit = General.load(source)
|
||||||
|
|
||||||
|
def apply(key: String): RGBAColorNorm = General(key)
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import ocelot.desktop.ui.UiHandler
|
|||||||
import ocelot.desktop.ui.swing.SplashScreen
|
import ocelot.desktop.ui.swing.SplashScreen
|
||||||
import ocelot.desktop.ui.widget._
|
import ocelot.desktop.ui.widget._
|
||||||
import ocelot.desktop.ui.widget.modal.notification.{NotificationDialog, NotificationType}
|
import ocelot.desktop.ui.widget.modal.notification.{NotificationDialog, NotificationType}
|
||||||
import ocelot.desktop.ui.widget.settings.SettingsDialog
|
|
||||||
import ocelot.desktop.util.CommandLine.Argument
|
import ocelot.desktop.util.CommandLine.Argument
|
||||||
import ocelot.desktop.util.FileUtils.getOcelotConfigDirectory
|
import ocelot.desktop.util.FileUtils.getOcelotConfigDirectory
|
||||||
import ocelot.desktop.util._
|
import ocelot.desktop.util._
|
||||||
@ -372,8 +371,6 @@ object OcelotDesktop extends Logging {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def showSettings(): Unit = new SettingsDialog().show()
|
|
||||||
|
|
||||||
def exit(): Unit = showCloseConfirmationDialog() {
|
def exit(): Unit = showCloseConfirmationDialog() {
|
||||||
UiHandler.exit()
|
UiHandler.exit()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package ocelot.desktop.audio
|
package ocelot.desktop.audio
|
||||||
|
|
||||||
import ocelot.desktop.Settings
|
import ocelot.desktop.Settings
|
||||||
import ocelot.desktop.util.{Logging, OpenAlException}
|
import ocelot.desktop.util.Logging
|
||||||
import org.lwjgl.openal.AL10
|
import org.lwjgl.openal.AL10
|
||||||
|
|
||||||
import java.nio.{ByteBuffer, IntBuffer}
|
import java.nio.{ByteBuffer, IntBuffer}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package ocelot.desktop.audio
|
package ocelot.desktop.audio
|
||||||
|
|
||||||
import ocelot.desktop.Settings
|
import ocelot.desktop.Settings
|
||||||
import ocelot.desktop.util.{Logging, OpenAlException, Transaction}
|
import ocelot.desktop.util.{Logging, Transaction}
|
||||||
import org.lwjgl.LWJGLException
|
import org.lwjgl.LWJGLException
|
||||||
import org.lwjgl.openal.{AL, AL10, ALC10}
|
import org.lwjgl.openal.{AL, AL10, ALC10}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package ocelot.desktop.util
|
package ocelot.desktop.audio
|
||||||
|
|
||||||
import scala.util.control
|
import scala.util.control
|
||||||
import scala.util.control.Exception.Catch
|
import scala.util.control.Exception.Catch
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package ocelot.desktop.audio
|
package ocelot.desktop.audio
|
||||||
|
|
||||||
import ocelot.desktop.util.{FileUtils, Logging, OpenAlException, Resource}
|
import ocelot.desktop.util.{FileUtils, Logging, Resource}
|
||||||
import org.lwjgl.openal.AL10
|
import org.lwjgl.openal.AL10
|
||||||
|
|
||||||
class SoundBuffer(val file: String) extends Resource with Logging {
|
class SoundBuffer(val file: String) extends Resource with Logging {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package ocelot.desktop.audio
|
package ocelot.desktop.audio
|
||||||
|
|
||||||
import ocelot.desktop.util.{Logging, OpenAlException}
|
import ocelot.desktop.util.Logging
|
||||||
import org.lwjgl.openal.AL10
|
import org.lwjgl.openal.AL10
|
||||||
|
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package ocelot.desktop.graphics
|
|||||||
|
|
||||||
import ocelot.desktop.color.{Color, RGBAColorNorm}
|
import ocelot.desktop.color.{Color, RGBAColorNorm}
|
||||||
import ocelot.desktop.geometry.{Rect2D, Size2D, Transform2D, Vector2D}
|
import ocelot.desktop.geometry.{Rect2D, Size2D, Transform2D, Vector2D}
|
||||||
|
import ocelot.desktop.graphics.IconSource.Animation
|
||||||
import ocelot.desktop.graphics.mesh.{Mesh2D, MeshInstance2D, MeshVertex2D}
|
import ocelot.desktop.graphics.mesh.{Mesh2D, MeshInstance2D, MeshVertex2D}
|
||||||
import ocelot.desktop.graphics.render.InstanceRenderer
|
import ocelot.desktop.graphics.render.InstanceRenderer
|
||||||
import ocelot.desktop.ui.UiHandler
|
import ocelot.desktop.ui.UiHandler
|
||||||
@ -279,9 +280,14 @@ class Graphics(private var scalingFactor: Float) extends Logging with Resource {
|
|||||||
sprite(name, pos.x, pos.y, size.width, size.height)
|
sprite(name, pos.x, pos.y, size.width, size.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sprite(name: String, x: Float, y: Float): Unit = {
|
||||||
|
val size = Spritesheet.spriteSize(name)
|
||||||
|
sprite(name, x, y, size.width, size.height)
|
||||||
|
}
|
||||||
|
|
||||||
def sprite(name: String, x: Float, y: Float, width: Float, height: Float,
|
def sprite(name: String, x: Float, y: Float, width: Float, height: Float,
|
||||||
color: Color = RGBAColorNorm(1f, 1f, 1f),
|
color: Color = RGBAColorNorm(1f, 1f, 1f),
|
||||||
animation: Option[IconSource.Animation] = None): Unit =
|
animation: Option[Animation] = None): Unit =
|
||||||
{
|
{
|
||||||
sprite = name
|
sprite = name
|
||||||
foreground = color
|
foreground = color
|
||||||
@ -308,23 +314,27 @@ class Graphics(private var scalingFactor: Float) extends Logging with Resource {
|
|||||||
|
|
||||||
private def _rect(x: Float, y: Float, width: Float, height: Float,
|
private def _rect(x: Float, y: Float, width: Float, height: Float,
|
||||||
fixUV: Boolean = true,
|
fixUV: Boolean = true,
|
||||||
animation: Option[Array[(Int, Float)]] = None): Unit = {
|
animation: Option[Animation] = None): Unit = {
|
||||||
val spriteRect = animation match {
|
val spriteRect = animation match {
|
||||||
case None => this.spriteRect
|
case None => this.spriteRect
|
||||||
case Some(frames) =>
|
case Some(animation) =>
|
||||||
val duration = frames.map(_._2).sum
|
val duration = animation.frames.map(_._2).sum
|
||||||
var timeOffset = 0f
|
var timeOffset = 0f
|
||||||
var curFrame = 0
|
var curFrame = 0
|
||||||
|
|
||||||
breakable {
|
breakable {
|
||||||
for ((idx, dur) <- frames) {
|
for ((idx, dur) <- animation.frames) {
|
||||||
timeOffset += dur
|
timeOffset += dur
|
||||||
curFrame = idx
|
curFrame = idx
|
||||||
if (timeOffset >= time % duration) break
|
if (timeOffset >= time % duration) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.spriteRect.copy(y = this.spriteRect.y + curFrame * this.spriteRect.w, h = this.spriteRect.w)
|
val size = animation.frameSize match {
|
||||||
|
case Some(size) => Size2D(this.spriteRect.w, this.spriteRect.w * size.height / size.width)
|
||||||
|
case None => Size2D(this.spriteRect.w, this.spriteRect.w)
|
||||||
|
}
|
||||||
|
this.spriteRect.copy(y = this.spriteRect.y + curFrame * size.height, h = size.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
val uvTransform = Transform2D.translate(spriteRect.x, spriteRect.y) >>
|
val uvTransform = Transform2D.translate(spriteRect.x, spriteRect.y) >>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package ocelot.desktop.graphics
|
package ocelot.desktop.graphics
|
||||||
|
|
||||||
|
import ocelot.desktop.geometry.Size2D
|
||||||
import ocelot.desktop.ui.widget.modal.notification.NotificationType.NotificationType
|
import ocelot.desktop.ui.widget.modal.notification.NotificationType.NotificationType
|
||||||
import totoro.ocelot.brain.util.DyeColor
|
import totoro.ocelot.brain.util.DyeColor
|
||||||
import totoro.ocelot.brain.util.ExtendedTier.ExtendedTier
|
import totoro.ocelot.brain.util.ExtendedTier.ExtendedTier
|
||||||
@ -11,8 +12,6 @@ case class IconSource(
|
|||||||
)
|
)
|
||||||
|
|
||||||
object IconSource {
|
object IconSource {
|
||||||
type Animation = Array[(Int, Float)]
|
|
||||||
|
|
||||||
val CardIcon: IconSource = IconSource("icons/Card")
|
val CardIcon: IconSource = IconSource("icons/Card")
|
||||||
val CpuIcon: IconSource = IconSource("icons/CPU")
|
val CpuIcon: IconSource = IconSource("icons/CPU")
|
||||||
val HddIcon: IconSource = IconSource("icons/HDD")
|
val HddIcon: IconSource = IconSource("icons/HDD")
|
||||||
@ -88,24 +87,36 @@ object IconSource {
|
|||||||
|
|
||||||
//noinspection ScalaWeakerAccess
|
//noinspection ScalaWeakerAccess
|
||||||
object Animations {
|
object Animations {
|
||||||
val Apu: Animation = Array(
|
val Apu: Animation = Animation(
|
||||||
(0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f),
|
(0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f),
|
||||||
(4, 3f), (3, 3f), (2, 3f), (1, 3f), (0, 3f))
|
(4, 3f), (3, 3f), (2, 3f), (1, 3f), (0, 3f))
|
||||||
|
|
||||||
val LinkedCard: Animation =
|
val LinkedCard: Animation =
|
||||||
Array((0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f))
|
Animation((0, 3f), (1, 3f), (2, 3f), (3, 3f), (4, 3f), (5, 3f))
|
||||||
|
|
||||||
val InternetCard: Animation = Array(
|
val InternetCard: Animation = Animation(
|
||||||
(0, 2f), (1, 7f), (0, 5f), (1, 4f), (0, 7f), (1, 2f), (0, 8f),
|
(0, 2f), (1, 7f), (0, 5f), (1, 4f), (0, 7f), (1, 2f), (0, 8f),
|
||||||
(1, 9f), (0, 6f), (1, 4f))
|
(1, 9f), (0, 6f), (1, 4f))
|
||||||
|
|
||||||
val DataCard: Animation = Array(
|
val DataCard: Animation = Animation(
|
||||||
(0, 4f), (1, 4f), (2, 4f), (3, 4f), (4, 4f), (5, 4f), (6, 4f), (7, 4f))
|
(0, 4f), (1, 4f), (2, 4f), (3, 4f), (4, 4f), (5, 4f), (6, 4f), (7, 4f))
|
||||||
|
|
||||||
val SelfDestructingCard: Animation = Array((0, 4f), (1, 4f))
|
val SelfDestructingCard: Animation = Animation((0, 4f), (1, 4f))
|
||||||
|
|
||||||
val OcelotCard: Animation = Array(
|
val OcelotCard: Animation = Animation(
|
||||||
(0, 12f), (1, 4f), (2, 4f), (3, 4f), (4, 5f), (5, 6f), (0, 9f), (6, 4f), (7, 3f))
|
(0, 12f), (1, 4f), (2, 4f), (3, 4f), (4, 5f), (5, 6f), (0, 9f), (6, 4f), (7, 3f))
|
||||||
|
|
||||||
|
val Loading: Animation = 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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
case class Animation(frames: Array[(Int, Float)], frameSize: Option[Size2D])
|
||||||
|
object Animation {
|
||||||
|
def apply(frames: (Int, Float)*) = new Animation(frames.toArray, None)
|
||||||
|
def apply(size: Size2D, frames: (Int, Float)*) = new Animation(frames.toArray, Some(size))
|
||||||
|
def apply(size: Option[Size2D] = None, frames: Array[(Int, Float)]) = new Animation(frames, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------- Ocelot interface icons -----------------------
|
// ----------------------- Ocelot interface icons -----------------------
|
||||||
@ -115,6 +126,8 @@ object IconSource {
|
|||||||
IconSource(s"icons/Notification$notificationType")
|
IconSource(s"icons/Notification$notificationType")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Loading: IconSource = IconSource("Loading", animation = Some(Animations.Loading))
|
||||||
|
|
||||||
val SettingsSystem: IconSource = IconSource("icons/SettingsSystem")
|
val SettingsSystem: IconSource = IconSource("icons/SettingsSystem")
|
||||||
val SettingsSound: IconSource = IconSource("icons/SettingsSound")
|
val SettingsSound: IconSource = IconSource("icons/SettingsSound")
|
||||||
val SettingsUI: IconSource = IconSource("icons/SettingsUI")
|
val SettingsUI: IconSource = IconSource("icons/SettingsUI")
|
||||||
@ -142,4 +155,7 @@ object IconSource {
|
|||||||
val Tiers: IconSource = IconSource("icons/Tiers")
|
val Tiers: IconSource = IconSource("icons/Tiers")
|
||||||
val LinesHorizontal: IconSource = IconSource("icons/LinesHorizontal")
|
val LinesHorizontal: IconSource = IconSource("icons/LinesHorizontal")
|
||||||
val ArrowRight: IconSource = IconSource("icons/ArrowRight")
|
val ArrowRight: IconSource = IconSource("icons/ArrowRight")
|
||||||
|
val Book: IconSource = IconSource("icons/Book")
|
||||||
|
val Help: IconSource = IconSource("icons/Help")
|
||||||
|
val Ocelot: IconSource = IconSource("icons/Ocelot")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,11 +5,14 @@ import ocelot.desktop.audio.SoundSource
|
|||||||
import ocelot.desktop.color.Color
|
import ocelot.desktop.color.Color
|
||||||
import ocelot.desktop.geometry.Size2D
|
import ocelot.desktop.geometry.Size2D
|
||||||
import ocelot.desktop.graphics.Graphics
|
import ocelot.desktop.graphics.Graphics
|
||||||
import ocelot.desktop.ui.event.handlers.ClickHandler
|
import ocelot.desktop.ui.event.handlers.{ClickHandler, HoverHandler}
|
||||||
import ocelot.desktop.ui.event.{ClickEvent, MouseEvent}
|
import ocelot.desktop.ui.event.{ClickEvent, HoverEvent, MouseEvent}
|
||||||
|
import ocelot.desktop.ui.widget.tooltip.Tooltip
|
||||||
import ocelot.desktop.util.DrawUtils
|
import ocelot.desktop.util.DrawUtils
|
||||||
|
|
||||||
class Button extends Widget with ClickHandler with ClickSoundSource {
|
class Button(tooltip: Tooltip = null) extends Widget with ClickHandler with HoverHandler with ClickSoundSource {
|
||||||
|
protected def colorScheme: ColorScheme = ColorScheme.General
|
||||||
|
|
||||||
def text: String = ""
|
def text: String = ""
|
||||||
|
|
||||||
def onClick(): Unit = {}
|
def onClick(): Unit = {}
|
||||||
@ -19,23 +22,37 @@ class Button extends Widget with ClickHandler with ClickSoundSource {
|
|||||||
eventHandlers += {
|
eventHandlers += {
|
||||||
case ClickEvent(MouseEvent.Button.Left, _) if enabled =>
|
case ClickEvent(MouseEvent.Button.Left, _) if enabled =>
|
||||||
onClick()
|
onClick()
|
||||||
|
|
||||||
clickSoundSource.play()
|
clickSoundSource.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tooltip != null) {
|
||||||
|
eventHandlers += {
|
||||||
|
case HoverEvent(HoverEvent.State.Enter) => onHoverEnter()
|
||||||
|
case HoverEvent(HoverEvent.State.Leave) => onHoverLeave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def onHoverEnter(): Unit = {
|
||||||
|
root.get.tooltipPool.addTooltip(tooltip)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def onHoverLeave(): Unit = {
|
||||||
|
root.get.tooltipPool.closeTooltip(tooltip)
|
||||||
|
}
|
||||||
|
|
||||||
override def minimumSize: Size2D = Size2D(24 + text.length * 8, 24)
|
override def minimumSize: Size2D = Size2D(24 + text.length * 8, 24)
|
||||||
|
|
||||||
override def maximumSize: Size2D = minimumSize
|
override def maximumSize: Size2D = minimumSize
|
||||||
|
|
||||||
override def draw(g: Graphics): Unit = {
|
override def draw(g: Graphics): Unit = {
|
||||||
val (background, border, foreground) = if (enabled) (
|
val (background, border, foreground) = if (enabled) (
|
||||||
ColorScheme("ButtonBackground"),
|
colorScheme("ButtonBackground"),
|
||||||
ColorScheme("ButtonBorder"),
|
colorScheme("ButtonBorder"),
|
||||||
ColorScheme("ButtonForeground")
|
colorScheme("ButtonForeground")
|
||||||
) else (
|
) else (
|
||||||
ColorScheme("ButtonBackgroundDisabled"),
|
colorScheme("ButtonBackgroundDisabled"),
|
||||||
ColorScheme("ButtonBorderDisabled"),
|
colorScheme("ButtonBorderDisabled"),
|
||||||
ColorScheme("ButtonForegroundDisabled")
|
colorScheme("ButtonForegroundDisabled")
|
||||||
)
|
)
|
||||||
|
|
||||||
g.rect(bounds, background)
|
g.rect(bounds, background)
|
||||||
|
|||||||
@ -24,9 +24,7 @@ class ChangeSimulationSpeedDialog() extends ModalDialog {
|
|||||||
children :+= new PaddingBox(new Widget {
|
children :+= new PaddingBox(new Widget {
|
||||||
override val layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
override val layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||||
|
|
||||||
children :+= new PaddingBox(new Label {
|
children :+= new PaddingBox(new Label("Change simulation speed"), Padding2D(bottom = 16))
|
||||||
override def text = "Change simulation speed"
|
|
||||||
}, Padding2D(bottom = 16))
|
|
||||||
|
|
||||||
private var inputTPS: TextInput = _
|
private var inputTPS: TextInput = _
|
||||||
private var inputMSPT: TextInput = _
|
private var inputMSPT: TextInput = _
|
||||||
@ -73,13 +71,9 @@ class ChangeSimulationSpeedDialog() extends ModalDialog {
|
|||||||
override def onConfirm(): Unit = confirm()
|
override def onConfirm(): Unit = confirm()
|
||||||
}
|
}
|
||||||
|
|
||||||
children :+= new Label {
|
children :+= new Label("Milliseconds per tick:")
|
||||||
override def text = "Milliseconds per tick:"
|
|
||||||
}
|
|
||||||
children :+= new PaddingBox(inputMSPT, Padding2D(bottom = 8))
|
children :+= new PaddingBox(inputMSPT, Padding2D(bottom = 8))
|
||||||
children :+= new Label {
|
children :+= new Label("Ticks per second:")
|
||||||
override def text = "Ticks per second:"
|
|
||||||
}
|
|
||||||
children :+= new PaddingBox(inputTPS, Padding2D(bottom = 8))
|
children :+= new PaddingBox(inputTPS, Padding2D(bottom = 8))
|
||||||
|
|
||||||
children :+= new Widget {
|
children :+= new Widget {
|
||||||
|
|||||||
@ -65,9 +65,7 @@ class DiskEditWindow(item: DiskItem) extends PanelWindow {
|
|||||||
override val layout = new LinearLayout(this,
|
override val layout = new LinearLayout(this,
|
||||||
orientation = Orientation.Horizontal, alignItems = AlignItems.Center)
|
orientation = Orientation.Horizontal, alignItems = AlignItems.Center)
|
||||||
|
|
||||||
children :+= new Label {
|
children :+= new Label("Label")
|
||||||
override def text: String = "Label"
|
|
||||||
}
|
|
||||||
|
|
||||||
children :+= new TextInput(item.label.getOrElse("")) {
|
children :+= new TextInput(item.label.getOrElse("")) {
|
||||||
override def onConfirm(): Unit = {
|
override def onConfirm(): Unit = {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import ocelot.desktop.geometry.Size2D
|
|||||||
import ocelot.desktop.graphics.{Graphics, IconSource}
|
import ocelot.desktop.graphics.{Graphics, IconSource}
|
||||||
import ocelot.desktop.util.Spritesheet
|
import ocelot.desktop.util.Spritesheet
|
||||||
|
|
||||||
class Icon(icon: IconSource) extends Widget {
|
class Icon(icon: IconSource, size: Size2D = null, private val color: Color = Color.White) extends Widget {
|
||||||
def this(name: String) {
|
def this(name: String) {
|
||||||
this(IconSource(name))
|
this(IconSource(name))
|
||||||
}
|
}
|
||||||
@ -14,18 +14,14 @@ class Icon(icon: IconSource) extends Widget {
|
|||||||
this(IconSource(name, animation = Some(animation)))
|
this(IconSource(name, animation = Some(animation)))
|
||||||
}
|
}
|
||||||
|
|
||||||
def iconColor: Color = Color.White
|
def iconColor: Color = color
|
||||||
def iconSize: Size2D = Spritesheet.spriteSize(icon.path)
|
def iconSize: Size2D =
|
||||||
|
if (size != null) size
|
||||||
override def minimumSize: Size2D = {
|
else if (icon.animation.isDefined && icon.animation.get.frameSize.isDefined)
|
||||||
val size = iconSize
|
icon.animation.get.frameSize.get
|
||||||
|
else Spritesheet.spriteSize(icon.path)
|
||||||
icon.animation match {
|
|
||||||
case None => size
|
|
||||||
case Some(_) => size.copy(height = size.width)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
override def minimumSize: Size2D = iconSize
|
||||||
override def maximumSize: Size2D = minimumSize
|
override def maximumSize: Size2D = minimumSize
|
||||||
|
|
||||||
override def draw(g: Graphics): Unit = {
|
override def draw(g: Graphics): Unit = {
|
||||||
|
|||||||
@ -5,11 +5,9 @@ import ocelot.desktop.color.Color
|
|||||||
import ocelot.desktop.geometry.Size2D
|
import ocelot.desktop.geometry.Size2D
|
||||||
import ocelot.desktop.graphics.Graphics
|
import ocelot.desktop.graphics.Graphics
|
||||||
|
|
||||||
class Label extends Widget {
|
class Label(private val value: String = "", private val small: Boolean = false) extends Widget {
|
||||||
def text: String = ""
|
def text: String = value
|
||||||
|
def isSmall: Boolean = small
|
||||||
def isSmall: Boolean = false
|
|
||||||
|
|
||||||
def color: Color = ColorScheme("Label")
|
def color: Color = ColorScheme("Label")
|
||||||
|
|
||||||
private var textWidth = text.length * 8
|
private var textWidth = text.length * 8
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import ocelot.desktop.geometry.{Padding2D, Size2D}
|
|||||||
import ocelot.desktop.graphics.{Graphics, IconSource}
|
import ocelot.desktop.graphics.{Graphics, IconSource}
|
||||||
import ocelot.desktop.ui.event.KeyEvent
|
import ocelot.desktop.ui.event.KeyEvent
|
||||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenuEntry, ContextMenuSubmenu}
|
import ocelot.desktop.ui.widget.contextmenu.{ContextMenuEntry, ContextMenuSubmenu}
|
||||||
|
import ocelot.desktop.ui.widget.help.{AboutDialog, UpdateCheckerDialog}
|
||||||
|
import ocelot.desktop.ui.widget.settings.SettingsDialog
|
||||||
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
||||||
import org.lwjgl.input.Keyboard
|
import org.lwjgl.input.Keyboard
|
||||||
|
|
||||||
@ -43,7 +45,16 @@ class MenuBar extends Widget {
|
|||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
addEntry(new MenuBarButton("Settings", () => OcelotDesktop.showSettings()))
|
addEntry(new MenuBarButton("Settings", () => new SettingsDialog().show()))
|
||||||
|
|
||||||
|
addEntry(new MenuBarSubmenu("Help", menu => {
|
||||||
|
menu.addEntry(ContextMenuEntry("Check for Updates", IconSource.Help) {
|
||||||
|
new UpdateCheckerDialog().show()
|
||||||
|
})
|
||||||
|
menu.addSeparator()
|
||||||
|
menu.addEntry(ContextMenuEntry("Manual", IconSource.Book) {}.setEnabled(false))
|
||||||
|
menu.addEntry(ContextMenuEntry("About", IconSource.Ocelot) { new AboutDialog().show() })
|
||||||
|
}))
|
||||||
|
|
||||||
addEntry(new Widget {
|
addEntry(new Widget {
|
||||||
override def maximumSize: Size2D = Size2D(Float.PositiveInfinity, 1)
|
override def maximumSize: Size2D = Size2D(Float.PositiveInfinity, 1)
|
||||||
|
|||||||
@ -12,12 +12,7 @@ class ScreenAspectRatioDialog(screenNode: ScreenNode) extends ModalDialog {
|
|||||||
new Widget {
|
new Widget {
|
||||||
override val layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
override val layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||||
|
|
||||||
children :+= new PaddingBox(
|
children :+= new PaddingBox(new Label("Set aspect ratio"), Padding2D(bottom = 16))
|
||||||
new Label {
|
|
||||||
override def text = "Set aspect ratio"
|
|
||||||
},
|
|
||||||
Padding2D(bottom = 16)
|
|
||||||
)
|
|
||||||
|
|
||||||
private var typedWidth: Option[Int] = Some(screenNode.screen.aspectRatio._1.toInt)
|
private var typedWidth: Option[Int] = Some(screenNode.screen.aspectRatio._1.toInt)
|
||||||
private var typedHeight: Option[Int] = Some(screenNode.screen.aspectRatio._2.toInt)
|
private var typedHeight: Option[Int] = Some(screenNode.screen.aspectRatio._2.toInt)
|
||||||
@ -61,9 +56,7 @@ class ScreenAspectRatioDialog(screenNode: ScreenNode) extends ModalDialog {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
children :+= new Label {
|
children :+= new Label("Width:")
|
||||||
override def text = "Width:"
|
|
||||||
}
|
|
||||||
|
|
||||||
addInput(
|
addInput(
|
||||||
8,
|
8,
|
||||||
@ -71,9 +64,7 @@ class ScreenAspectRatioDialog(screenNode: ScreenNode) extends ModalDialog {
|
|||||||
value => typedWidth = value
|
value => typedWidth = value
|
||||||
)
|
)
|
||||||
|
|
||||||
children :+= new Label {
|
children :+= new Label("Height:")
|
||||||
override def text = "Height:"
|
|
||||||
}
|
|
||||||
|
|
||||||
addInput(
|
addInput(
|
||||||
6,
|
6,
|
||||||
|
|||||||
@ -32,9 +32,7 @@ class TunnelDialog(
|
|||||||
new Widget {
|
new Widget {
|
||||||
override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 8)
|
override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 8)
|
||||||
|
|
||||||
children :+= new PaddingBox(new Label {
|
children :+= new PaddingBox(new Label("Set channel name/code"), Padding2D(bottom = 8))
|
||||||
override def text: String = "Set channel name/code"
|
|
||||||
}, Padding2D(bottom = 8))
|
|
||||||
|
|
||||||
children :+= new Widget {
|
children :+= new Widget {
|
||||||
children :+= input
|
children :+= input
|
||||||
|
|||||||
118
src/main/scala/ocelot/desktop/ui/widget/help/AboutDialog.scala
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package ocelot.desktop.ui.widget.help
|
||||||
|
|
||||||
|
import buildinfo.BuildInfo
|
||||||
|
import ocelot.desktop.ColorScheme
|
||||||
|
import ocelot.desktop.color.Color
|
||||||
|
import ocelot.desktop.geometry.{Padding2D, Size2D}
|
||||||
|
import ocelot.desktop.graphics.Graphics
|
||||||
|
import ocelot.desktop.ui.layout.LinearLayout
|
||||||
|
import ocelot.desktop.ui.widget.{Button, Filler, Label, PaddingBox, Widget}
|
||||||
|
import ocelot.desktop.ui.widget.modal.ModalDialog
|
||||||
|
import ocelot.desktop.ui.widget.tooltip.{LabelTooltip, Tooltip}
|
||||||
|
import ocelot.desktop.util.{DrawUtils, Orientation, Spritesheet}
|
||||||
|
|
||||||
|
import java.awt.Desktop
|
||||||
|
import java.net.URI
|
||||||
|
import java.time.Year
|
||||||
|
|
||||||
|
class AboutDialog extends ModalDialog {
|
||||||
|
val WebsiteURL: String = "https://ocelot.fomalhaut.me/desktop"
|
||||||
|
val IrcURL: String = "https://webchat.esper.net/?join=cc.ru"
|
||||||
|
val DiscordURL: String = "https://discord.gg/ygxUkxg9pt"
|
||||||
|
|
||||||
|
children :+= new Widget {
|
||||||
|
private val logo: Widget = new Widget {
|
||||||
|
override def minimumSize: Size2D = Spritesheet.spriteSize("Logo") + 40
|
||||||
|
|
||||||
|
override def draw(g: Graphics): Unit = {
|
||||||
|
g.sprite("Logo", bounds.x + 20, bounds.y + 80, ColorScheme("AboutLogo"))
|
||||||
|
drawChildren(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
children :+= logo
|
||||||
|
|
||||||
|
children :+= new PaddingBox(new Widget {
|
||||||
|
override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 8)
|
||||||
|
|
||||||
|
children :++= Seq(
|
||||||
|
new PaddingBox(AboutLabel("OCELOT DESKTOP"), Padding2D(top = 32)),
|
||||||
|
new PaddingBox(AboutLabel(" OpenComputers Emulator", isSmall = true), Padding2D(bottom = 16)),
|
||||||
|
|
||||||
|
AboutLabel(s"Version: ${BuildInfo.version}"),
|
||||||
|
new PaddingBox(AboutLabel(s" (${BuildInfo.commit.take(7)})", isSmall = true), Padding2D(bottom = 16)),
|
||||||
|
|
||||||
|
AboutLabel(s"MIT License (c) ${Year.now.getValue} Ocelot Dev Team"),
|
||||||
|
AboutLabel(" OpenComputers (C) 2013-2015, MIT, Florian \"Sangar\" Nücke", isSmall = true),
|
||||||
|
AboutLabel(" MineOS (C) 2022, Dungeon MIT License, ECS", isSmall = true),
|
||||||
|
AboutLabel(" Advanced Loader (C) 2018, MIT, Luca_S", isSmall = true),
|
||||||
|
AboutLabel(" LuaJ (C) 2007, MIT, Luaj.org", isSmall = true),
|
||||||
|
AboutLabel(" Unifont (C) 2007, SIL OFL 1.1, Roman Czyborra", isSmall = true),
|
||||||
|
AboutLabel(" Unscii (Public Domain) by viznut", isSmall = true),
|
||||||
|
AboutLabel(" wcwidth (C) 2005-2020, MIT, Rich Felker, et al.", isSmall = true),
|
||||||
|
AboutLabel(" JNLua (C) 2008-2012, MIT, Andre Naef", isSmall = true),
|
||||||
|
AboutLabel(" LuaJ (C) 2007, MIT, Luaj.org", isSmall = true),
|
||||||
|
AboutLabel(" Typesafe Config (C) 2011-2012, Apache License 2.0, Typesafe Inc.", isSmall = true),
|
||||||
|
)
|
||||||
|
|
||||||
|
children :+= new Filler
|
||||||
|
|
||||||
|
children :+= new Widget {
|
||||||
|
children :+= new Filler {
|
||||||
|
override def maximumSize: Size2D = Size2D(Float.PositiveInfinity, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Desktop.isDesktopSupported) {
|
||||||
|
children :+= new PaddingBox(new AboutButton("Website", WebsiteURL), Padding2D(right = 8))
|
||||||
|
children :+= new PaddingBox(new AboutButton("IRC", IrcURL), Padding2D(right = 8))
|
||||||
|
children :+= new PaddingBox(new AboutButton("Discord", DiscordURL), Padding2D(right = 20))
|
||||||
|
}
|
||||||
|
|
||||||
|
children :+= new Button {
|
||||||
|
override def text: String = "Ok"
|
||||||
|
override def onClick(): Unit = close()
|
||||||
|
override protected def colorScheme: ColorScheme = customButtonColorScheme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Padding2D.equal(18))
|
||||||
|
|
||||||
|
override def draw(g: Graphics): Unit = {
|
||||||
|
g.rect(bounds.x, bounds.y, logo.bounds.w, bounds.h, ColorScheme("Accent"))
|
||||||
|
super.draw(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def drawInner(g: Graphics): Unit = {
|
||||||
|
DrawUtils.shadow(g, bounds.x - 8, bounds.y - 8, bounds.w + 16, bounds.h + 20, 0.5f)
|
||||||
|
g.rect(bounds, ColorScheme("ContextMenuBackground"))
|
||||||
|
DrawUtils.ring(g, bounds.x, bounds.y, bounds.w, bounds.h, 1, ColorScheme("ContextMenuBorder"))
|
||||||
|
|
||||||
|
drawChildren(g)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def customButtonColorScheme = {
|
||||||
|
val scheme = new ColorScheme()
|
||||||
|
scheme.add("ButtonBackground", ColorScheme("AboutButtonBackground"))
|
||||||
|
scheme.add("ButtonBorder", ColorScheme("AboutButtonBorder"))
|
||||||
|
scheme.add("ButtonForeground", ColorScheme("AboutButtonForeground"))
|
||||||
|
scheme.add("ButtonBackgroundDisabled", ColorScheme("ButtonBackgroundDisabled"))
|
||||||
|
scheme.add("ButtonBorderDisabled", ColorScheme("ButtonBorderDisabled"))
|
||||||
|
scheme.add("ButtonForegroundDisabled", ColorScheme("ButtonForegroundDisabled"))
|
||||||
|
scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AboutButton(val label: String, val url: String) extends Button(new LabelTooltip(url)) {
|
||||||
|
override def text: String = label
|
||||||
|
override def onClick(): Unit = Desktop.getDesktop.browse(new URI(url))
|
||||||
|
override protected def colorScheme: ColorScheme = customButtonColorScheme
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AboutLabel(private val _text: String, private val _isSmall: Boolean = false) extends Label {
|
||||||
|
override def text: String = _text
|
||||||
|
override def isSmall: Boolean = _isSmall
|
||||||
|
override def color: Color = if (isSmall) ColorScheme("AboutForegroundSubtle") else ColorScheme("AboutForeground")
|
||||||
|
}
|
||||||
|
|
||||||
|
private object AboutLabel {
|
||||||
|
def apply(text: String, isSmall: Boolean = false): AboutLabel = new AboutLabel(text, isSmall)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
package ocelot.desktop.ui.widget.help
|
||||||
|
|
||||||
|
import buildinfo.BuildInfo
|
||||||
|
import ocelot.desktop.ColorScheme
|
||||||
|
import ocelot.desktop.geometry.{Padding2D, Size2D}
|
||||||
|
import ocelot.desktop.graphics.IconSource
|
||||||
|
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
|
||||||
|
import ocelot.desktop.ui.widget.{Button, Filler, Icon, Label, PaddingBox, Widget}
|
||||||
|
import ocelot.desktop.ui.widget.modal.ModalDialog
|
||||||
|
import ocelot.desktop.util.Orientation.Vertical
|
||||||
|
import ocelot.desktop.util.{Logging, OcelotOnlineAPI}
|
||||||
|
|
||||||
|
import java.awt.Desktop
|
||||||
|
import java.net.URI
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import scala.collection.immutable.ArraySeq
|
||||||
|
import scala.util.{Failure, Success}
|
||||||
|
|
||||||
|
class UpdateCheckerDialog extends ModalDialog with Logging {
|
||||||
|
private val dateFormat = DateTimeFormatter.ofPattern("dd MMM YYYY (HH:mm:ss Z)")
|
||||||
|
|
||||||
|
private val container = new Widget {
|
||||||
|
override protected val layout: Layout = new LinearLayout(this, orientation = Vertical)
|
||||||
|
}
|
||||||
|
|
||||||
|
children :+= new PaddingBox(new Widget {
|
||||||
|
override protected val layout: Layout = new LinearLayout(this, orientation = Vertical, gap = 16)
|
||||||
|
|
||||||
|
children :+= container
|
||||||
|
|
||||||
|
children :+= new Widget {
|
||||||
|
children :+= new Filler {
|
||||||
|
override def maximumSize: Size2D = Size2D(Float.PositiveInfinity, 1)
|
||||||
|
}
|
||||||
|
children :+= new Button {
|
||||||
|
override def text: String = "Ok"
|
||||||
|
override def onClick(): Unit = close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Padding2D.equal(16))
|
||||||
|
|
||||||
|
// loading screen
|
||||||
|
container.children :+= new Label("Checking development news...")
|
||||||
|
container.children :+= new PaddingBox(new Icon(IconSource.Loading, color = ColorScheme("Label")), Padding2D(16, 0, 0, 90))
|
||||||
|
|
||||||
|
// check the API
|
||||||
|
OcelotOnlineAPI.checkRemoteVersion {
|
||||||
|
case Success(version) =>
|
||||||
|
setContainerChildren(ArraySeq.empty)
|
||||||
|
if (version.releaseVersion.isDefined) {
|
||||||
|
val newReleaseVersion = version.releaseVersion.get.drop(1)
|
||||||
|
container.children :+= new Label(s"Release: ${BuildInfo.version} ▸ ${newReleaseVersion}")
|
||||||
|
if (newReleaseVersion == BuildInfo.version) {
|
||||||
|
container.children :+= new PaddingBox(new Label("Up to date!", small = true), Padding2D(6))
|
||||||
|
} else {
|
||||||
|
container.children :+= new PaddingBox(new Label("New release version is available:", small = true), Padding2D(6))
|
||||||
|
if (Desktop.isDesktopSupported) {
|
||||||
|
container.children :+= new PaddingBox(new Button {
|
||||||
|
override def text: String = "Download"
|
||||||
|
|
||||||
|
override def onClick(): Unit = Desktop.getDesktop.browse(new URI("https://ocelot.fomalhaut.me/desktop"))
|
||||||
|
}, Padding2D(6))
|
||||||
|
} else {
|
||||||
|
container.children :+= new PaddingBox(new Label("https://ocelot.fomalhaut.me/desktop", small = true), Padding2D(6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.children :+= new Label("Release: N\\A")
|
||||||
|
}
|
||||||
|
|
||||||
|
container.children :+= new Filler {
|
||||||
|
override def minimumSize: Size2D = Size2D(8, 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.devId.isDefined && version.devDate.isDefined) {
|
||||||
|
val newDevVersion = version.devId.get.take(7)
|
||||||
|
container.children :+= new Label(s"Dev build: ${BuildInfo.commit.take(7)} ▸ ${newDevVersion}")
|
||||||
|
if (BuildInfo.commit.take(7) == newDevVersion) {
|
||||||
|
container.children :+= new PaddingBox(new Label("Up to date!", small = true), Padding2D(6))
|
||||||
|
} else {
|
||||||
|
container.children :+= new PaddingBox(
|
||||||
|
new Label(s"New dev build from ${version.devDate.get.withZoneSameInstant(ZoneId.systemDefault()).format(dateFormat)}:", small = true)
|
||||||
|
, Padding2D(4))
|
||||||
|
if (Desktop.isDesktopSupported) {
|
||||||
|
container.children :+= new PaddingBox(new Button {
|
||||||
|
override def text: String = "Download"
|
||||||
|
|
||||||
|
override def onClick(): Unit = Desktop.getDesktop.browse(new URI("https://ocelot.fomalhaut.me/desktop"))
|
||||||
|
}, Padding2D(6))
|
||||||
|
} else {
|
||||||
|
container.children :+= new PaddingBox(new Label("https://ocelot.fomalhaut.me/desktop", small = true), Padding2D(6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.children :+= new Label("Dev build: N\\A")
|
||||||
|
}
|
||||||
|
|
||||||
|
case Failure(exception) =>
|
||||||
|
logger.error("Cannot download information about new Ocelot version!", exception)
|
||||||
|
val message = "Ocelot website is unavailable...\n" +
|
||||||
|
s"($exception)\n" +
|
||||||
|
"Check the log file for a full stacktrace."
|
||||||
|
setContainerChildren(ArraySeq.unsafeWrapArray(message.split('\n').map(line => new Label {
|
||||||
|
override def text: String = line
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
private def setContainerChildren(children: ArraySeq[Widget]): Unit = {
|
||||||
|
container.children.foreach(it => { it.parent = None; it.root = None })
|
||||||
|
container.children = children
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,6 @@ import ocelot.desktop.util.animation.UnitAnimation
|
|||||||
import org.lwjgl.input.Keyboard
|
import org.lwjgl.input.Keyboard
|
||||||
|
|
||||||
abstract class ModalDialog(val autoClose: Boolean = true) extends Widget {
|
abstract class ModalDialog(val autoClose: Boolean = true) extends Widget {
|
||||||
protected def dialogPool: ModalDialogPool = parent.get.asInstanceOf[ModalDialogPool]
|
|
||||||
protected val openCloseAnimation: UnitAnimation = UnitAnimation.easeInOutQuad(0.13f)
|
protected val openCloseAnimation: UnitAnimation = UnitAnimation.easeInOutQuad(0.13f)
|
||||||
|
|
||||||
if (autoClose) {
|
if (autoClose) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package ocelot.desktop.ui.widget.modal.notification
|
|||||||
|
|
||||||
import ocelot.desktop.ColorScheme
|
import ocelot.desktop.ColorScheme
|
||||||
import ocelot.desktop.color.Color
|
import ocelot.desktop.color.Color
|
||||||
import ocelot.desktop.geometry.Padding2D
|
import ocelot.desktop.geometry.{Padding2D, Size2D}
|
||||||
import ocelot.desktop.graphics.{Graphics, IconSource}
|
import ocelot.desktop.graphics.{Graphics, IconSource}
|
||||||
import ocelot.desktop.ui.layout.LinearLayout
|
import ocelot.desktop.ui.layout.LinearLayout
|
||||||
import ocelot.desktop.ui.widget._
|
import ocelot.desktop.ui.widget._
|
||||||
@ -11,7 +11,7 @@ import ocelot.desktop.ui.widget.modal.notification.NotificationType.Notification
|
|||||||
import ocelot.desktop.util.{DrawUtils, Orientation}
|
import ocelot.desktop.util.{DrawUtils, Orientation}
|
||||||
|
|
||||||
class NotificationDialog(message: String, notificationType: NotificationType = NotificationType.Warning) extends ModalDialog {
|
class NotificationDialog(message: String, notificationType: NotificationType = NotificationType.Warning) extends ModalDialog {
|
||||||
protected val buttonsLayout: Widget = new Widget {
|
private val buttonsLayout: Widget = new Widget {
|
||||||
override val layout: LinearLayout = new LinearLayout(this, gap = 15)
|
override val layout: LinearLayout = new LinearLayout(this, gap = 15)
|
||||||
|
|
||||||
children :+= new Filler
|
children :+= new Filler
|
||||||
@ -30,7 +30,7 @@ class NotificationDialog(message: String, notificationType: NotificationType = N
|
|||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
children :+= new PaddingBox(
|
children :+= new PaddingBox(
|
||||||
new Icon(IconSource.Notification(notificationType)),
|
new Icon(IconSource.Notification(notificationType), Size2D(22, 22)),
|
||||||
Padding2D.equal(10)
|
Padding2D.equal(10)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,7 @@ class SystemSettingsTab extends SettingsTab {
|
|||||||
override val icon: IconSource = IconSource.SettingsSystem
|
override val icon: IconSource = IconSource.SettingsSystem
|
||||||
override val label: String = "System"
|
override val label: String = "System"
|
||||||
|
|
||||||
children :+= new PaddingBox(new Label {
|
children :+= new PaddingBox(new Label("OpenComputers configuration file path"), Padding2D(bottom = 8))
|
||||||
override def text = "OpenComputers configuration file path"
|
|
||||||
}, Padding2D(bottom = 8))
|
|
||||||
|
|
||||||
children :+= new PaddingBox(new Widget {
|
children :+= new PaddingBox(new Widget {
|
||||||
override val layout = new LinearLayout(this, orientation = Orientation.Horizontal)
|
override val layout = new LinearLayout(this, orientation = Orientation.Horizontal)
|
||||||
|
|||||||
@ -22,9 +22,7 @@ class VerticalMenuButton(icon: IconSource, label: String, handler: VerticalMenuB
|
|||||||
override val layout = new LinearLayout(this, orientation = Orientation.Horizontal)
|
override val layout = new LinearLayout(this, orientation = Orientation.Horizontal)
|
||||||
|
|
||||||
children :+= new PaddingBox(
|
children :+= new PaddingBox(
|
||||||
new Icon(icon) {
|
new Icon(icon, color = ColorScheme("VerticalMenuEntryIcon")),
|
||||||
override def iconColor: Color = ColorScheme("VerticalMenuEntryIcon")
|
|
||||||
},
|
|
||||||
Padding2D(right = 8)
|
Padding2D(right = 8)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
49
src/main/scala/ocelot/desktop/util/OcelotOnlineAPI.scala
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ocelot.desktop.util
|
||||||
|
|
||||||
|
import java.net.{HttpURLConnection, URL}
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
import scala.util.{Success, Try, Using}
|
||||||
|
|
||||||
|
object OcelotOnlineAPI {
|
||||||
|
private val UrlInfo: String = "https://ocelot.fomalhaut.me/desktop/info"
|
||||||
|
|
||||||
|
private val RegexDevId = "\"dev\":\\s?\\{.*?\"id\":\\s?\"(.*?)\"".r
|
||||||
|
private val RegexDevDate = "\"dev\":\\s?\\{.*?\"date\":\\s?\"(.*?)\"".r
|
||||||
|
private val RegexReleaseVersion = "\"release\":\\s?\\{.*?\"version\":\\s?\"(.*?)\"".r
|
||||||
|
private val RegexReleaseDate = "\"release\":\\s?\\{.*?\"date\":\\s?\"(.*?)\"".r
|
||||||
|
|
||||||
|
def checkRemoteVersion(callback: Try[Version] => Unit): Unit =
|
||||||
|
new Thread(() => callback(getVersion)).start()
|
||||||
|
|
||||||
|
private def getVersion: Try[Version] = Try {
|
||||||
|
val source = scala.io.Source.fromURL(UrlInfo)
|
||||||
|
val response = source.mkString
|
||||||
|
|
||||||
|
val devId = RegexDevId.findFirstMatchIn(response).map(_.group(1))
|
||||||
|
val devDate = RegexDevDate.findFirstMatchIn(response).map(_.group(1))
|
||||||
|
val releaseVersion = RegexReleaseVersion.findFirstMatchIn(response).map(_.group(1))
|
||||||
|
val releaseDate = RegexReleaseDate.findFirstMatchIn(response).map(_.group(1))
|
||||||
|
val version = Version(
|
||||||
|
devId, devDate.map(it => ZonedDateTime.parse(it)),
|
||||||
|
releaseVersion, releaseDate.map(it => ZonedDateTime.parse(it))
|
||||||
|
)
|
||||||
|
|
||||||
|
source.close()
|
||||||
|
version
|
||||||
|
}
|
||||||
|
|
||||||
|
@throws(classOf[java.io.IOException])
|
||||||
|
@throws(classOf[java.net.SocketTimeoutException])
|
||||||
|
def get(url: String, connectTimeout: Int = 5000, readTimeout: Int = 5000, requestMethod: String = "GET"): String = {
|
||||||
|
val connection = new URL(url).openConnection.asInstanceOf[HttpURLConnection]
|
||||||
|
connection.setConnectTimeout(connectTimeout)
|
||||||
|
connection.setReadTimeout(readTimeout)
|
||||||
|
connection.setRequestMethod(requestMethod)
|
||||||
|
Using.resource(connection.getInputStream) { inputStream =>
|
||||||
|
val content = io.Source.fromInputStream(inputStream).mkString
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class Version(devId: Option[String], devDate: Option[ZonedDateTime], releaseVersion: Option[String], releaseDate: Option[ZonedDateTime])
|
||||||
|
}
|
||||||