Compare commits

1 Commits

Author SHA1 Message Date
56dcbb62af functional card/row edit and drag 2024-04-23 23:31:42 -05:00
29 changed files with 674 additions and 48 deletions

23
ClearButton.cs Normal file
View File

@@ -0,0 +1,23 @@
using Godot;
using System;
public partial class ClearButton : Button
{
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public void EnableToggled(bool newState)
{
Disabled = !newState;
}
public void ClearPressed()
{
this.GetParentOfType<game>().Clear();
}
}

View File

@@ -51,14 +51,11 @@ public partial class CommandHandler : Node
private void IncomingCommand(Command command)
{
GD.Print("Received command");
if (!Settings.IsUserAuthorized(command.User, command.IsStreamer,
command.IsModerator))
return;
GD.Print($"User {command.User} is authorized");
var baseArgs = command.GetArgs();
var type = CommandTypeHelper.ParseCommand(baseArgs.Pop());
GD.Print($"Command type: {type}");
var args = baseArgs.DuplicateAtState();
switch (type)
{

19
ExportButton.cs Normal file
View File

@@ -0,0 +1,19 @@
using Godot;
using System;
public partial class ExportButton : Button
{
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public void ExportPressed()
{
GetNode<FileDialog>("%ExportDialog").Show();
}
}

9
ExportSettings.cs Normal file
View File

@@ -0,0 +1,9 @@
using Godot;
public partial class ExportSettings : GodotObject
{
/// <summary>
/// Scales images down to size of the
/// </summary>
public bool ScaleImages { get; set; } = false;
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using Godot.NativeInterop;
public static class ExtensionHelper
{
@@ -65,10 +66,11 @@ public static class ExtensionHelper
i++;
}
}
public static string GetUnusedCardId(this SceneTree tree)
public static string GetUnusedCardId(this SceneTree tree, params string[] otherIds)
{
//use hashset because there are (probably) more cards than rows
var ids = tree.GetNodesInGroup("CardGroup").OfType<card>().Select(c => c.CardId).ToHashSet();
var ids = tree.GetNodesInGroup("CardGroup").OfType<card>().Select(c => c.CardId)
.Concat(otherIds).ToHashSet();
int i = 1;
while (true)
{
@@ -91,4 +93,17 @@ public static class ExtensionHelper
=> new(Math.Max(vect.X, other.X), Math.Max(vect.Y, other.Y));
public static Vector2I Union(this Vector2I vect, Vector2 other)
=> new((int)Math.Max(vect.X, other.X), (int)Math.Max(vect.Y, other.Y));
public static System.Drawing.Color ToSystemColor(this Godot.Color color)
=> System.Drawing.Color.FromArgb(
(int)(color.R * 255),
(int)(color.G * 255),
(int)(color.B * 255)
);
public static Godot.Color ToGodotColor(this System.Drawing.Color color)
=> new Godot.Color(
color.R / 255.0f,
color.G / 255.0f,
color.B / 255.0f,
1
);
}

19
ImportButton.cs Normal file
View File

@@ -0,0 +1,19 @@
using Godot;
using System;
public partial class ImportButton : Button
{
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public void ImportPressed()
{
GetNode<FileDialog>("%ImportDialog").Show();
}
}

17
ImportMarginContainer.cs Normal file
View File

@@ -0,0 +1,17 @@
using Godot;
using System;
public partial class ImportMarginContainer : MarginContainer
{
public readonly string Title = "Import";
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
GetParentOrNull<TabContainer>().SetTabTitle(GetIndex(), Title);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
}

View File

@@ -18,6 +18,6 @@ public partial class RowCardContainer : HFlowContainer
}
public override void _DropData(Vector2 atPosition, Variant data)
{
this.GetParentOfType<row>().DropOn(atPosition, data);
this.GetParentOfType<row>().DropCardOn(atPosition, data);
}
}

39
RowTitleBoxBackground.cs Normal file
View File

@@ -0,0 +1,39 @@
using Godot;
using System;
public partial class RowTitleBoxBackground : Panel
{
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public override void _GuiInput(InputEvent @event)
{
if (@event.IsActionPressed("LocationMenu"))
{
RowMenu();
}
}
private void RowMenu()
{
this.GetParentOfType<game>().EditRowInMenu(this.GetParentOfType<row>());
}
public override Variant _GetDragData(Vector2 atPosition)
{
var prev = MakePreview();
var prev_root = new Control();
prev_root.AddChild(prev);
prev.Position = prev.Size / -2;
SetDragPreview(prev_root);
return this.GetParentOfType<row>();
}
private Panel MakePreview()
{
return Duplicate(0) as Panel;
}
}

View File

@@ -0,0 +1,29 @@
using Godot;
using System;
using System.Data.Common;
using System.Linq;
using System.Text.Json.Serialization;
public class SerialCard
{
[JsonInclude]
public string Text { get; set; }
[JsonInclude]
public SerialImage Image { get; set; }
public card ToCard(SceneTree tree)
{
var c = card.MakeCard(tree);
c.CardName = Text;
if (Image.DataWebp.Any())
{
var iwm = Image.ToImageWithMetadata();
c.SetTexture(ImageTexture.CreateFromImage(iwm.Image));
c.SetStretchMode(iwm.StretchMode);
}
else
{
c.SetStretchMode(Image.StretchMode);
}
return c;
}
}

View File

@@ -0,0 +1,42 @@
using Godot;
using System.Text.Json.Serialization;
public class SerialColor
{
[JsonInclude]
public float R { get; set; }
[JsonInclude]
public float G { get; set; }
[JsonInclude]
public float B { get; set; }
public void Deconstruct(out float r, out float g, out float b)
{
r = R;
g = G;
b = B;
}
public SerialColor()
{
R = 0;
G = 0;
B = 0;
}
public SerialColor(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
public SerialColor(Color c)
{
R = c.R;
G = c.G;
B = c.B;
}
public static implicit operator Color(SerialColor sc)
=> new(
sc.R,
sc.G,
sc.B
);
}

View File

@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;
public class SerialGame
{
[JsonInclude]
public SerialRow[] Rows { get; set; }
[JsonInclude]
public SerialCard[] UnassignedCards { get; set; }
}

View File

@@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
using Godot;
public class SerialImage
{
[JsonInclude]
public byte[] DataWebp { get; set; }
[JsonInclude]
[JsonConverter(typeof(JsonStringEnumConverter))]
public StretchMode StretchMode { get; set; }
public ImageWithMetadata ToImageWithMetadata()
{
var im = new Image();
im.LoadWebpFromBuffer(DataWebp);
return new(im, StretchMode);
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Godot;
public class SerialRow
{
[JsonInclude]
public string Text { get; set; }
[JsonInclude]
public SerialColor Color { get; set; }
[JsonInclude]
public SerialCard[] Cards { get; set; }
public row ToRow(SceneTree tree)
{
var r = row.MakeRow(tree);
r.RowText = Text;
r.RowColor = Color;
foreach (var c in Cards)
r.AddCard(c.ToCard(tree));
return r;
}
}

View File

@@ -0,0 +1,65 @@
using Godot;
using System;
using System.Linq;
using System.Text.Json;
public static class Serializer
{
public static string CreateGameJson(game g, ExportSettings es)
=> JsonSerializer.Serialize(CreateGameObject(g, es));
private static SerialGame CreateGameObject(game g, ExportSettings es)
=> new()
{
Rows = g.GetNode("%RowContainer").GetChildren().OfType<row>()
.Select(r => RowToSerial(r, es)).ToArray(),
UnassignedCards = g.GetNode("%UnassignedCardContainer").GetChildren()
.OfType<card>().Select(c => CardToSerial(c, es)).ToArray(),
};
private static SerialRow RowToSerial(row r, ExportSettings es)
=> new()
{
Color = new(r.RowColor),
Cards = r.Cards.Select(c => CardToSerial(c, es)).ToArray(),
Text = r.RowText
};
private static SerialCard CardToSerial(card c, ExportSettings es)
{
byte[] imData;
var i = c.GetTexture()?.GetImage();
if (i is Image img)
{
if (es.ScaleImages)
{
Image copy = new();
copy.CopyFrom(img);
copy.Resize(500, 500);
imData = copy.SaveWebpToBuffer(true);
}
else
imData = img.SaveWebpToBuffer(false);
}
else
imData = Array.Empty<byte>();
return new()
{
Text = c.CardName,
Image = new()
{
DataWebp = imData,
StretchMode = c.GetStretchMode(),
},
};
}
public static void LoadFromSerial(game g, string jsonString)
{
var sg = JsonSerializer.Deserialize<SerialGame>(jsonString)
?? throw new Exception("Failed to deserialize game");
g.Clear();
using var context = card.MakeContext(g.GetTree());
foreach (var r in sg.Rows)
g.AddRow(r.ToRow(g.GetTree()));
foreach (var c in sg.UnassignedCards)
g.AddUnassignedCard(c.ToCard(g.GetTree()));
g.PropogateCardSize();
}
}

View File

@@ -0,0 +1,4 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://cota68polt1iy"]
[resource]
bg_color = Color(0.32549, 0.32549, 0.32549, 1)

View File

@@ -179,6 +179,8 @@ public partial class TwitchChatWatcher : Node
else if (tcm is Privmsg p)
{
var com = Settings.Command;
if (string.IsNullOrWhiteSpace(com))
break;
if (!p.ChatMessage.StartsWith(com))
continue;
var chat = p.ChatMessage;

36
card.cs
View File

@@ -1,4 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Godot;
using Microsoft.VisualBasic;
public partial class card : Panel
{
@@ -150,11 +155,40 @@ public partial class card : Panel
{
this.GetParentOfType<game>().EditCardInMenu(this);
}
//TODO need to completely rework this
public static card MakeCard(SceneTree tree)
{
var scene = GD.Load<PackedScene>("res://card.tscn");
var c = scene.Instantiate<card>();
c.CardId = tree.GetUnusedCardId();
string[] ids = {};
if (Context is CardMakerContext cme)
ids = cme.Ids.ToArray();
c.CardId = tree.GetUnusedCardId(ids);
if (Context is CardMakerContext cme2)
cme2.AddNewId(c.CardId);
return c;
}
public class CardMakerContext : IDisposable
{
private readonly SceneTree Tree;
private readonly List<string> NewCards = new();
public IEnumerable<string> Ids => NewCards;
public void AddNewId(string id) => NewCards.Add(id);
public CardMakerContext(SceneTree tree)
{
Tree = tree;
}
public void Dispose()
{
card.Context = null;
}
}
private static CardMakerContext Context = null;
public static CardMakerContext MakeContext(SceneTree tree)
{
if (Context is not null)
return null;
Context = new(tree);
return Context;
}
}

View File

@@ -120,6 +120,11 @@ public partial class card_edit_popup : ConfirmationDialog
{
// Hide();
}
public void DeleteCard()
{
this.GetParentOfType<game>().DeleteCards(EditingCard.CardId);
Hide();
}
public void FileSelected(string path)
{
Image image = new();

View File

@@ -11,7 +11,7 @@
[node name="CardEditPopup" type="ConfirmationDialog"]
title = "Edit Card"
position = Vector2i(0, 36)
size = Vector2i(350, 320)
size = Vector2i(350, 327)
visible = true
unresizable = true
always_on_top = true
@@ -24,7 +24,7 @@ anchor_bottom = 1.0
offset_left = 8.0
offset_top = 8.0
offset_right = 342.0
offset_bottom = 271.0
offset_bottom = 278.0
grow_horizontal = 2
grow_vertical = 2
@@ -88,10 +88,18 @@ layout_mode = 2
button_group = SubResource("ButtonGroup_t74v5")
text = "Crop"
[node name="DeleteCardButton" type="Button" parent="CardEditContainer"]
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 8
text = "DELETE"
[node name="CardImagePicker" parent="." instance=ExtResource("3_4k21m")]
unique_name_in_owner = true
[connection signal="canceled" from="." to="." method="CancelClicked"]
[connection signal="confirmed" from="." to="." method="OkClicked"]
[connection signal="visibility_changed" from="." to="." method="OnVisibilityChange"]
[connection signal="pressed" from="CardEditContainer/DeleteCardButton" to="." method="DeleteCard"]
[connection signal="file_selected" from="CardImagePicker" to="." method="FileSelected"]

1
debug.log Normal file
View File

@@ -0,0 +1 @@
[0423/181235.827:ERROR:registration_protocol_win.cc(107)] CreateFile: The system cannot find the file specified. (0x2)

74
game.cs
View File

@@ -2,7 +2,9 @@ using Godot;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
public partial class game : Control
{
@@ -30,16 +32,18 @@ public partial class game : Control
{
CardSize = size;
}
protected void PropogateCardSize()
public void PropogateCardSize()
{
foreach (var r in GetNode("%RowContainer").GetChildren().OfType<row>())
r.CardSize = _CardSize;
foreach (var c in GetNode("%UnassignedCardContainer").GetChildren().OfType<card>())
c.CustomMinimumSize = _CardSize;
SetContainerMinima();
}
public bool AllowDragging = true;
public IEnumerable<row> Rows
=> GetNode<VBoxContainer>("%RowContainer").GetChildren().OfType<row>();
=> GetNode("%RowContainer").GetChildren().OfType<row>();
public IEnumerable<card> UnassignedCards
=> GetNode("%UnassignedCardContainer").GetChildren().OfType<card>();
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
@@ -78,38 +82,38 @@ public partial class game : Control
GetViewport().SetInputAsHandled();
}
}
public void Clear()
{
var rowContainer = GetNode("%RowContainer");
var unContainer = GetNode("%UnassignedCardContainer");
foreach (var r in rowContainer.GetChildren())
{
rowContainer.RemoveChild(r);
r.QueueFree();
}
foreach (var c in unContainer.GetChildren())
{
unContainer.RemoveChild(c);
c.QueueFree();
}
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public void SetContainerMinima()
{
// var node = GetNode<VBoxContainer>("%RowContainer");
// node.CustomMinimumSize = new Vector2(0, _CardSize.Y * node.GetChildCount());
}
public row GetRowById(string id)
=> GetTree().GetNodesInGroup("RowGroup").OfType<row>()
.FirstOrDefault(r => r.RowId == id);
public void AddRow(row row, string after = null)
public void AddRow(row row, int index = -1)
{
if (after is not null)
{
var r = GetRowById(after) ?? throw new Exception("row id does not exist");
r.AddSibling(row);
}
else
{
var node = GetNode<VBoxContainer>("%RowContainer");
node.AddChild(row);
node.MoveChild(row, 0);
}
SetContainerMinima();
var node = GetNode<VBoxContainer>("%RowContainer");
node.AddChild(row);
node.MoveChild(row, index);
}
public void RemoveRow(string id)
{
var r = GetRowById(id);
GetNode<VBoxContainer>("%RowContainer").RemoveChild(r);
SetContainerMinima();
}
public void AddUnassignedCard(card c)
{
@@ -131,6 +135,10 @@ public partial class game : Control
{
GetNode<card_edit_popup>("%CardEditPopup").ActivateForCard(c);
}
public void EditRowInMenu(row r)
{
GetNode<row_edit_popup>("%RowEditPopup").OpenWithRow(r);
}
public card ClaimCard(string id)
{
foreach (row r in Rows)
@@ -157,6 +165,28 @@ public partial class game : Control
return null;
}
public void MenuOpenDisableInteraction()
{
GetNode<Control>("%UiMask").MouseFilter = MouseFilterEnum.Stop;
}
public void MenuClosedEnableInteraction()
{
GetNode<Control>("%UiMask").MouseFilter = MouseFilterEnum.Ignore;
}
public void ImportGame(string filename)
{
GD.Print($"Importing from {filename}");
Serializer.LoadFromSerial(this,
File.ReadAllText(filename)
);
}
public void ExportGame(string filename, ExportSettings es)
{
GD.Print($"Exporting to {filename}");
File.WriteAllText(filename,
Serializer.CreateGameJson(this, es)
);
}
#region Commands
public void MoveCard(string cardId, string targetRowId, int? toIndex = null)
{

View File

@@ -1,11 +1,13 @@
[gd_scene load_steps=7 format=3 uid="uid://ck0t4k3guvmfm"]
[gd_scene load_steps=9 format=3 uid="uid://ck0t4k3guvmfm"]
[ext_resource type="PackedScene" uid="uid://b7pebyti48f7b" path="res://row.tscn" id="1_numg7"]
[ext_resource type="Script" path="res://game.cs" id="1_vl33u"]
[ext_resource type="Script" path="res://UnassignedCardPanel.cs" id="3_dbs2t"]
[ext_resource type="Script" path="res://PictureDropHandler.cs" id="3_owd27"]
[ext_resource type="StyleBox" uid="uid://cota68polt1iy" path="res://SettingsOverlayStyleBox.tres" id="6_8am6d"]
[ext_resource type="PackedScene" uid="uid://jm7tss267q8y" path="res://settings_popup.tscn" id="6_e1cou"]
[ext_resource type="PackedScene" uid="uid://dxvues6b3g2tn" path="res://card_edit_popup.tscn" id="6_eqvov"]
[ext_resource type="PackedScene" uid="uid://dwtxrx5xtewur" path="res://row_edit_popup.tscn" id="7_nyiqt"]
[node name="Game" type="Control"]
layout_mode = 3
@@ -27,6 +29,7 @@ grow_horizontal = 2
grow_vertical = 2
[node name="GameContainer" type="VBoxContainer" parent="GameScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
@@ -79,23 +82,31 @@ layout_mode = 2
unique_name_in_owner = true
script = ExtResource("3_owd27")
[node name="CardContextMenu" type="PopupMenu" parent="."]
item_count = 2
item_0/text = "Rename"
item_0/id = 0
item_1/text = "Change Picture"
item_1/id = 1
[node name="RowContextMenu" type="PopupMenu" parent="."]
item_count = 1
item_0/text = ""
item_0/id = 0
[node name="UiMask" type="Control" parent="."]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="SettingsPopup" parent="." instance=ExtResource("6_e1cou")]
unique_name_in_owner = true
visible = false
layout_mode = 0
theme_override_styles/panel = ExtResource("6_8am6d")
[node name="RowEditPopup" parent="." instance=ExtResource("7_nyiqt")]
unique_name_in_owner = true
visible = false
layout_mode = 0
theme_override_styles/panel = ExtResource("6_8am6d")
[node name="CardEditPopup" parent="." instance=ExtResource("6_eqvov")]
unique_name_in_owner = true
visible = false
[connection signal="ExportSelected" from="SettingsPopup" to="." method="ExportGame"]
[connection signal="ImportSelected" from="SettingsPopup" to="." method="ImportGame"]

19
row.cs
View File

@@ -98,7 +98,7 @@ public partial class row : Control
{
}
public void DropOn(Vector2 atPosition, Variant data)
public void DropCardOn(Vector2 atPosition, Variant data)
{
GD.Print($"Dropping at {atPosition}");
card c = data.As<card>()
@@ -128,6 +128,23 @@ public partial class row : Control
{
throw new Exception($"Can't find card {c.CardId}");
}
}
public override bool _CanDropData(Vector2 atPosition, Variant data)
{
return data.As<row>() is not null;
}
public override void _DropData(Vector2 atPosition, Variant data)
{
var r = data.As<row>()
?? throw new Exception("Invalid drop row");
if (ReferenceEquals(this, r))
return;
var toIndex = GetIndex();
if (atPosition.Y > Size.Y / 2)
toIndex++;
if (r.GetIndex() < GetIndex())
toIndex--;
GetParent().MoveChild(r, toIndex);
}
public void AddCard(card card, int? toIndex = null)
{

View File

@@ -1,8 +1,9 @@
[gd_scene load_steps=8 format=3 uid="uid://b7pebyti48f7b"]
[gd_scene load_steps=9 format=3 uid="uid://b7pebyti48f7b"]
[ext_resource type="Script" path="res://row.cs" id="1_dodxa"]
[ext_resource type="Script" path="res://RowGrid.cs" id="2_h4wwk"]
[ext_resource type="Script" path="res://RowCardContainer.cs" id="3_0etg2"]
[ext_resource type="Script" path="res://RowTitleBoxBackground.cs" id="3_y52xd"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_spa1m"]
@@ -46,8 +47,9 @@ unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 0
mouse_filter = 2
mouse_filter = 1
theme_override_styles/panel = SubResource("StyleBoxFlat_22f0d")
script = ExtResource("3_y52xd")
[node name="RowTitleBoxLabel" type="Label" parent="RowGrid/RowBaseContainer/RowTitleBoxBackground"]
unique_name_in_owner = true

48
row_edit_popup.cs Normal file
View File

@@ -0,0 +1,48 @@
using Godot;
using System;
public partial class row_edit_popup : PanelContainer
{
[Export]
private Color DefaultColor = new(0, 0, 0, 1);
[Signal]
public delegate void NowVisibleEventHandler();
[Signal]
public delegate void NowInvisibleEventHandler();
public row EditingRow;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public void OpenWithRow(row r)
{
EditingRow = r;
GetNode<ColorPickerButton>("%ColorPickerButton").Color = r.RowColor;
GetNode<TextEdit>("%RowTextEdit").Text = r.RowText;
this.GetParentOfType<game>().MenuOpenDisableInteraction();
Show();
}
public void OkClicked()
{
EditingRow.RowColor = GetNode<ColorPickerButton>("%ColorPickerButton").Color;
EditingRow.RowText = GetNode<TextEdit>("%RowTextEdit").Text;
Reset();
}
public void CancelClicked()
{
Reset();
}
public void Reset()
{
GetNode<ColorPickerButton>("%ColorPickerButton").Color = DefaultColor;
GetNode<TextEdit>("%RowTextEdit").Text = "";
EditingRow = null;
Hide();
this.GetParentOfType<game>().MenuClosedEnableInteraction();
}
}

52
row_edit_popup.tscn Normal file
View File

@@ -0,0 +1,52 @@
[gd_scene load_steps=2 format=3 uid="uid://dwtxrx5xtewur"]
[ext_resource type="Script" path="res://row_edit_popup.cs" id="1_1wf8q"]
[node name="RowEditPopup" type="PanelContainer"]
script = ExtResource("1_1wf8q")
[node name="RowEditMarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_right = 5
theme_override_constants/margin_bottom = 5
[node name="VSplitContainer" type="VSplitContainer" parent="RowEditMarginContainer"]
layout_mode = 2
dragger_visibility = 1
[node name="RowEditVbox" type="HSplitContainer" parent="RowEditMarginContainer/VSplitContainer"]
layout_mode = 2
[node name="ColorPickerButton" type="ColorPickerButton" parent="RowEditMarginContainer/VSplitContainer/RowEditVbox"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 200)
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 0
edit_alpha = false
[node name="RowTextEdit" type="TextEdit" parent="RowEditMarginContainer/VSplitContainer/RowEditVbox"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
[node name="RowEditButtonContainer" type="HBoxContainer" parent="RowEditMarginContainer/VSplitContainer"]
layout_mode = 2
alignment = 2
[node name="RowEditCancelButton" type="Button" parent="RowEditMarginContainer/VSplitContainer/RowEditButtonContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_horizontal = 8
text = "Cancel"
[node name="RowEditOkButton" type="Button" parent="RowEditMarginContainer/VSplitContainer/RowEditButtonContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_horizontal = 8
text = "OK"
[connection signal="pressed" from="RowEditMarginContainer/VSplitContainer/RowEditButtonContainer/RowEditCancelButton" to="." method="CancelClicked"]
[connection signal="pressed" from="RowEditMarginContainer/VSplitContainer/RowEditButtonContainer/RowEditOkButton" to="." method="OkClicked"]

View File

@@ -19,6 +19,10 @@ public partial class settings_popup : PanelContainer
public string Channel => GetNode<LineEdit>("%ChannelNameEdit").Text;
[Signal]
public delegate void BeforeOkEventHandler();
[Signal]
public delegate void ImportSelectedEventHandler(string filename);
[Signal]
public delegate void ExportSelectedEventHandler(string filename, ExportSettings settings);
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
@@ -45,11 +49,13 @@ public partial class settings_popup : PanelContainer
}
public void ShowPopup()
{
Visible = true;
this.GetParentOfType<game>().MenuOpenDisableInteraction();
Show();
}
public void ClosePopup()
{
Hide();
this.GetParentOfType<game>().MenuClosedEnableInteraction();
}
public void _on_cancel_button_pressed()
{
@@ -116,4 +122,16 @@ public partial class settings_popup : PanelContainer
{
GetNode<BaseButton>("%ConnectButton").Disabled = false;
}
private void ImportFileSelected(string filename)
{
EmitSignal(SignalName.ImportSelected, filename);
}
private void ExportFileSelected(string filename)
{
ExportSettings es = new()
{
ScaleImages = GetNode<BaseButton>("%ExportCompressPicturesButton").ButtonPressed,
};
EmitSignal(SignalName.ExportSelected, filename, Variant.From(es));
}
}

View File

@@ -1,9 +1,13 @@
[gd_scene load_steps=7 format=3 uid="uid://jm7tss267q8y"]
[gd_scene load_steps=11 format=3 uid="uid://jm7tss267q8y"]
[ext_resource type="Script" path="res://settings_popup.cs" id="1_blkox"]
[ext_resource type="Script" path="res://ConfigStretchContainer.cs" id="2_fhn7i"]
[ext_resource type="Script" path="res://ChatMarginContainer.cs" id="2_x6hlu"]
[ext_resource type="Script" path="res://ConfigMarginContainer.cs" id="3_pguul"]
[ext_resource type="Script" path="res://ClearButton.cs" id="5_71uyg"]
[ext_resource type="Script" path="res://ImportMarginContainer.cs" id="5_b5ygb"]
[ext_resource type="Script" path="res://ImportButton.cs" id="6_mxvlq"]
[ext_resource type="Script" path="res://ExportButton.cs" id="7_lurd3"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jcc71"]
@@ -155,6 +159,66 @@ layout_mode = 2
button_group = SubResource("ButtonGroup_4itga")
text = "Crop"
[node name="ClearMarginContainer" type="HBoxContainer" parent="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer"]
layout_mode = 2
[node name="CheckBox" type="CheckBox" parent="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer"]
layout_mode = 2
[node name="ClearButton" type="Button" parent="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer"]
layout_mode = 2
disabled = true
text = "Clear Everything"
script = ExtResource("5_71uyg")
[node name="ImportMarginContainer" type="MarginContainer" parent="SettingsDivider/SettingsPopupContainer"]
visible = false
layout_mode = 2
script = ExtResource("5_b5ygb")
[node name="ImportBoxContainer" type="VBoxContainer" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer"]
layout_mode = 2
alignment = 1
[node name="ImportButton" type="Button" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer"]
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
text = "Import"
script = ExtResource("6_mxvlq")
[node name="ImportDialog" type="FileDialog" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ImportButton"]
unique_name_in_owner = true
title = "Open a File"
ok_button_text = "Open"
file_mode = 0
access = 2
filters = PackedStringArray("*.tier; Tier Files")
use_native_dialog = true
[node name="ExportButton" type="Button" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer"]
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
text = "Export"
script = ExtResource("7_lurd3")
[node name="ExportDialog" type="FileDialog" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ExportButton"]
unique_name_in_owner = true
size = Vector2i(312, 154)
access = 2
filters = PackedStringArray("*.tier; Tier Files")
use_native_dialog = true
[node name="ExportCompressPicturesButton" type="CheckBox" parent="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
text = "Scale Images"
[node name="ButtonContainer" type="HBoxContainer" parent="SettingsDivider"]
layout_mode = 2
alignment = 2
@@ -176,5 +240,11 @@ text = "OK"
[connection signal="BeforeOk" from="." to="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ConfigStretchContainer" method="OkClicked"]
[connection signal="pressed" from="SettingsDivider/SettingsPopupContainer/ChatMarginContainer/ChatContainer/ConnectButtonMarginContainer/HBoxContainer/JoinChannelButton" to="." method="_on_join_channel_button_pressed"]
[connection signal="pressed" from="SettingsDivider/SettingsPopupContainer/ChatMarginContainer/ChatContainer/ConnectButtonMarginContainer/HBoxContainer/ConnectButton" to="." method="_on_connect_button_pressed"]
[connection signal="toggled" from="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer/CheckBox" to="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer/ClearButton" method="EnableToggled"]
[connection signal="pressed" from="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer/ClearButton" to="SettingsDivider/SettingsPopupContainer/ConfigMarginContainer/ConfigContainer/ClearMarginContainer/ClearButton" method="ClearPressed"]
[connection signal="pressed" from="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ImportButton" to="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ImportButton" method="ImportPressed"]
[connection signal="file_selected" from="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ImportButton/ImportDialog" to="." method="ImportFileSelected"]
[connection signal="pressed" from="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ExportButton" to="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ExportButton" method="ExportPressed"]
[connection signal="file_selected" from="SettingsDivider/SettingsPopupContainer/ImportMarginContainer/ImportBoxContainer/ExportButton/ExportDialog" to="." method="ExportFileSelected"]
[connection signal="pressed" from="SettingsDivider/ButtonContainer/CancelButton" to="." method="_on_cancel_button_pressed"]
[connection signal="pressed" from="SettingsDivider/ButtonContainer/OkButton" to="." method="_on_ok_button_pressed"]