Allow holding down tab in Launcher

This commit is contained in:
UnknownShadow200 2018-12-06 20:55:09 +11:00
parent 397f0f872a
commit 8066a76858
8 changed files with 438 additions and 131 deletions

View File

@ -23,7 +23,6 @@ namespace Launcher.Gui.Screens {
Mouse.Move += MouseMove;
Mouse.ButtonDown += MouseButtonDown;
Keyboard.KeyDown += KeyDown;
Keyboard.KeyUp += KeyUp;
}
/// <summary> Function that is repeatedly called multiple times every second. </summary>
@ -37,7 +36,6 @@ namespace Launcher.Gui.Screens {
Mouse.Move -= MouseMove;
Mouse.ButtonDown -= MouseButtonDown;
Keyboard.KeyDown -= KeyDown;
Keyboard.KeyUp -= KeyUp;
}
/// <summary> Function called when the pixels from the framebuffer
@ -148,22 +146,14 @@ namespace Launcher.Gui.Screens {
}
}
protected virtual void KeyUp(Key key) {
if (key == Key.Tab)
tabDown = false;
}
protected int IndexOfWidget(Widget w) {
for (int i = 0; i < widgets.Length; i++) {
if (widgets[i] == w) return i;
}
return -1;
}
protected bool tabDown = false;
protected void HandleTab() {
if (tabDown) return;
tabDown = true;
bool shiftDown = game.IsKeyDown(Key.ShiftLeft)
|| game.IsKeyDown(Key.ShiftRight);

View File

@ -4,6 +4,9 @@
#include "Gui.h"
#include "Game.h"
/*########################################################################################################################*
*---------------------------------------------------------Screen base-----------------------------------------------------*
*#########################################################################################################################*/
static void LScreen_NullFunc(struct LScreen* s) { }
static void LScreen_DrawAll(struct LScreen* s) {
struct LWidget* widget;
@ -38,15 +41,19 @@ CC_NOINLINE static void LScreen_Reset(struct LScreen* s) {
s->HoverWidget = LScreen_HoverWidget;
s->UnhoverWidget = LScreen_UnhoverWidget;
/* reset all widgets to unselected */
/* reset all widgets mouse state */
for (i = 0; i < s->NumWidgets; i++) {
s->Widgets[i]->Hovered = false;
s->Widgets[i]->Hovered = false;
s->Widgets[i]->Selected = false;
}
s->OnEnterWidget = NULL;
s->HoveredWidget = NULL;
}
/*########################################################################################################################*
*---------------------------------------------------------Widget init-----------------------------------------------------*
*--------------------------------------------------------Widget helpers---------------------------------------------------*
*#########################################################################################################################*/
CC_NOINLINE static void LScreen_Button(struct LScreen* s, struct LButton* w, int width, int height, const char* text,
uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
@ -54,7 +61,6 @@ CC_NOINLINE static void LScreen_Button(struct LScreen* s, struct LButton* w, int
LButton_Init(w, width, height);
LButton_SetText(w, &str, &Launcher_TitleFont);
w->Hovered = false;
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
}
@ -65,7 +71,15 @@ CC_NOINLINE static void LScreen_Label(struct LScreen* s, struct LLabel* w, const
LLabel_Init(w);
LLabel_SetText(w, &str, &Launcher_TextFont);
w->Hovered = false;
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
}
CC_NOINLINE static void LScreen_Input(struct LScreen* s, struct LInput* w, int width, bool password, const char* hintText,
uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
LInput_Init(w, width, 30, hintText, &Launcher_HintFont);
w->Password = password;
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
}
@ -77,15 +91,39 @@ CC_NOINLINE static void LScreen_Slider(struct LScreen* s, struct LSlider* w, int
w->Value = initValue; w->MaxValue = maxValue;
w->ProgressCol = progressCol;
w->Hovered = false;
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
}
CC_NOINLINE static int LScreen_IndexOf(struct LScreen* s, void* w) {
int i;
for (i = 0; i < s->NumWidgets; i++) {
if (s->Widgets[i] == w) return i;
}
return -1;
}
static void SwitchToChooseMode(void* w, int x, int y) {
Launcher_SetScreen(ChooseModeScreen_MakeInstance(false));
}
static void SwitchToColours(void* w, int x, int y) {
Launcher_SetScreen(ColoursScreen_MakeInstance());
}
static void SwitchToMain(void* w, int x, int y) {
Launcher_SetScreen(MainScreen_MakeInstance());
}
static void SwitchToSettings(void* w, int x, int y) {
Launcher_SetScreen(SettingsScreen_MakeInstance());
}
static void SwitchToUpdates(void* w, int x, int y) {
Launcher_SetScreen(UpdatesScreen_MakeInstance());
}
/*########################################################################################################################*
*-------------------------------------------------------ChooseModeScreen--------------------------------------------------*
*#########################################################################################################################*/
/*static struct ChooseModeScreen {
static struct ChooseModeScreen {
LScreen_Layout
struct LWidget* Widgets[12];
struct LButton BtnEnhanced, BtnClassicHax, BtnClassic, BtnBack;
@ -93,7 +131,7 @@ CC_NOINLINE static void LScreen_Slider(struct LScreen* s, struct LSlider* w, int
bool FirstTime;
} ChooseModeScreen_Instance;
static void ChooseMode_Click(bool classic, bool classicHacks) {
CC_NOINLINE static void ChooseMode_Click(bool classic, bool classicHacks) {
Launcher_ClassicBackground = classic;
Options_Load();
Options_SetBool(OPT_CLASSIC_MODE, classic);
@ -110,18 +148,9 @@ static void ChooseMode_Click(bool classic, bool classicHacks) {
Launcher_SetScreen(MainScreen_MakeInstance());
}
static void UseModeEnhanced(void* w, int x, int y) {
Launcher_SetScreen(ChooseModeScreen_MakeInstance(false));
}
static void UseModeClassicHax(void* w, int x, int y) {
Launcher_SetScreen(UpdatesScreen_MakeInstance());
}
static void UseModeClassic(void* w, int x, int y) {
Launcher_SetScreen(ColoursScreen_MakeInstance());
}
static void SwitchToSettings(void* w, int x, int y) {
Launcher_SetScreen(SettingsScreen_MakeInstance());
}
static void UseModeEnhanced(void* w, int x, int y) { ChooseMode_Click(false, false); }
static void UseModeClassicHax(void* w, int x, int y) { ChooseMode_Click(true, true); }
static void UseModeClassic(void* w, int x, int y) { ChooseMode_Click(true, false); }
static void ChooseModeScreenScreen_InitWidgets(struct ChooseModeScreen* s) {
struct LScreen* s_ = (struct LScreen*)s;
@ -168,7 +197,7 @@ static void ChooseModeScreen_Init(struct LScreen* s_) {
s->LblHelp.Hidden = !s->FirstTime;
s->BtnBack.Hidden = s->FirstTime;
s->DrawAll(s);
s->DrawAll(s_);
}
struct LScreen* ChooseModeScreen_MakeInstance(bool firstTime) {
@ -177,32 +206,145 @@ struct LScreen* ChooseModeScreen_MakeInstance(bool firstTime) {
s->Init = ChooseModeScreen_Init;
s->FirstTime = firstTime;
return (struct LScreen*)s;
}*/
}
/*########################################################################################################################*
*------------------------------------------------------DirectConnectScreen------------------------------------------------*
*#########################################################################################################################*/
static struct DirectConnectScreen {
LScreen_Layout
struct LWidget* Widgets[6];
struct LButton BtnConnect, BtnBack;
struct LInput IptUsername, IptAddress, IptMppass;
struct LLabel LblStatus;
bool FirstTime;
} DirectConnectScreen_Instance;
CC_NOINLINE static void DirectConnectScreen_SetStatus(const char* msg) {
String str = String_FromReadonly(msg);
struct LLabel* w = &DirectConnectScreen_Instance.LblStatus;
Launcher_ResetArea(w->X, w->Y, w->Width, w->Height);
LLabel_SetText(w, &str, &Launcher_TextFont);
w->VTABLE->Redraw(w);
}
static void DirectConnectScreen_Load(struct DirectConnectScreen* s) {
String addr; char addrBuffer[STRING_SIZE];
String mppass; char mppassBuffer[STRING_SIZE];
String user, ip, port;
Options_Load();
Options_UNSAFE_Get("launcher-dc-username", &user);
Options_UNSAFE_Get("launcher-dc-ip", &ip);
Options_UNSAFE_Get("launcher-dc-port", &port);
String_InitArray(mppass, mppassBuffer);
Launcher_LoadSecureOpt("launcher-dc-mppass", &mppass, &user);
String_InitArray(addr, addrBuffer);
String_Format2(&addr, "%s:%s", &ip, &port);
LInput_SetText(&s->IptUsername, &user, &Launcher_TextFont);
LInput_SetText(&s->IptAddress, &addr, &Launcher_TextFont);
LInput_SetText(&s->IptMppass, &mppass, &Launcher_TextFont);
}
static void DirectConnectScreen_Save(const String* user, const String* mppass, const String* ip, const String* port) {
Options_Load();
Options_Set("launcher-dc-username", user);
Options_Set("launcher-dc-ip", ip);
Options_Set("launcher-dc-port", port);
Launcher_SaveSecureOpt("launcher-dc-mppass", mppass, user);
Options_Save();
}
static void StartClient(void* w, int x, int y) {
static String loopbackIp = String_FromConst("127.0.0.1");
static String defMppass = String_FromConst("(none)");
String* user = &DirectConnectScreen_Instance.IptUsername.Text;
String* addr = &DirectConnectScreen_Instance.IptAddress.Text;
String* mppass = &DirectConnectScreen_Instance.IptMppass.Text;
String ip, port;
uint8_t raw_ip[4];
uint16_t raw_port;
int index = String_LastIndexOf(addr, ':');
if (index <= 0 || index == addr->length - 1) {
DirectConnectScreen_SetStatus("&eInvalid address"); return;
}
ip = String_UNSAFE_Substring(addr, 0, index);
port = String_UNSAFE_SubstringAt(addr, index + 1);
if (String_CaselessEqualsConst(&ip, "localhost")) ip = loopbackIp;
if (!user->length) {
DirectConnectScreen_SetStatus("&eUsername required"); return;
}
if (!Utils_ParseIP(&ip, raw_ip)) {
DirectConnectScreen_SetStatus("&eInvalid ip"); return;
}
if (!Convert_TryParseUInt16(&port, &raw_port)) {
DirectConnectScreen_SetStatus("&eInvalid port"); return;
}
if (!mppass->length) mppass = &defMppass;
DirectConnectScreen_Save(user, mppass, &ip, &port);
DirectConnectScreen_SetStatus("");
Launcher_StartGame(user, mppass, &ip, &port, &String_Empty);
}
static void DirectConnectScreen_InitWidgets(struct DirectConnectScreen* s) {
struct LScreen* s_ = (struct LScreen*)s;
LScreen_Input(s_, &s->IptUsername, 330, false, "&gUsername..",
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -120);
LScreen_Input(s_, &s->IptAddress, 330, false, "&gIP address:Port number..",
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -75);
LScreen_Input(s_, &s->IptMppass, 330, false, "&gMppass..",
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30);
LScreen_Button(s_, &s->BtnConnect, 110, 35, "Connect",
ANCHOR_CENTRE, ANCHOR_CENTRE, -110, 20);
LScreen_Button(s_, &s->BtnBack, 80, 35, "Back",
ANCHOR_CENTRE, ANCHOR_CENTRE, 125, 20);
LScreen_Label(s_, &s->LblStatus, "",
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 70);
s->BtnConnect.OnClick = StartClient;
s->BtnBack.OnClick = SwitchToMain;
/* Init input text from options */
DirectConnectScreen_Load(s);
}
static void DirectConnectScreen_Init(struct LScreen* s_) {
struct DirectConnectScreen* s = (struct DirectConnectScreen*)s_;
if (!s->NumWidgets) DirectConnectScreen_InitWidgets(s);
s->DrawAll(s_);
}
struct LScreen* DirectConnectScreen_MakeInstance(void) {
struct DirectConnectScreen* s = &DirectConnectScreen_Instance;
LScreen_Reset((struct LScreen*)s);
s->Init = DirectConnectScreen_Init;
s->OnEnterWidget = (struct LWidget*)&s->BtnConnect;
return (struct LScreen*)s;
}
/*########################################################################################################################*
*--------------------------------------------------------SettingsScreen---------------------------------------------------*
*#########################################################################################################################*/
/*static struct SettingsScreen {
static struct SettingsScreen {
LScreen_Layout
struct LWidget* Widgets[7];
struct LButton BtnUpdates, BtnMode, BtnColours, BtnBack;
struct LLabel LblUpdates, LblMode, LblColours;
} SettingsScreen_Instance;
static void SwitchToChooseMode(void* w, int x, int y) {
Launcher_SetScreen(ChooseModeScreen_MakeInstance(false));
}
static void SwitchToUpdates(void* w, int x, int y) {
Launcher_SetScreen(UpdatesScreen_MakeInstance());
}
static void SwitchToColours(void* w, int x, int y) {
Launcher_SetScreen(ColoursScreen_MakeInstance());
}
static void SwitchToMain(void* w, int x, int y) {
Launcher_SetScreen(MainScreen_MakeInstance());
}
static void SettingsScreen_InitWidgets(struct SettingsScreen* s) {
struct LScreen* s_ = (struct LScreen*)s;
@ -236,7 +378,7 @@ static void SettingsScreen_Init(struct LScreen* s_) {
s->BtnColours.Hidden = Launcher_ClassicBackground;
s->LblColours.Hidden = Launcher_ClassicBackground;
s->DrawAll(s);
s->DrawAll(s_);
}
struct LScreen* SettingsScreen_MakeInstance(void) {
@ -245,4 +387,3 @@ struct LScreen* SettingsScreen_MakeInstance(void) {
s->Init = SettingsScreen_Init;
return (struct LScreen*)s;
}
*/

View File

@ -19,6 +19,7 @@ typedef void (*LWidget_Func)(struct LScreen* s, struct LWidget* w);
LScreen_Func OnDisplay; /* Called when framebuffer is about to be displayed. */ \
LWidget_Func HoverWidget; /* Called when mouse is moved over a given widget. */ \
LWidget_Func UnhoverWidget; /* Called when the mouse is moved away from a previously hovered widget. */ \
struct LWidget* OnEnterWidget; /* Default widget to auto-click when Enter is pressed. Can be NULL. */ \
struct LWidget* HoveredWidget; /* Widget the mouse is currently hovering over. */ \
int NumWidgets; /* Number of widgets actually used. */

View File

@ -4,6 +4,10 @@
#include "Drawer2D.h"
#include "Launcher.h"
#include "ExtMath.h"
#include "Window.h"
#include "Funcs.h"
#define BORDER 1
void LWidget_SetLocation(void* widget, uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
struct Widget* w = widget;
@ -21,6 +25,7 @@ void LWidget_CalcPosition(void* widget) {
void LWidget_Reset(void* widget) {
struct LWidget* w = widget;
w->Hovered = false;
w->Selected = false;
w->Hidden = false;
w->X = 0; w->Y = 0;
w->Width = 0; w->Height = 0;
@ -37,7 +42,6 @@ void LWidget_Reset(void* widget) {
/*########################################################################################################################*
*------------------------------------------------------ButtonWidget-------------------------------------------------------*
*#########################################################################################################################*/
#define BTN_BORDER 1
static BitmapCol LButton_Expand(BitmapCol a, int amount) {
int r, g, b;
r = a.R + amount; Math_Clamp(r, 0, 255); a.R = r;
@ -54,13 +58,13 @@ static void LButton_DrawBackground(struct LButton* w) {
if (Launcher_ClassicBackground) {
col = w->Hovered ? activeCol : inactiveCol;
Gradient_Noise(&Launcher_Framebuffer, col, 8,
w->X + BTN_BORDER, w->Y + BTN_BORDER,
w->Width - 2 * BTN_BORDER, w->Height - 2 * BTN_BORDER);
w->X + BORDER, w->Y + BORDER,
w->Width - 2 * BORDER, w->Height - 2 * BORDER);
} else {
col = w->Hovered ? Launcher_ButtonForeActiveCol : Launcher_ButtonForeCol;
Gradient_Vertical(&Launcher_Framebuffer, LButton_Expand(col, 8), LButton_Expand(col, -8),
w->X + BTN_BORDER, w->Y + BTN_BORDER,
w->Width - 2 * BTN_BORDER, w->Height - 2 * BTN_BORDER);
w->X + BORDER, w->Y + BORDER,
w->Width - 2 * BORDER, w->Height - 2 * BORDER);
}
}
@ -69,17 +73,17 @@ static void LButton_DrawBorder(struct LButton* w) {
BitmapCol backCol = Launcher_ClassicBackground ? black : Launcher_ButtonBorderCol;
Drawer2D_Clear(&Launcher_Framebuffer, backCol,
w->X + BTN_BORDER, w->Y,
w->Width - 2 * BTN_BORDER, BTN_BORDER);
w->X + BORDER, w->Y,
w->Width - 2 * BORDER, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, backCol,
w->X + BTN_BORDER, w->Y + w->Height - BTN_BORDER,
w->Width - 2 * BTN_BORDER, BTN_BORDER);
w->X + BORDER, w->Y + w->Height - BORDER,
w->Width - 2 * BORDER, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, backCol,
w->X, w->Y + BTN_BORDER,
BTN_BORDER, w->Height - 2 * BTN_BORDER);
w->X, w->Y + BORDER,
BORDER, w->Height - 2 * BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, backCol,
w->X + w->Width - BTN_BORDER, w->Y + BTN_BORDER,
BTN_BORDER, w->Height - 2 * BTN_BORDER);
w->X + w->Width - BORDER, w->Y + BORDER,
BORDER, w->Height - 2 * BORDER);
}
static void LButton_DrawHighlight(struct LButton* w) {
@ -90,15 +94,15 @@ static void LButton_DrawHighlight(struct LButton* w) {
if (Launcher_ClassicBackground) {
highlightCol = w->Hovered ? activeCol : inactiveCol;
Drawer2D_Clear(&Launcher_Framebuffer, highlightCol,
w->X + BTN_BORDER * 2, w->Y + BTN_BORDER,
w->Width - BTN_BORDER * 4, BTN_BORDER);
w->X + BORDER * 2, w->Y + BORDER,
w->Width - BORDER * 4, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, highlightCol,
w->X + BTN_BORDER, w->Y + BTN_BORDER * 2,
BTN_BORDER, w->Height - BTN_BORDER * 4);
w->X + BORDER, w->Y + BORDER * 2,
BORDER, w->Height - BORDER * 4);
} else if (!w->Hovered) {
Drawer2D_Clear(&Launcher_Framebuffer, Launcher_ButtonHighlightCol,
w->X + BTN_BORDER * 2, w->Y + BTN_BORDER,
w->Width - BTN_BORDER * 4, BTN_BORDER);
w->X + BORDER * 2, w->Y + BORDER,
w->Width - BORDER * 4, BORDER);
}
}
@ -108,8 +112,8 @@ static void LButton_Redraw(void* widget) {
int xOffset, yOffset;
if (w->Hidden) return;
xOffset = w->Width - w->__TextSize.Width;
yOffset = w->Height - w->__TextSize.Height;
xOffset = w->Width - w->_TextSize.Width;
yOffset = w->Height - w->_TextSize.Height;
DrawTextArgs_Make(&args, &w->Text, &w->Font, true);
LButton_DrawBackground(w);
@ -132,7 +136,7 @@ void LButton_Init(struct LButton* w, int width, int height) {
w->VTABLE = &lbutton_VTABLE;
w->TabSelectable = true;
w->Width = width; w->Height = height;
String_InitArray(w->Text, w->__TextBuffer);
String_InitArray(w->Text, w->_TextBuffer);
}
void LButton_SetText(struct LButton* w, const String* text, const FontDesc* font) {
@ -141,7 +145,7 @@ void LButton_SetText(struct LButton* w, const String* text, const FontDesc* font
String_Copy(&w->Text, text);
DrawTextArgs_Make(&args, text, font, true);
w->__TextSize = Drawer2D_MeasureText(&args);
w->_TextSize = Drawer2D_MeasureText(&args);
}
@ -157,9 +161,172 @@ CC_NOINLINE static void LInput_GetText(struct LInput* w, String* text) {
}
}
CC_NOINLINE void LInput_Init(struct LInput* w, int width, int height, const char* hintText, const FontDesc* hintFont);
CC_NOINLINE void LInput_SetText(struct LInput* w, const String* text, const FontDesc* font);
CC_NOINLINE Rect2D LInput_MeasureCaret(struct LInput* w);
static void LInput_DrawOuterBorder(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(97, 81, 110, 255);
int width = w->_RealWidth;
if (w->Selected) {
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X, w->Y,
width, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X, w->Y + w->Height - BORDER,
width, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X, w->Y,
BORDER, w->Height);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + width - BORDER, w->Y,
BORDER, w->Height);
} else {
Launcher_ResetArea(w->X, w->Y,
width, BORDER);
Launcher_ResetArea(w->X, w->Y + w->Height - BORDER,
width, BORDER);
Launcher_ResetArea(w->X, w->Y,
BORDER, w->Height);
Launcher_ResetArea(w->X + width - BORDER, w->Y,
BORDER, w->Height);
}
}
static void LInput_DrawInnerBorder(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(165, 142, 168, 255);
int width = w->_RealWidth;
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + BORDER, w->Y + BORDER,
width - BORDER * 2, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + BORDER, w->Y + w->Height - BORDER * 2,
width - BORDER * 2, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + BORDER, w->Y + BORDER,
BORDER, w->Height - BORDER * 2);
Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + width - BORDER * 2, w->Y + BORDER,
BORDER, w->Height - BORDER * 2);
}
static void LInput_BlendBoxTop(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(0, 0, 0, 255);
int width = w->_RealWidth;
Gradient_Blend(&Launcher_Framebuffer, col, 75,
w->X + BORDER, w->Y + BORDER * 1,
width - BORDER * 2, BORDER);
Gradient_Blend(&Launcher_Framebuffer, col, 50,
w->X + BORDER, w->Y + BORDER * 2,
width - BORDER * 2, BORDER);
Gradient_Blend(&Launcher_Framebuffer, col, 25,
w->X + BORDER, w->Y + BORDER * 3,
width - BORDER * 2, BORDER);
}
static void LInput_DrawText(struct LInput* w, struct DrawTextArgs* args) {
int hintHeight, y;
if (w->Text.length || !w->HintText) {
y = w->Y + (w->Height - w->_TextHeight) / 2;
Drawer2D_DrawText(&Launcher_Framebuffer, args, w->X + 5, y + 2);
} else {
args->Text = String_FromReadonly(w->HintText);
args->Font = w->HintFont;
hintHeight = Drawer2D_MeasureText(args).Height;
y = w->Y + (w->Height - hintHeight) / 2;
Drawer2D_DrawText(&Launcher_Framebuffer, args, w->X + 5, y);
}
}
static void LInput_Redraw(void* widget) {
String text; char textBuffer[STRING_SIZE];
struct DrawTextArgs args;
Size2D size;
BitmapCol white = BITMAPCOL_CONST(255, 255, 255, 255);
struct LInput* w = widget;
if (w->Hidden) return;
String_InitArray(text, textBuffer);
LInput_GetText(w, &text);
DrawTextArgs_Make(&args, &text, &w->Font, false);
size = Drawer2D_MeasureText(&args);
w->_RealWidth = max(w->BaseWidth, size.Width + 20);
w->_TextHeight = size.Height;
LInput_DrawOuterBorder(w);
LInput_DrawInnerBorder(w);
Drawer2D_Clear(&Launcher_Framebuffer, white,
w->X + 2, w->Y + 2, w->_RealWidth - 4, w->Height - 4);
LInput_BlendBoxTop(w);
Drawer2D_Cols['f'] = Drawer2D_Cols['0'];
LInput_DrawText(w, &args);
Drawer2D_Cols['f'] = Drawer2D_Cols['F'];
Launcher_Dirty = true;
}
static struct LWidgetVTABLE linput_VTABLE = {
LInput_Redraw, NULL, NULL,
/* TODO: Don't redraw whole thing, just the outer border */
LInput_Redraw, LInput_Redraw
};
void LInput_Init(struct LInput* w, int width, int height, const char* hintText, const FontDesc* hintFont) {
Widget_Reset(w);
w->VTABLE = &linput_VTABLE;
String_InitArray(w->Text, w->_TextBuffer);
w->BaseWidth = width;
w->Width = width; w->Height = height;
LWidget_CalcPosition(w);
w->HintFont = *hintFont;
w->HintText = hintText;
}
void LInput_SetText(struct LInput* w, const String* text_, const FontDesc* font) {
String text; char textBuffer[STRING_SIZE];
struct DrawTextArgs args;
Size2D size;
String_Copy(&w->Text, text_);
w->Font = *font;
String_InitArray(text, textBuffer);
LInput_GetText(w, &text);
DrawTextArgs_Make(&args, &text, &w->Font, true);
size = Drawer2D_MeasureText(&args);
w->_RealWidth = max(w->BaseWidth, size.Width + 15);
w->_TextHeight = size.Height;
}
Rect2D LInput_MeasureCaret(struct LInput* w) {
String text; char textBuffer[STRING_SIZE];
struct DrawTextArgs args;
Rect2D r;
String_InitArray(text, textBuffer);
LInput_GetText(w, &text);
DrawTextArgs_Make(&args, &text, &w->Font, true);
r.X = w->X + 5;
r.Y = w->Y + w->Height - 5; r.Height = 2;
if (w->CaretPos == -1) {
r.X += Drawer2D_MeasureText(&args).Width;
r.Width = 10;
} else {
args.Text = String_UNSAFE_Substring(&text, 0, w->CaretPos);
r.X += Drawer2D_MeasureText(&args).Width;
args.Text = String_UNSAFE_Substring(&text, w->CaretPos, 1);
r.Width = Drawer2D_MeasureText(&args).Width;
}
return r;
}
void LInput_AdvanceCaretPos(struct LInput* w, bool forwards) {
if (forwards && w->CaretPos == -1) return;
@ -249,8 +416,22 @@ bool LInput_Clear(struct LInput* w) {
return true;
}
/* Sets the currently entered text to the contents of the system clipboard. */
CC_NOINLINE bool LInput_CopyFromClipboard(struct LInput* w, const String* text);
bool LInput_CopyFromClipboard(struct LInput* w) {
String text; char textBuffer[256];
String_InitArray(text, textBuffer);
Window_GetClipboardText(&text);
String_UNSAFE_TrimStart(&text);
String_UNSAFE_TrimEnd(&text);
if (w->Text.length >= w->Text.capacity) return false;
if (!text.length) return false;
if (w->ClipboardFilter) w->ClipboardFilter(&text);
String_AppendString(&w->Text, &text);
if (w->TextChanged) w->TextChanged(w);
return true;
}
/*########################################################################################################################*
@ -272,7 +453,7 @@ static struct LWidgetVTABLE llabel_VTABLE = {
void LLabel_Init(struct LLabel* w) {
Widget_Reset(w);
w->VTABLE = &llabel_VTABLE;
String_InitArray(w->Text, w->__TextBuffer);
String_InitArray(w->Text, w->_TextBuffer);
}
void LLabel_SetText(struct LLabel* w, const String* text, const FontDesc* font) {
@ -291,25 +472,24 @@ void LLabel_SetText(struct LLabel* w, const String* text, const FontDesc* font)
/*########################################################################################################################*
*------------------------------------------------------SliderWidget-------------------------------------------------------*
*#########################################################################################################################*/
#define SDR_BORDER 1
static void LSlider_DrawBoxBounds(struct LSlider* w) {
BitmapCol boundsTop = BITMAPCOL_CONST(119, 100, 132, 255);
BitmapCol boundsBottom = BITMAPCOL_CONST(150, 130, 165, 255);
/* TODO: Check these are actually right */
Drawer2D_Clear(&Launcher_Framebuffer, boundsTop,
w->X - SDR_BORDER, w->Y - SDR_BORDER,
w->Width + 2 * SDR_BORDER, SDR_BORDER);
w->X - BORDER, w->Y - BORDER,
w->Width + 2 * BORDER, BORDER);
Drawer2D_Clear(&Launcher_Framebuffer, boundsBottom,
w->X - SDR_BORDER, w->Y + w->Height,
w->Width + 2 * SDR_BORDER, SDR_BORDER);
w->X - BORDER, w->Y + w->Height,
w->Width + 2 * BORDER, BORDER);
Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom,
w->X - SDR_BORDER, w->Y - SDR_BORDER,
SDR_BORDER, w->Height + SDR_BORDER);
w->X - BORDER, w->Y - BORDER,
BORDER, w->Height + BORDER);
Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom,
w->X + w->Width, w->Y - SDR_BORDER,
SDR_BORDER, w->Height + SDR_BORDER);
w->X + w->Width, w->Y - BORDER,
BORDER, w->Height + BORDER);
}
static void LSlider_DrawBox(struct LSlider* w) {

View File

@ -25,7 +25,8 @@ struct LWidgetVTABLE {
#define LWidget_Layout \
struct LWidgetVTABLE* VTABLE; /* General widget functions */ \
int X, Y, Width, Height; /* Top left corner, and dimensions, of this widget */ \
bool Hovered; /* Whether this widget is currently being moused over*/ \
bool Hovered; /* Whether this widget is currently being moused over */ \
bool Selected; /* Whether this widget is last widget to be clicked on */ \
bool Hidden; /* Whether this widget is hidden from view */ \
bool TabSelectable; /* Whether this widget gets selected when pressing tab */ \
uint8_t HorAnchor, VerAnchor; /* Specifies the reference point for when this widget is resized */ \
@ -42,8 +43,8 @@ struct LButton {
LWidget_Layout
String Text;
FontDesc Font;
Size2D __TextSize;
char __TextBuffer[STRING_SIZE];
Size2D _TextSize;
char _TextBuffer[STRING_SIZE];
};
CC_NOINLINE void LButton_Init(struct LButton* w, int width, int height);
CC_NOINLINE void LButton_SetText(struct LButton* w, const String* text, const FontDesc* font);
@ -51,7 +52,7 @@ CC_NOINLINE void LButton_SetText(struct LButton* w, const String* text, const Fo
struct LInput;
struct LInput {
LWidget_Layout
int BaseWidth, RealWidth;
int BaseWidth, _RealWidth;
/* Text displayed when the user has not entered anything in the text field. */
const char* HintText;
/* Whether all characters should be rendered as *. */
@ -67,8 +68,8 @@ struct LInput {
int CaretPos;
FontDesc Font, HintFont;
String Text;
int __TextHeight;
char __TextBuffer[STRING_SIZE];
int _TextHeight;
char _TextBuffer[STRING_SIZE];
};
CC_NOINLINE void LInput_Init(struct LInput* w, int width, int height, const char* hintText, const FontDesc* hintFont);
CC_NOINLINE void LInput_SetText(struct LInput* w, const String* text, const FontDesc* font);
@ -84,15 +85,15 @@ CC_NOINLINE bool LInput_Backspace(struct LInput* w);
CC_NOINLINE bool LInput_Delete(struct LInput* w);
/* Resets the currently entered text to an empty string. */
CC_NOINLINE bool LInput_Clear(struct LInput* w);
/* Sets the currently entered text to the contents of the system clipboard. */
CC_NOINLINE bool LInput_CopyFromClipboard(struct LInput* w, const String* text);
/* Appends the contents of the system clipboard to the currently entered text. */
CC_NOINLINE bool LInput_CopyFromClipboard(struct LInput* w);
struct LLabel {
LWidget_Layout
FontDesc Font;
String Text;
Size2D __TextSize;
char __TextBuffer[STRING_SIZE];
Size2D _TextSize;
char _TextBuffer[STRING_SIZE];
};
CC_NOINLINE void LLabel_Init(struct LLabel* w);
CC_NOINLINE void LLabel_SetText(struct LLabel* w, const String* text, const FontDesc* font);

View File

@ -10,6 +10,7 @@
#include "Window.h"
#include "GameStructs.h"
#include "Event.h"
#include "AsyncDownloader.h"
struct LScreen* Launcher_Screen;
bool Launcher_Dirty;
@ -17,6 +18,7 @@ Rect2D Launcher_DirtyArea;
Bitmap Launcher_Framebuffer;
bool Launcher_ClassicBackground;
FontDesc Launcher_TitleFont, Launcher_TextFont;
FontDesc Launcher_InputHintFont;
bool Launcher_ShouldExit, Launcher_ShouldUpdate;
TimeMS Launcher_PatchTime;
@ -33,33 +35,31 @@ void Launcher_ShowError(ReturnCode res, const char* place) {
}
/* TODO: FIX THESE STUBS!!! */
void Launcher_SecureSetOpt(const char* opt, const String* data, const String* key) { }
/* TODO: FIX */
/* internal UpdateCheckTask checkTask; */
//void Launcher_SecureSetOpt(const char* opt, const String* data, const String* key) { }
internal UpdateCheckTask checkTask;
static bool fullRedraw, pendingRedraw;
static FontDesc logoFont;
static void Launcher_RedrawAll(void) {
static void Launcher_RedrawAll(void* obj) {
Launcher_ResetPixels();
if (Launcher_Screen) Launcher_Screen->DrawAll(Launcher_Screen);
fullRedraw = true;
}
static void Launcher_ReqeustRedraw(void) {
static void Launcher_ReqeustRedraw(void* obj) {
/* We may get multiple Redraw events in short timespan */
/* So we just request a redraw at next launcher tick */
pendingRedraw = true;
Launcher_Dirty = true;
}
/* updates window state on resize and redraws contents. */
static void Launcher_OnResize(void) {
static void Launcher_OnResize(void* obj) {
Game_UpdateClientSize();
Launcher_Framebuffer.Width = Game_Width;
Launcher_Framebuffer.Height = Game_Height;
Window_InitRaw(&Launcher_Framebuffer);
Launcher_RedrawAll();
Launcher_RedrawAll(NULL);
}
void Launcher_SetScreen(struct LScreen* screen) {
@ -69,24 +69,22 @@ void Launcher_SetScreen(struct LScreen* screen) {
screen->Init(screen);
/* for hovering over active button etc */
/* TODO: FIX */
/* screen->MouseMove(screen, 0, 0); */
screen->MouseMove(screen, 0, 0);
}
/* TODO FIX */
/*
static void Launcher_Init(void) {
BitmapCol col = BITMAPCOL_CONST(125, 125, 125, 255);
Event_RegisterVoid(&WindowEvents_Resized, NULL, Launcher_OnResize);
Event_RegisterVoid(&WindowEvents_StateChanged, NULL, Launcher_OnResize);
Window.FocusedChanged += RedrawAll;
Window.Redraw += RedrawPending;
Event_RegisterVoid(&WindowEvents_FocusChanged, NULL, Launcher_RedrawAll);
Event_RegisterVoid(&WindowEvents_Redraw, NULL, Launcher_ReqeustRedraw);
Keyboard.KeyDown += KeyDown;
Font_Make(&logoFont, &Drawer2D_FontName, 32, FONT_STYLE_NORMAL);
Font_Make(&Launcher_TitleFont, &Drawer2D_FontName, 16, FONT_STYLE_BOLD);
Font_Make(&Launcher_TextFont, &Drawer2D_FontName, 14, FONT_STYLE_NORMAL);
Font_Make(&Launcher_HintFont, &Drawer2D_FontName, 12, FONT_STYLE_ITALIC);
Drawer2D_Cols['g'] = col;
Utils_EnsureDirectory("texpacks");
@ -96,9 +94,8 @@ static void Launcher_Init(void) {
void Dispose() {
Event_UnregisterVoid(&WindowEvents_Resized, NULL, Launcher_OnResize);
Event_UnregisterVoid(&WindowEvents_StateChanged, NULL, Launcher_OnResize);
Window.FocusedChanged -= RedrawAll;
Window.Redraw -= RedrawPending;
Event_UnregisterVoid(&WindowEvents_FocusChanged, NULL, Launcher_RedrawAll);
Event_UnregisterVoid(&WindowEvents_Redraw, NULL, Launcher_ReqeustRedraw);
Keyboard.KeyDown -= KeyDown;
List<FastBitmap> bitmaps = FetchFlagsTask.Bitmaps;
@ -110,6 +107,7 @@ void Dispose() {
Font_Free(&logoFont);
Font_Free(&Launcher_TitleFont);
Font_Free(&Launcher_TextFont);
Font_Free(&Launcher_HintFont);
}
void Run() {
@ -128,8 +126,7 @@ void Run() {
Launcher_Framebuffer.Height = Game_Height;
Window_InitRaw(&Launcher_Framebuffer);
Downloader = new AsyncDownloader(Drawer);
Downloader.Init("");
AsyncDownloader_Component.Init();
Downloader.Cookies = new CookieContainer();
Downloader.KeepAlive = true;
@ -187,7 +184,7 @@ void Display() {
Window_DrawRaw(rec);
DirtyArea = Rectangle.Empty;
fullRedraw = false;
}*/
}
static bool Launcher_IsShutdown(Key key) {
if (key == KEY_F4 && Key_IsAltPressed()) return true;
@ -428,7 +425,7 @@ bool Launcher_StartGame(const String* user, const String* mppass, const String*
Options_Set("launcher-username", user);
Options_Set("launcher-ip", ip);
Options_Set("launcher-port", port);
Launcher_SecureSetOpt("launcher-mppass", mppass, user);
Launcher_SaveSecureOpt("launcher-mppass", mppass, user);
Options_Save();
}

View File

@ -19,6 +19,8 @@ extern Bitmap Launcher_Framebuffer;
extern bool Launcher_ClassicBackground;
/* Default font for buttons and labels. */
extern FontDesc Launcher_TitleFont, Launcher_TextFont;
/* Default font for input widget hints. */
extern FontDesc Launcher_HintFont;
/* Whether at the next tick, the launcher window should proceed to stop displaying frames and subsequently exit. */
extern bool Launcher_ShouldExit;
@ -77,7 +79,10 @@ void Launcher_Run(void);
void Launcher_ShowError(ReturnCode res, const char* place);
/* Attempts to securely encode an option. */
/* NOTE: Not all platforms support secure saving, DO NOT rely on this being secure. */
void Launcher_SecureSetOpt(const char* opt, const String* data, const String* key);
void Launcher_SaveSecureOpt(const char* opt, const String* data, const String* key);
/* Attempts to securely decode an option. */
/* NOTE: Not all platforms support secure saving, DO NOT rely on this being secure. */
void Launcher_LoadSecureOpt(const char* opt, String* data, const String* key);
/* Starts the game from the given arguments. */
bool Launcher_StartGame(const String* user, const String* mppass, const String* ip, const String* port, const String* server);

View File

@ -1093,12 +1093,6 @@ static void ChatScreen_ContextRecreated(void* screen) {
struct ChatScreen* s = screen;
ChatScreen_ConstructWidgets(s);
ChatScreen_SetInitialMessages(s);
}
static void ChatScreen_FontChanged(void* screen) {
struct ChatScreen* s = screen;
if (!Drawer2D_BitmappedText) return;
Elem_Recreate(s);
ChatScreen_UpdateChatYOffset(s, true);
}
@ -1123,9 +1117,8 @@ static void ChatScreen_Init(void* screen) {
Drawer2D_MakeFont(&s->AnnouncementFont, largeSize, FONT_STYLE_NORMAL);
Screen_CommonInit(s);
Event_RegisterChat(&ChatEvents_ChatReceived, s, ChatScreen_ChatReceived);
Event_RegisterVoid(&ChatEvents_FontChanged, s, ChatScreen_FontChanged);
Event_RegisterInt(&ChatEvents_ColCodeChanged, s, ChatScreen_ColCodeChanged);
Event_RegisterChat(&ChatEvents_ChatReceived, s, ChatScreen_ChatReceived);
Event_RegisterInt(&ChatEvents_ColCodeChanged, s, ChatScreen_ColCodeChanged);
}
static void ChatScreen_Render(void* screen, double delta) {
@ -1183,9 +1176,8 @@ static void ChatScreen_Free(void* screen) {
Font_Free(&s->AnnouncementFont);
Screen_CommonFree(s);
Event_UnregisterChat(&ChatEvents_ChatReceived, s, ChatScreen_ChatReceived);
Event_UnregisterVoid(&ChatEvents_FontChanged, s, ChatScreen_FontChanged);
Event_UnregisterInt(&ChatEvents_ColCodeChanged, s, ChatScreen_ColCodeChanged);
Event_UnregisterChat(&ChatEvents_ChatReceived, s, ChatScreen_ChatReceived);
Event_UnregisterInt(&ChatEvents_ColCodeChanged, s, ChatScreen_ColCodeChanged);
}
static struct ScreenVTABLE ChatScreen_VTABLE = {