yvt 8e7cf01492 Refactor AngelScript code
Split huge source files
2017-12-30 22:06:38 +09:00

520 lines
21 KiB
ActionScript

/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreateProfileScreen.as"
#include "ServerList.as"
namespace spades {
class RefreshButton: spades::ui::SimpleButton {
RefreshButton(spades::ui::UIManager@ manager){
super(manager);
}
void Render() {
SimpleButton::Render();
Renderer@ renderer = Manager.Renderer;
Vector2 pos = ScreenPosition;
Vector2 size = Size;
Image@ img = renderer.RegisterImage("Gfx/UI/Refresh.png");
renderer.DrawImage(img, pos + (size - Vector2(16.f, 16.f)) * 0.5f);
}
}
class ProtocolButton: spades::ui::SimpleButton {
ProtocolButton(spades::ui::UIManager@ manager){
super(manager);
Toggle = true;
}
}
uint8 ToLower(uint8 c) {
if(c >= uint8(0x41) and c <= uint8(0x5a)) {
return uint8(c - 0x41 + 0x61);
} else {
return c;
}
}
bool StringContainsCaseInsensitive(string text, string pattern) {
for(int i = text.length - 1; i >= 0; i--)
text[i] = ToLower(text[i]);
for(int i = pattern.length - 1; i >= 0; i--)
pattern[i] = ToLower(pattern[i]);
return text.findFirst(pattern) >= 0;
}
class MainScreenMainMenu: spades::ui::UIElement {
MainScreenUI@ ui;
MainScreenHelper@ helper;
spades::ui::Field@ addressField;
spades::ui::Button@ protocol3Button;
spades::ui::Button@ protocol4Button;
spades::ui::Button@ filterProtocol3Button;
spades::ui::Button@ filterProtocol4Button;
spades::ui::Button@ filterEmptyButton;
spades::ui::Button@ filterFullButton;
spades::ui::Field@ filterField;
spades::ui::ListView@ serverList;
MainScreenServerListLoadingView@ loadingView;
MainScreenServerListErrorView@ errorView;
bool loading = false, loaded = false;
private ConfigItem cg_protocolVersion("cg_protocolVersion", "3");
private ConfigItem cg_lastQuickConnectHost("cg_lastQuickConnectHost", "127.0.0.1");
private ConfigItem cg_serverlistSort("cg_serverlistSort", "16385");
MainScreenMainMenu(MainScreenUI@ ui) {
super(ui.manager);
@this.ui = ui;
@this.helper = ui.helper;
float contentsWidth = 750.f;
float contentsLeft = (Manager.Renderer.ScreenWidth - contentsWidth) * 0.5f;
float footerPos = Manager.Renderer.ScreenHeight - 50.f;
{
spades::ui::Button button(Manager);
button.Caption = _Tr("MainScreen", "Connect");
button.Bounds = AABB2(contentsLeft + contentsWidth - 150.f, 200.f, 150.f, 30.f);
@button.Activated = spades::ui::EventHandler(this.OnConnectPressed);
AddChild(button);
}
{
@addressField = spades::ui::Field(Manager);
addressField.Bounds = AABB2(contentsLeft, 200, contentsWidth - 240.f, 30.f);
addressField.Placeholder = _Tr("MainScreen", "Quick Connect");
addressField.Text = cg_lastQuickConnectHost.StringValue;
@addressField.Changed = spades::ui::EventHandler(this.OnAddressChanged);
AddChild(addressField);
}
{
@protocol3Button = ProtocolButton(Manager);
protocol3Button.Bounds = AABB2(contentsLeft + contentsWidth - 240.f + 6.f, 200,
40.f, 30.f);
protocol3Button.Caption = _Tr("MainScreen", "0.75");
@protocol3Button.Activated = spades::ui::EventHandler(this.OnProtocol3Pressed);
protocol3Button.Toggle = true;
protocol3Button.Toggled = cg_protocolVersion.IntValue == 3;
AddChild(protocol3Button);
}
{
@protocol4Button = ProtocolButton(Manager);
protocol4Button.Bounds = AABB2(contentsLeft + contentsWidth - 200.f + 6.f, 200,
40.f, 30.f);
protocol4Button.Caption = _Tr("MainScreen", "0.76");
@protocol4Button.Activated = spades::ui::EventHandler(this.OnProtocol4Pressed);
protocol4Button.Toggle = true;
protocol4Button.Toggled = cg_protocolVersion.IntValue == 4;
AddChild(protocol4Button);
}
{
spades::ui::Button button(Manager);
button.Caption = _Tr("MainScreen", "Quit");
button.Bounds = AABB2(contentsLeft + contentsWidth - 100.f, footerPos, 100.f, 30.f);
@button.Activated = spades::ui::EventHandler(this.OnQuitPressed);
AddChild(button);
}
{
spades::ui::Button button(Manager);
button.Caption = _Tr("MainScreen", "Credits");
button.Bounds = AABB2(contentsLeft + contentsWidth - 202.f, footerPos, 100.f, 30.f);
@button.Activated = spades::ui::EventHandler(this.OnCreditsPressed);
AddChild(button);
}
{
spades::ui::Button button(Manager);
button.Caption = _Tr("MainScreen", "Setup");
button.Bounds = AABB2(contentsLeft + contentsWidth - 304.f, footerPos, 100.f, 30.f);
@button.Activated = spades::ui::EventHandler(this.OnSetupPressed);
AddChild(button);
}
{
RefreshButton button(Manager);
button.Bounds = AABB2(contentsLeft + contentsWidth - 364.f, footerPos, 30.f, 30.f);
@button.Activated = spades::ui::EventHandler(this.OnRefreshServerListPressed);
AddChild(button);
}
{
spades::ui::Label label(Manager);
label.Text = _Tr("MainScreen", "Filter");
label.Bounds = AABB2(contentsLeft, footerPos, 50.f, 30.f);
label.Alignment = Vector2(0.f, 0.5f);
AddChild(label);
}
{
@filterProtocol3Button = ProtocolButton(Manager);
filterProtocol3Button.Bounds = AABB2(contentsLeft + 50.f, footerPos,
40.f, 30.f);
filterProtocol3Button.Caption = _Tr("MainScreen", "0.75");
@filterProtocol3Button.Activated = spades::ui::EventHandler(this.OnFilterProtocol3Pressed);
filterProtocol3Button.Toggle = true;
AddChild(filterProtocol3Button);
}
{
@filterProtocol4Button = ProtocolButton(Manager);
filterProtocol4Button.Bounds = AABB2(contentsLeft + 90.f, footerPos,
40.f, 30.f);
filterProtocol4Button.Caption = _Tr("MainScreen", "0.76");
@filterProtocol4Button.Activated = spades::ui::EventHandler(this.OnFilterProtocol4Pressed);
filterProtocol4Button.Toggle = true;
AddChild(filterProtocol4Button);
}
{
@filterEmptyButton = ProtocolButton(Manager);
filterEmptyButton.Bounds = AABB2(contentsLeft + 135.f, footerPos,
50.f, 30.f);
filterEmptyButton.Caption = _Tr("MainScreen", "Empty");
@filterEmptyButton.Activated = spades::ui::EventHandler(this.OnFilterEmptyPressed);
filterEmptyButton.Toggle = true;
AddChild(filterEmptyButton);
}
{
@filterFullButton = ProtocolButton(Manager);
filterFullButton.Bounds = AABB2(contentsLeft + 185.f, footerPos,
70.f, 30.f);
filterFullButton.Caption = _Tr("MainScreen", "Not Full");
@filterFullButton.Activated = spades::ui::EventHandler(this.OnFilterFullPressed);
filterFullButton.Toggle = true;
AddChild(filterFullButton);
}
{
@filterField = spades::ui::Field(Manager);
filterField.Bounds = AABB2(contentsLeft + 260.f, footerPos, 120.f, 30.f);
filterField.Placeholder = _Tr("MainScreen", "Filter");
@filterField.Changed = spades::ui::EventHandler(this.OnFilterTextChanged);
AddChild(filterField);
}
{
@serverList = spades::ui::ListView(Manager);
serverList.Bounds = AABB2(contentsLeft, 270.f, contentsWidth, footerPos - 280.f);
AddChild(serverList);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 2.f, 240.f, 300.f - 2.f, 30.f);
header.Text = _Tr("MainScreen", "Server Name");
@header.Activated = spades::ui::EventHandler(this.SortServerListByName);
AddChild(header);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 300.f, 240.f, 100.f, 30.f);
header.Text = _Tr("MainScreen", "Players");
@header.Activated = spades::ui::EventHandler(this.SortServerListByNumPlayers);
AddChild(header);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 400.f, 240.f, 150.f, 30.f);
header.Text = _Tr("MainScreen", "Map Name");
@header.Activated = spades::ui::EventHandler(this.SortServerListByMapName);
AddChild(header);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 550.f, 240.f, 80.f, 30.f);
header.Text = _Tr("MainScreen", "Game Mode");
@header.Activated = spades::ui::EventHandler(this.SortServerListByGameMode);
AddChild(header);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 630.f, 240.f, 50.f, 30.f);
header.Text = _Tr("MainScreen", "Ver.");
@header.Activated = spades::ui::EventHandler(this.SortServerListByProtocol);
AddChild(header);
}
{
ServerListHeader header(Manager);
header.Bounds = AABB2(contentsLeft + 680.f, 240.f, 50.f, 30.f);
header.Text = _Tr("MainScreen", "Loc.");
@header.Activated = spades::ui::EventHandler(this.SortServerListByCountry);
AddChild(header);
}
{
@loadingView = MainScreenServerListLoadingView(Manager);
loadingView.Bounds = AABB2(contentsLeft, 240.f, contentsWidth, 100.f);
loadingView.Visible = false;
AddChild(loadingView);
}
{
@errorView = MainScreenServerListErrorView(Manager);
errorView.Bounds = AABB2(contentsLeft, 240.f, contentsWidth, 100.f);
errorView.Visible = false;
AddChild(errorView);
}
LoadServerList();
}
void LoadServerList() {
if(loading) {
return;
}
loaded = false;
loading = true;
@serverList.Model = spades::ui::ListViewModel(); // empty
errorView.Visible = false;
loadingView.Visible = true;
helper.StartQuery();
}
void ServerListItemActivated(ServerListModel@ sender, MainScreenServerItem@ item) {
addressField.Text = item.Address;
cg_lastQuickConnectHost = addressField.Text;
if(item.Protocol == "0.75") {
SetProtocolVersion(3);
}else if(item.Protocol == "0.76") {
SetProtocolVersion(4);
}
addressField.SelectAll();
}
void ServerListItemDoubleClicked(ServerListModel@ sender, MainScreenServerItem@ item) {
ServerListItemActivated(sender, item);
// Double-click to connect
Connect();
}
void ServerListItemRightClicked(ServerListModel@ sender, MainScreenServerItem@ item) {
helper.SetServerFavorite(item.Address, !item.Favorite);
UpdateServerList();
}
private void SortServerListByPing(spades::ui::UIElement@ sender) {
SortServerList(0);
}
private void SortServerListByNumPlayers(spades::ui::UIElement@ sender) {
SortServerList(1);
}
private void SortServerListByName(spades::ui::UIElement@ sender) {
SortServerList(2);
}
private void SortServerListByMapName(spades::ui::UIElement@ sender) {
SortServerList(3);
}
private void SortServerListByGameMode(spades::ui::UIElement@ sender) {
SortServerList(4);
}
private void SortServerListByProtocol(spades::ui::UIElement@ sender) {
SortServerList(5);
}
private void SortServerListByCountry(spades::ui::UIElement@ sender) {
SortServerList(6);
}
private void SortServerList(int keyId) {
int sort = cg_serverlistSort.IntValue;
if(int(sort & 0xfff) == keyId) {
sort ^= int(0x4000);
} else {
sort = keyId;
}
cg_serverlistSort = sort;
UpdateServerList();
}
private void UpdateServerList() {
string key = "";
switch(cg_serverlistSort.IntValue & 0xfff) {
case 0: key = "Ping"; break;
case 1: key = "NumPlayers"; break;
case 2: key = "Name"; break;
case 3: key = "MapName"; break;
case 4: key = "GameMode"; break;
case 5: key = "Protocol"; break;
case 6: key = "Country"; break;
}
MainScreenServerItem@[]@ list = helper.GetServerList(key,
(cg_serverlistSort.IntValue & 0x4000) != 0);
if((list is null) or (loading)){
@serverList.Model = spades::ui::ListViewModel(); // empty
return;
}
// filter the server list
bool filterProtocol3 = filterProtocol3Button.Toggled;
bool filterProtocol4 = filterProtocol4Button.Toggled;
bool filterEmpty = filterEmptyButton.Toggled;
bool filterFull = filterFullButton.Toggled;
string filterText = filterField.Text;
MainScreenServerItem@[]@ list2 = array<spades::MainScreenServerItem@>();
for(int i = 0, count = list.length; i < count; i++) {
MainScreenServerItem@ item = list[i];
if(filterProtocol3 and (item.Protocol != "0.75")) {
continue;
}
if(filterProtocol4 and (item.Protocol != "0.76")) {
continue;
}
if(filterEmpty and (item.NumPlayers > 0)) {
continue;
}
if(filterFull and (item.NumPlayers >= item.MaxPlayers)) {
continue;
}
if(filterText.length > 0) {
if(not (StringContainsCaseInsensitive(item.Name, filterText) or
StringContainsCaseInsensitive(item.MapName, filterText) or
StringContainsCaseInsensitive(item.GameMode, filterText))) {
continue;
}
}
list2.insertLast(item);
}
ServerListModel model(Manager, list2);
@serverList.Model = model;
@model.ItemActivated = ServerListItemEventHandler(this.ServerListItemActivated);
@model.ItemDoubleClicked = ServerListItemEventHandler(this.ServerListItemDoubleClicked);
@model.ItemRightClicked = ServerListItemEventHandler(this.ServerListItemRightClicked);
serverList.ScrollToTop();
}
private void CheckServerList() {
if(helper.PollServerListState()) {
MainScreenServerItem@[]@ list = helper.GetServerList("", false);
if(list is null or list.length == 0) {
// failed.
// FIXME: show error message?
loaded = false; loading = false;
errorView.Visible = true;
loadingView.Visible = false;
@serverList.Model = spades::ui::ListViewModel(); // empty
return;
}
loading = false;
loaded = true;
errorView.Visible = false;
loadingView.Visible = false;
UpdateServerList();
}
}
private void OnAddressChanged(spades::ui::UIElement@ sender) {
cg_lastQuickConnectHost = addressField.Text;
}
private void SetProtocolVersion(int ver) {
protocol3Button.Toggled = (ver == 3);
protocol4Button.Toggled = (ver == 4);
cg_protocolVersion = ver;
}
private void OnProtocol3Pressed(spades::ui::UIElement@ sender) {
SetProtocolVersion(3);
}
private void OnProtocol4Pressed(spades::ui::UIElement@ sender) {
SetProtocolVersion(4);
}
private void OnFilterProtocol3Pressed(spades::ui::UIElement@ sender) {
filterProtocol4Button.Toggled = false;
UpdateServerList();
}
private void OnFilterProtocol4Pressed(spades::ui::UIElement@ sender) {
filterProtocol3Button.Toggled = false;
UpdateServerList();
}
private void OnFilterFullPressed(spades::ui::UIElement@ sender) {
filterEmptyButton.Toggled = false;
UpdateServerList();
}
private void OnFilterEmptyPressed(spades::ui::UIElement@ sender) {
filterFullButton.Toggled = false;
UpdateServerList();
}
private void OnFilterTextChanged(spades::ui::UIElement@ sender) {
UpdateServerList();
}
private void OnRefreshServerListPressed(spades::ui::UIElement@ sender) {
LoadServerList();
}
private void OnQuitPressed(spades::ui::UIElement@ sender) {
ui.shouldExit = true;
}
private void OnCreditsPressed(spades::ui::UIElement@ sender) {
AlertScreen al(this, ui.helper.Credits, Min(500.f, Manager.Renderer.ScreenHeight - 100.f));
al.Run();
}
private void OnSetupPressed(spades::ui::UIElement@ sender) {
PreferenceView al(this, PreferenceViewOptions(), ui.fontManager);
al.Run();
}
private void Connect() {
string msg = helper.ConnectServer(addressField.Text, cg_protocolVersion.IntValue);
if(msg.length > 0) {
// failde to initialize client.
AlertScreen al(this, msg);
al.Run();
}
}
private void OnConnectPressed(spades::ui::UIElement@ sender) {
Connect();
}
void HotKey(string key) {
if(IsEnabled and key == "Enter") {
Connect();
} else if(IsEnabled and key == "Escape") {
ui.shouldExit = true;
} else {
UIElement::HotKey(key);
}
}
void Render() {
CheckServerList();
UIElement::Render();
// check for client error message.
if(IsEnabled) {
string msg = helper.GetPendingErrorMessage();
if(msg.length > 0) {
// try to maek the "disconnected" message more friendly.
if(msg.findFirst("Disconnected:") >= 0) {
int ind1 = msg.findFirst("Disconnected:");
int ind2 = msg.findFirst("\n", ind1);
if(ind2 < 0) ind2 = msg.length;
ind1 += "Disconnected:".length;
msg = msg.substr(ind1, ind2 - ind1);
msg = _Tr("MainScreen", "You were disconnected from the server because of the following reason:\n\n{0}", msg);
}
// failed to connect.
AlertScreen al(this, msg);
al.Run();
}
}
}
}
}