mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
Start porting MenuScreen to C
This commit is contained in:
parent
11af117185
commit
c8af9c0ab5
@ -33,7 +33,7 @@ namespace ClassicalSharp.Gui {
|
||||
|
||||
public virtual bool HandlesKeyUp(Key key) { return false; }
|
||||
|
||||
public virtual bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) { return false; }
|
||||
public virtual bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) { return false; }
|
||||
|
||||
public virtual bool HandlesMouseMove(int mouseX, int mouseY) { return false; }
|
||||
|
||||
|
@ -397,16 +397,16 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (!HandlesAllInput || game.HideGui) return false;
|
||||
|
||||
if (!normalChat.Bounds.Contains(mouseX, mouseY)) {
|
||||
if (altText.Active && altText.Bounds.Contains(mouseX, mouseY)) {
|
||||
altText.HandlesMouseClick(mouseX, mouseY, button);
|
||||
altText.HandlesMouseDown(mouseX, mouseY, button);
|
||||
UpdateAltTextY();
|
||||
return true;
|
||||
}
|
||||
input.HandlesMouseClick(mouseX, mouseY, button);
|
||||
input.HandlesMouseDown(mouseX, mouseY, button);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
public override bool HandlesKeyUp(Key key) { return true; }
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (button != MouseButton.Left) return true;
|
||||
|
||||
if (!reconnect.Disabled && reconnect.Bounds.Contains(mouseX, mouseY)) {
|
||||
|
@ -167,12 +167,12 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
return chat.HandlesMouseScroll(delta);
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (button != MouseButton.Left || !HandlesAllInput) return false;
|
||||
|
||||
string name;
|
||||
if (playerList == null || (name = playerList.GetNameUnder(mouseX, mouseY)) == null)
|
||||
return chat.HandlesMouseClick(mouseX, mouseY, button);
|
||||
return chat.HandlesMouseDown(mouseX, mouseY, button);
|
||||
chat.AppendTextToInput(name + " ");
|
||||
return true;
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
return table.HandlesMouseMove(mouseX, mouseY);
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
if (table.scroll.draggingMouse || game.Gui.hudScreen.hotbar.HandlesMouseClick(mouseX, mouseY, button))
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (table.scroll.draggingMouse || game.Gui.hudScreen.hotbar.HandlesMouseDown(mouseX, mouseY, button))
|
||||
return true;
|
||||
|
||||
bool handled = table.HandlesMouseClick(mouseX, mouseY, button);
|
||||
bool handled = table.HandlesMouseDown(mouseX, mouseY, button);
|
||||
if ((!handled || table.PendingClose) && button == MouseButton.Left) {
|
||||
bool hotbar = game.Input.ControlDown || game.Input.ShiftDown;
|
||||
if (!hotbar) game.Gui.SetNewScreen(null);
|
||||
|
@ -104,7 +104,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
return game.Gui.hudScreen.HandlesKeyUp(key);
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) { return true; }
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) { return true; }
|
||||
|
||||
public override bool HandlesMouseMove(int mouseX, int mouseY) { return true; }
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
game.Graphics.Draw2DQuad(0, 0, game.Width, game.Height, topBackCol, bottomBackCol);
|
||||
}
|
||||
|
||||
protected bool HandleMouseClick(Widget[] widgets, int mouseX, int mouseY, MouseButton button) {
|
||||
protected bool HandleMouseDown(Widget[] widgets, int mouseX, int mouseY, MouseButton button) {
|
||||
// iterate backwards (because last elements rendered are shown over others)
|
||||
for (int i = widgets.Length - 1; i >= 0; i--) {
|
||||
Widget widget = widgets[i];
|
||||
|
@ -97,7 +97,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
void InputClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
||||
if (btn != MouseButton.Left) return;
|
||||
widget.HandlesMouseClick(x, y, btn);
|
||||
widget.HandlesMouseDown(x, y, btn);
|
||||
}
|
||||
|
||||
void LeaveOpenClick(Game game, Widget widget) {
|
||||
|
@ -91,7 +91,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
if (selected != null) selected.ShowCaret = false;
|
||||
|
||||
selected = (MenuInputWidget)widget;
|
||||
selected.HandlesMouseClick(x, y, btn);
|
||||
selected.HandlesMouseDown(x, y, btn);
|
||||
selected.ShowCaret = true;
|
||||
}
|
||||
|
||||
|
@ -116,8 +116,8 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
return HandleMouseMove(buttons, mouseX, mouseY) >= 0;
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
return HandleMouseClick(buttons, mouseX, mouseY, button);
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
return HandleMouseDown(buttons, mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public override void OnResize(int width, int height) {
|
||||
|
@ -205,7 +205,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
void InputClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
||||
if (btn != MouseButton.Left) return;
|
||||
widget.HandlesMouseClick(x, y, btn);
|
||||
widget.HandlesMouseDown(x, y, btn);
|
||||
}
|
||||
|
||||
void HandleEnumOption(ButtonWidget button, Type type) {
|
||||
|
@ -48,8 +48,8 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
}
|
||||
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
return HandleMouseClick(widgets, mouseX, mouseY, button);
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
return HandleMouseDown(widgets, mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
public override bool HandlesMouseMove(int mouseX, int mouseY) {
|
@ -72,7 +72,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
}
|
||||
|
||||
int selectedIndex = 0;
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
mouseX -= X; mouseY -= Y;
|
||||
if (IntersectsHeader(mouseX, mouseY)) {
|
||||
Redraw();
|
||||
|
@ -121,7 +121,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (button != MouseButton.Left || !Bounds.Contains(mouseX, mouseY))
|
||||
return false;
|
||||
InventoryScreen screen = game.Gui.ActiveScreen as InventoryScreen;
|
||||
|
@ -316,7 +316,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
|
||||
public override bool HandlesKeyUp(Key key) { return true; }
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (button == MouseButton.Left)
|
||||
SetCaretToCursor(mouseX, mouseY);
|
||||
return true;
|
||||
|
@ -75,7 +75,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
if (draggingMouse) return true;
|
||||
if (button != MouseButton.Left) return false;
|
||||
|
||||
|
@ -255,11 +255,11 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HandlesMouseClick(int mouseX, int mouseY, MouseButton button) {
|
||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||
PendingClose = false;
|
||||
if (button != MouseButton.Left) return false;
|
||||
|
||||
if (scroll.HandlesMouseClick(mouseX, mouseY, button)) {
|
||||
if (scroll.HandlesMouseDown(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
} else if (SelectedIndex != -1) {
|
||||
game.Inventory.Selected = Elements[SelectedIndex];
|
||||
|
@ -93,7 +93,7 @@
|
||||
<Compile Include="2D\Screens\Overlays\WarningOverlays.cs" />
|
||||
<Compile Include="2D\Screens\StatusScreen.cs" />
|
||||
<Compile Include="2D\Screens\LoadingMapScreen.cs" />
|
||||
<Compile Include="2D\Screens\MenuScreen.cs" />
|
||||
<Compile Include="2D\Screens\Menu\MenuScreen.cs" />
|
||||
<Compile Include="2D\Screens\Menu\ClassicOptionsScreen.cs" />
|
||||
<Compile Include="2D\Screens\Menu\EditHotkeyScreen.cs" />
|
||||
<Compile Include="2D\Screens\Menu\EnvSettingsScreen.cs" />
|
||||
|
@ -115,7 +115,7 @@ namespace ClassicalSharp {
|
||||
}
|
||||
|
||||
void MouseButtonDown(object sender, MouseButtonEventArgs e) {
|
||||
if (!game.Gui.ActiveScreen.HandlesMouseClick(e.X, e.Y, e.Button)) {
|
||||
if (!game.Gui.ActiveScreen.HandlesMouseDown(e.X, e.Y, e.Button)) {
|
||||
bool left = e.Button == MouseButton.Left;
|
||||
bool middle = e.Button == MouseButton.Middle;
|
||||
bool right = e.Button == MouseButton.Right;
|
||||
|
@ -4,6 +4,7 @@
|
||||
/* Represents a 2D array of pixels.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
typedef struct Stream_ Stream;
|
||||
|
||||
typedef struct Bitmap_ {
|
||||
UInt8* Scan0; /* Pointer to first scaneline. */
|
||||
@ -25,7 +26,6 @@ void Bitmap_Allocate(Bitmap* bmp, Int32 width, Int32 height);
|
||||
/* Allocates a power-of-2 sized bitmap larger or equal to to the given size. You are responsible for freeing its memory! */
|
||||
void Bitmap_AllocatePow2(Bitmap* bmp, Int32 width, Int32 height);
|
||||
|
||||
typedef struct Stream_ Stream; /* Forward declaration */
|
||||
/*
|
||||
Partially based off information from
|
||||
https://handmade.network/forums/wip/t/2363-implementing_a_basic_png_reader_the_handmade_way
|
||||
|
@ -205,6 +205,7 @@
|
||||
<ClInclude Include="IModel.h" />
|
||||
<ClInclude Include="Input.h" />
|
||||
<ClInclude Include="InputHandler.h" />
|
||||
<ClInclude Include="Menus.h" />
|
||||
<ClInclude Include="Physics.h" />
|
||||
<ClInclude Include="Inventory.h" />
|
||||
<ClInclude Include="IsometricDrawer.h" />
|
||||
@ -278,6 +279,7 @@
|
||||
<ClCompile Include="GameStructs.c" />
|
||||
<ClCompile Include="Deflate.c" />
|
||||
<ClCompile Include="IModel.c" />
|
||||
<ClCompile Include="Menus.c" />
|
||||
<ClCompile Include="Physics.c" />
|
||||
<ClCompile Include="IsometricDrawer.c" />
|
||||
<ClCompile Include="Input.c" />
|
||||
|
@ -363,6 +363,9 @@
|
||||
<ClInclude Include="Physics.h">
|
||||
<Filter>Header Files\Math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Menus.h">
|
||||
<Filter>Header Files\2D</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Noise.c">
|
||||
@ -566,5 +569,8 @@
|
||||
<ClCompile Include="Physics.c">
|
||||
<Filter>Source Files\Math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Menus.c">
|
||||
<Filter>Source Files\2D</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -2,6 +2,7 @@
|
||||
#include "ErrorHandler.h"
|
||||
#include "Funcs.h"
|
||||
#include "Platform.h"
|
||||
#include "Stream.h"
|
||||
|
||||
bool Header_ReadByte(Stream* s, UInt8* state, Int32* value) {
|
||||
*value = Stream_TryReadByte(s);
|
||||
@ -447,6 +448,7 @@ void Deflate_Process(DeflateState* state) {
|
||||
case 3: {
|
||||
ErrorHandler_Fail("DEFLATE - Invalid block type");
|
||||
} break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef CC_DEFLATE_H
|
||||
#define CC_DEFLATE_H
|
||||
#include "Stream.h"
|
||||
#include "Typedefs.h"
|
||||
/* Decodes data compressed using DEFLATE in a streaming manner.
|
||||
Partially based off information from
|
||||
https://handmade.network/forums/wip/t/2363-implementing_a_basic_png_reader_the_handmade_way
|
||||
@ -9,6 +9,7 @@
|
||||
https://github.com/nothings/stb/blob/master/stb_image.h
|
||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
typedef struct Stream_ Stream;
|
||||
|
||||
typedef struct GZipHeader_ {
|
||||
UInt8 State; bool Done; UInt8 PartsRead; Int32 Flags;
|
||||
|
@ -11,7 +11,7 @@ void Map_ReadBlocks(Stream* stream) {
|
||||
World_BlocksSize = World_Width * World_Length * World_Height;
|
||||
World_Blocks = Platform_MemAlloc(World_BlocksSize);
|
||||
if (World_Blocks == NULL) {
|
||||
ErrorHandler_Fail("Failed to allocate memory when reading blocks array from file");
|
||||
ErrorHandler_Fail("Failed to allocate memory for reading blocks array from file");
|
||||
}
|
||||
Stream_Read(stream, World_Blocks, World_BlocksSize);
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ void GuiElement_Recreate(GuiElement* elem) {
|
||||
elem->VTABLE->Init(elem);
|
||||
}
|
||||
|
||||
bool Gui_FalseMouse(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) { return false; }
|
||||
bool Gui_FalseKey(GuiElement* elem, Key key) { return false; }
|
||||
bool Gui_FalseKeyPress(GuiElement* elem, UInt8 keyChar) { return false; }
|
||||
bool Gui_FalseMouse(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) { return false; }
|
||||
bool Gui_FalseMouseMove(GuiElement* elem, Int32 x, Int32 y) { return false; }
|
||||
bool Gui_FalseMouseScroll(GuiElement* elem, Real32 delta) { return false; }
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef CC_GUI_H
|
||||
#define CC_GUI_H
|
||||
#include "Input.h"
|
||||
#include "VertexStructs.h"
|
||||
#include "Texture.h"
|
||||
#include "GameStructs.h"
|
||||
/* Describes and manages 2D GUI elements on screen.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
typedef struct VertexP3fT2fC4b_ VertexP3fT2fC4b;
|
||||
|
||||
#define ANCHOR_MIN 0 /* Left or top */
|
||||
#define ANCHOR_CENTRE 1 /* Middle */
|
||||
@ -14,28 +14,18 @@
|
||||
|
||||
typedef struct GuiElement_ GuiElement;
|
||||
typedef struct GuiElementVTABLE_ {
|
||||
/* Initalises state of this GUI element */
|
||||
void (*Init)(GuiElement* elem);
|
||||
/* Draws this gui element on screen */
|
||||
void (*Render)(GuiElement* elem, Real64 delta);
|
||||
/* Frees the state of this GUI element */
|
||||
void (*Free)(GuiElement* elem);
|
||||
/* Recreates all sub-elements and/or textures. (e.g. for when bitmap font changes) */
|
||||
void (*Recreate)(GuiElement* elem);
|
||||
/* Returns whether this GUI element handles a key being pressed. */
|
||||
bool (*HandlesKeyDown)(GuiElement* elem, Key key);
|
||||
/* Returns whether this GUI element handles a key being released. */
|
||||
bool (*HandlesKeyUp)(GuiElement* elem, Key key);
|
||||
/* Returns whether this GUI element handles a character being input */
|
||||
bool (*HandlesKeyPress)(GuiElement* elem, UInt8 keyChar);
|
||||
/* Returns whether this GUI element handles a mouse button being pressed. */
|
||||
bool (*HandlesMouseDown)(GuiElement* elem, Int32 x, Int32 y, MouseButton btn);
|
||||
/* Returns whether this GUI element handles a mouse button being released. */
|
||||
bool (*HandlesMouseUp)(GuiElement* elem, Int32 x, Int32 y, MouseButton btn);
|
||||
/* Returns whether this GUI element handles the mouse being moved. */
|
||||
bool (*HandlesMouseMove)(GuiElement* elem, Int32 x, Int32 y);
|
||||
/* Returns whether this GUI element handles the mouse being scrolled. */
|
||||
bool(*HandlesMouseScroll)(GuiElement* elem, Real32 delta);
|
||||
bool (*HandlesMouseScroll)(GuiElement* elem, Real32 delta);
|
||||
} GuiElementVTABLE;
|
||||
|
||||
typedef struct GuiElement_ { GuiElementVTABLE* VTABLE; } GuiElement;
|
||||
@ -103,4 +93,18 @@ void TextAtlas_Make(TextAtlas* atlas, STRING_PURE String* chars, FontDesc* font,
|
||||
void TextAtlas_Free(TextAtlas* atlas);
|
||||
void TextAtlas_Add(TextAtlas* atlas, Int32 charI, VertexP3fT2fC4b** vertices);
|
||||
void TextAtlas_AddInt(TextAtlas* atlas, Int32 value, VertexP3fT2fC4b** vertices);
|
||||
|
||||
|
||||
#define Widget_Reposition(widget) (widget)->Reposition((GuiElement*)(widget));
|
||||
#define Elem_Init(elem) (elem)->VTABLE->Init((GuiElement*)(elem))
|
||||
#define Elem_Render(elem, delta) (elem)->VTABLE->Render((GuiElement*)(elem), delta)
|
||||
#define Elem_Free(elem) (elem)->VTABLE->Free((GuiElement*)(elem))
|
||||
#define Elem_Recreate(elem) (elem)->VTABLE->Recreate((GuiElement*)(elem))
|
||||
#define Elem_HandlesKeyPress(elem, key) (elem)->VTABLE->HandlesKeyPress((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyDown(elem, key) (elem)->VTABLE->HandlesKeyDown((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyUp(elem, key) (elem)->VTABLE->HandlesKeyUp((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesMouseDown(elem, x, y, btn) (elem)->VTABLE->HandlesMouseDown((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseUp(elem, x, y, btn) (elem)->VTABLE->HandlesMouseUp((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseMove(elem, x, y) (elem)->VTABLE->HandlesMouseMove((GuiElement*)(elem), x, y)
|
||||
#define Elem_HandlesMouseScroll(elem, delta) (elem)->VTABLE->HandlesMouseScroll((GuiElement*)(elem), delta)
|
||||
#endif
|
391
src/Client/Menus.c
Normal file
391
src/Client/Menus.c
Normal file
@ -0,0 +1,391 @@
|
||||
#include "Menus.h"
|
||||
#include "Widgets.h"
|
||||
#include "Game.h"
|
||||
#include "Event.h"
|
||||
#include "GraphicsCommon.h"
|
||||
#include "Platform.h"
|
||||
#include "Inventory.h"
|
||||
#include "Drawer2D.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Funcs.h"
|
||||
#include "TerrainAtlas.h"
|
||||
#include "ModelCache.h"
|
||||
#include "MapGenerator.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "Chat.h"
|
||||
#include "ExtMath.h"
|
||||
#include "Window.h"
|
||||
#include "Camera.h"
|
||||
#include "AsyncDownloader.h"
|
||||
#include "Block.h"
|
||||
|
||||
#define LeftOnly(func) { if (btn == MouseButton_Left) { func; } return true; }
|
||||
#define FILES_SCREEN_ITEMS 5
|
||||
#define FILES_SCREEN_BUTTONS (FILES_SCREEN_ITEMS + 3)
|
||||
|
||||
typedef struct ListScreen_ {
|
||||
Screen_Layout
|
||||
FontDesc Font;
|
||||
Int32 CurrentIndex;
|
||||
ButtonWidget_Click TextButtonClick;
|
||||
String TitleText;
|
||||
ButtonWidget Buttons[FILES_SCREEN_BUTTONS];
|
||||
TextWidget Title;
|
||||
Widget* Widgets[FILES_SCREEN_BUTTONS + 1];
|
||||
StringsBuffer Entries; /* NOTE: this is the last member so we can avoid memsetting it to 0 */
|
||||
} ListScreen;
|
||||
|
||||
typedef void (*Menu_ContextRecreated)(GuiElement* elem);
|
||||
typedef struct MenuScreen_ {
|
||||
Screen_Layout
|
||||
Widget** WidgetsPtr;
|
||||
Int32 WidgetsCount;
|
||||
FontDesc TitleFont, RegularFont;
|
||||
Menu_ContextRecreated ContextRecreated;
|
||||
} MenuScreen;
|
||||
|
||||
|
||||
void Menu_FreeWidgets(Widget** widgets, Int32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
Int32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->VTABLE->Free((GuiElement*)widgets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu_RepositionWidgets(Widget** widgets, Int32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
Int32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->Reposition((GuiElement*)widgets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu_RenderWidgets(Widget** widgets, Int32 widgetsCount, Real64 delta) {
|
||||
if (widgets == NULL) return;
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->VTABLE->Render((GuiElement*)widgets[i], delta);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu_MakeBack(ButtonWidget* widget, Int32 width, STRING_PURE String* text, Int32 y, FontDesc* font, ButtonWidget_Click onClick) {
|
||||
ButtonWidget_Create(widget, text, width, font, onClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_MAX, 0, y);
|
||||
}
|
||||
|
||||
void Menu_MakeDefaultBack(ButtonWidget* widget, bool toGame, FontDesc* font, ButtonWidget_Click onClick) {
|
||||
Int32 width = Game_UseClassicOptions ? 400 : 200;
|
||||
if (toGame) {
|
||||
String msg = String_FromConst("Back to game");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
} else {
|
||||
String msg = String_FromConst("Cancel");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
}
|
||||
}
|
||||
|
||||
bool Menu_SwitchOptions(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
LeftOnly(Gui_SetNewScreen(OptionsGroupScreen_MakeInstance()));
|
||||
}
|
||||
bool Menu_SwitchPause(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
LeftOnly(Gui_SetNewScreen(PauseScreen_MakeInstance()));
|
||||
}
|
||||
|
||||
void Menu_RenderBounds(void) {
|
||||
/* These were sourced by taking a screenshot of vanilla
|
||||
Then using paint to extract the colour components
|
||||
Then using wolfram alpha to solve the glblendfunc equation */
|
||||
PackedCol topCol = PACKEDCOL_CONST(24, 24, 24, 105);
|
||||
PackedCol bottomCol = PACKEDCOL_CONST(51, 51, 98, 162);
|
||||
GfxCommon_Draw2DGradient(0, 0, Game_Width, Game_Height, topCol, bottomCol);
|
||||
}
|
||||
|
||||
bool Menu_HandleMouseDown(Widget** widgets, Int32 count, Int32 x, Int32 y, MouseButton btn) {
|
||||
Int32 i;
|
||||
/* iterate backwards (because last elements rendered are shown over others) */
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL && Widget_Contains(widget, x, y)) {
|
||||
if (!widget->Disabled) {
|
||||
widget->VTABLE->HandlesMouseDown((GuiElement*)widget, x, y, btn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Int32 Menu_HandleMouseMove(Widget** widgets, Int32 count, Int32 x, Int32 y) {
|
||||
Int32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL) widget->Active = false;
|
||||
}
|
||||
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL && Widget_Contains(widget, x, y)) {
|
||||
widget->Active = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
GuiElementVTABLE ListScreen_VTABLE;
|
||||
ListScreen ListScreen_Instance;
|
||||
String ListScreen_Get(ListScreen* screen, UInt32 index) {
|
||||
if (index < screen->Entries.Count) {
|
||||
return StringsBuffer_UNSAFE_Get(&screen->Entries, index);
|
||||
} else {
|
||||
String str = String_FromConst("-----"); return str;
|
||||
}
|
||||
}
|
||||
|
||||
void ListScreen_MakeText(ListScreen* screen, Int32 idx, Int32 x, Int32 y, String* text) {
|
||||
ButtonWidget* widget = &screen->Buttons[idx];
|
||||
ButtonWidget_Create(widget, text, 300, &screen->Font, screen->TextButtonClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_CENTRE, x, y);
|
||||
}
|
||||
|
||||
void ListScreen_Make(ListScreen* screen, Int32 idx, Int32 x, Int32 y, String* text, ButtonWidget_Click onClick) {
|
||||
ButtonWidget* widget = &screen->Buttons[idx];
|
||||
ButtonWidget_Create(widget, text, 40, &screen->Font, onClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_CENTRE, x, y);
|
||||
}
|
||||
|
||||
void ListScreen_UpdateArrows(ListScreen* screen) {
|
||||
Int32 start = FILES_SCREEN_ITEMS, end = screen->Entries.Count - FILES_SCREEN_ITEMS;
|
||||
screen->Buttons[5].Disabled = screen->CurrentIndex < start;
|
||||
screen->Buttons[6].Disabled = screen->CurrentIndex >= end;
|
||||
}
|
||||
|
||||
void ListScreen_SetCurrentIndex(ListScreen* screen, Int32 index) {
|
||||
if (index >= screen->Entries.Count) index -= FILES_SCREEN_ITEMS;
|
||||
if (index < 0) index = 0;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < FILES_SCREEN_ITEMS; i++) {
|
||||
String str = ListScreen_Get(screen, index + i);
|
||||
ButtonWidget_SetText(&screen->Buttons[i], &str);
|
||||
}
|
||||
|
||||
screen->CurrentIndex = index;
|
||||
ListScreen_UpdateArrows(screen);
|
||||
}
|
||||
|
||||
void ListScreen_PageClick(ListScreen* screen, bool forward) {
|
||||
Int32 delta = forward ? FILES_SCREEN_ITEMS : -FILES_SCREEN_ITEMS;
|
||||
ListScreen_SetCurrentIndex(screen, screen->CurrentIndex + delta);
|
||||
}
|
||||
|
||||
bool ListScreen_MoveBackwards(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
LeftOnly(ListScreen_PageClick(screen, false));
|
||||
}
|
||||
|
||||
bool ListScreen_MoveForwards(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
LeftOnly(ListScreen_PageClick(screen, true));
|
||||
}
|
||||
|
||||
void ListScreen_ContextLost(void* obj) {
|
||||
ListScreen* screen = (ListScreen*)obj;
|
||||
Menu_FreeWidgets(screen->Widgets, Array_Elems(screen->Widgets));
|
||||
}
|
||||
|
||||
void ListScreen_ContextRecreated(void* obj) {
|
||||
ListScreen* screen = (ListScreen*)obj;
|
||||
TextWidget_Create(&screen->Title, &screen->TitleText, &screen->Font);
|
||||
Widget_SetLocation((Widget*)(&screen->Title), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -155);
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < FILES_SCREEN_ITEMS; i++) {
|
||||
String str = ListScreen_Get(screen, i);
|
||||
ListScreen_MakeText(screen, i, 0, 50 * (Int32)i - 100, &str);
|
||||
}
|
||||
|
||||
String lArrow = String_FromConst("<");
|
||||
ListScreen_Make(screen, 5, -220, 0, &lArrow, ListScreen_MoveBackwards);
|
||||
String rArrow = String_FromConst(">");
|
||||
ListScreen_Make(screen, 6, 220, 0, &rArrow, ListScreen_MoveForwards);
|
||||
Screen_MakeDefaultBack(&screen->Buttons[7], false, &screen->Font, Menu_SwitchPause);
|
||||
|
||||
screen->Widgets[0] = (Widget*)(&screen->Title);
|
||||
for (i = 0; i < FILES_SCREEN_BUTTONS; i++) {
|
||||
screen->Widgets[i + 1] = (Widget*)(&screen->Buttons[i]);
|
||||
}
|
||||
ListScreen_UpdateArrows(screen);
|
||||
}
|
||||
|
||||
void ListScreen_Init(GuiElement* elem) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
Platform_MakeFont(&screen->Font, &Game_FontName, 16, FONT_STYLE_BOLD);
|
||||
ListScreen_ContextRecreated(screen);
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, screen, ListScreen_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, screen, ListScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void ListScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
Menu_RenderBounds();
|
||||
Gfx_SetTexturing(true);
|
||||
Menu_RenderWidgets(screen->Widgets, Array_Elems(screen->Widgets), delta);
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void ListScreen_Free(GuiElement* elem) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
Platform_FreeFont(&screen->Font);
|
||||
ListScreen_ContextLost(screen);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, screen, ListScreen_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, screen, ListScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
bool ListScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
if (key == Key_Escape) {
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (key == Key_Left) {
|
||||
ListScreen_PageClick(screen, false);
|
||||
} else if (key == Key_Right) {
|
||||
ListScreen_PageClick(screen, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ListScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
return Menu_HandleMouseMove(screen->Widgets, Array_Elems(screen->Widgets), x, y) >= 0;
|
||||
}
|
||||
|
||||
bool ListScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
return Menu_HandleMouseDown(screen->Widgets, Array_Elems(screen->Widgets), x, y, btn);
|
||||
}
|
||||
|
||||
void ListScreen_OnResize(GuiElement* elem) {
|
||||
ListScreen* screen = (ListScreen*)elem;
|
||||
Menu_RepositionWidgets(screen->Widgets, Array_Elems(screen->Widgets));
|
||||
}
|
||||
|
||||
Screen* ListScreen_MakeInstance(void) {
|
||||
ListScreen* screen = &ListScreen_Instance;
|
||||
Platform_MemSet(screen, 0, sizeof(ListScreen) - sizeof(StringsBuffer));
|
||||
StringsBuffer_UNSAFE_Reset(&screen->Entries);
|
||||
screen->VTABLE = &ListScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
screen->VTABLE->HandlesKeyDown = ListScreen_HandlesKeyDown;
|
||||
screen->VTABLE->HandlesMouseDown = ListScreen_HandlesMouseDown;
|
||||
screen->VTABLE->HandlesMouseMove = ListScreen_HandlesMouseMove;
|
||||
|
||||
screen->OnResize = ListScreen_OnResize;
|
||||
screen->VTABLE->Init = ListScreen_Init;
|
||||
screen->VTABLE->Render = ListScreen_Render;
|
||||
screen->VTABLE->Free = ListScreen_Free;
|
||||
screen->HandlesAllInput = true;
|
||||
return (Screen*)screen;
|
||||
}
|
||||
|
||||
|
||||
GuiElementVTABLE MenuScreen_VTABLE;
|
||||
Int32 MenuScreen_Index(MenuScreen* screen, Widget* w) {
|
||||
Int32 i;
|
||||
for (i = 0; i < screen->WidgetsCount; i++) {
|
||||
if (screen->WidgetsPtr[i] == w) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool MenuScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
return Menu_HandleMouseDown(screen->WidgetsPtr, screen->WidgetsCount, x, y, btn);
|
||||
}
|
||||
|
||||
bool MenuScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
return Menu_HandleMouseMove(screen->WidgetsPtr, screen->WidgetsCount, x, y) >= 0;
|
||||
}
|
||||
|
||||
bool MenuScreen_TrueMouse(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) { return true; }
|
||||
bool MenuScreen_TrueMouseScroll(GuiElement* elem, Real32 delta) { return true; }
|
||||
bool MenuScreen_TrueKeyPress(GuiElement* elem, UInt8 key) { return true; }
|
||||
bool MenuScreen_TrueKey(GuiElement* elem, Key key) { return true; }
|
||||
|
||||
void MenuScreen_ContextLost(void* obj) {
|
||||
MenuScreen* screen = (MenuScreen*)obj;
|
||||
Menu_FreeWidgets(screen->WidgetsPtr, screen->WidgetsCount);
|
||||
}
|
||||
|
||||
void MenuScreen_ContextRecreated(void* obj) {
|
||||
MenuScreen* screen = (MenuScreen*)obj;
|
||||
screen->ContextRecreated((GuiElement*)screen);
|
||||
}
|
||||
|
||||
void MenuScreen_Init(GuiElement* elem) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, screen, MenuScreen_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, screen, MenuScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void MenuScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
Menu_RenderBounds();
|
||||
Gfx_SetTexturing(true);
|
||||
Menu_RenderWidgets(screen->WidgetsPtr, screen->WidgetsCount, delta);
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void MenuScreen_Free(GuiElement* elem) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
MenuScreen_ContextLost(screen);
|
||||
|
||||
if (screen->TitleFont.Handle != NULL) {
|
||||
Platform_FreeFont(&screen->TitleFont);
|
||||
}
|
||||
if (screen->RegularFont.Handle != NULL) {
|
||||
Platform_FreeFont(&screen->RegularFont);
|
||||
}
|
||||
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, screen, MenuScreen_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, screen, MenuScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void MenuScreen_OnResize(GuiElement* elem) {
|
||||
MenuScreen* screen = (MenuScreen*)elem;
|
||||
Menu_RepositionWidgets(screen->WidgetsPtr, screen->WidgetsCount);
|
||||
}
|
||||
|
||||
void MenuScreen_MakeInstance(MenuScreen* screen, Widget** widgets, Int32 count, Menu_ContextRecreated contextRecreated) {
|
||||
ListScreen* screen = &ListScreen_Instance;
|
||||
Platform_MemSet(screen, 0, sizeof(MenuScreen));
|
||||
screen->VTABLE = &MenuScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
screen->VTABLE->HandlesKeyDown = MenuScreen_TrueKey;
|
||||
screen->VTABLE->HandlesKeyUp = MenuScreen_TrueKey;
|
||||
screen->VTABLE->HandlesKeyPress = MenuScreen_TrueKeyPress;
|
||||
screen->VTABLE->HandlesMouseDown = MenuScreen_HandlesMouseDown;
|
||||
screen->VTABLE->HandlesMouseUp = MenuScreen_TrueMouse;
|
||||
screen->VTABLE->HandlesMouseMove = MenuScreen_HandlesMouseMove;
|
||||
screen->VTABLE->HandlesMouseScroll = MenuScreen_TrueMouseScroll;
|
||||
|
||||
screen->OnResize = MenuScreen_OnResize;
|
||||
screen->VTABLE->Init = MenuScreen_Init;
|
||||
screen->VTABLE->Render = MenuScreen_Render;
|
||||
screen->VTABLE->Free = MenuScreen_Free;
|
||||
|
||||
screen->HandlesAllInput = true;
|
||||
screen->WidgetsPtr = widgets;
|
||||
screen->WidgetsCount = count;
|
||||
screen->ContextRecreated = contextRecreated;
|
||||
}
|
12
src/Client/Menus.h
Normal file
12
src/Client/Menus.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef CC_MENUS_H
|
||||
#define CC_MENUS_H
|
||||
#include "Gui.h"
|
||||
#include "String.h"
|
||||
|
||||
/* Contains all 2D menu screen implementations.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
Screen* OptionsGroupScreen_MakeInstance(void);
|
||||
Screen* PauseScreen_MakeInstance(void);
|
||||
#endif
|
@ -19,22 +19,6 @@
|
||||
#include "AsyncDownloader.h"
|
||||
#include "Block.h"
|
||||
|
||||
#define LeftOnly(func) { if (btn == MouseButton_Left) { func; } return true; }
|
||||
#define Widget_Reposition(widget) (widget)->Reposition((GuiElement*)widget)
|
||||
|
||||
#define Elem_Init(elem) (elem)->VTABLE->Init((GuiElement*)(elem))
|
||||
#define Elem_Render(elem, delta) (elem)->VTABLE->Render((GuiElement*)(elem), delta)
|
||||
#define Elem_Free(elem) (elem)->VTABLE->Free((GuiElement*)(elem))
|
||||
#define Elem_Recreate(elem) (elem)->VTABLE->Recreate((GuiElement*)(elem))
|
||||
|
||||
#define Elem_HandlesKeyPress(elem, key) (elem)->VTABLE->HandlesKeyPress((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyDown(elem, key) (elem)->VTABLE->HandlesKeyDown((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyUp(elem, key) (elem)->VTABLE->HandlesKeyUp((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesMouseDown(elem, x, y, btn) (elem)->VTABLE->HandlesMouseDown((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseUp(elem, x, y, btn) (elem)->VTABLE->HandlesMouseUp((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseMove(elem, x, y) (elem)->VTABLE->HandlesMouseMove((GuiElement*)(elem), x, y)
|
||||
#define Elem_HandlesMouseScroll(elem, delta) (elem)->VTABLE->HandlesMouseScroll((GuiElement*)(elem), delta)
|
||||
|
||||
|
||||
typedef struct InventoryScreen_ {
|
||||
Screen_Layout
|
||||
@ -63,20 +47,6 @@ typedef struct HUDScreen_ {
|
||||
bool ShowingList, WasShowingList;
|
||||
} HUDScreen;
|
||||
|
||||
#define FILES_SCREEN_ITEMS 5
|
||||
#define FILES_SCREEN_BUTTONS (FILES_SCREEN_ITEMS + 3)
|
||||
typedef struct FilesScreen_ {
|
||||
Screen_Layout
|
||||
FontDesc Font;
|
||||
Int32 CurrentIndex;
|
||||
Gui_MouseHandler TextButtonClick;
|
||||
String TitleText;
|
||||
ButtonWidget Buttons[FILES_SCREEN_BUTTONS];
|
||||
TextWidget Title;
|
||||
Widget* Widgets[FILES_SCREEN_BUTTONS + 1];
|
||||
StringsBuffer Entries; /* NOTE: this is the last member so we can avoid memsetting it to 0 */
|
||||
} FilesScreen;
|
||||
|
||||
typedef struct LoadingScreen_ {
|
||||
Screen_Layout
|
||||
FontDesc Font;
|
||||
@ -124,100 +94,6 @@ typedef struct DisconnectScreen_ {
|
||||
} DisconnectScreen;
|
||||
|
||||
|
||||
void Screen_FreeWidgets(Widget** widgets, UInt32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
UInt32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->VTABLE->Free((GuiElement*)widgets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Screen_RepositionWidgets(Widget** widgets, UInt32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
UInt32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->Reposition((GuiElement*)widgets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Screen_RenderWidgets(Widget** widgets, UInt32 widgetsCount, Real64 delta) {
|
||||
if (widgets == NULL) return;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < widgetsCount; i++) {
|
||||
if (widgets[i] == NULL) continue;
|
||||
widgets[i]->VTABLE->Render((GuiElement*)widgets[i], delta);
|
||||
}
|
||||
}
|
||||
|
||||
void Screen_MakeBack(ButtonWidget* widget, Int32 width, STRING_PURE String* text, Int32 y, FontDesc* font, Gui_MouseHandler onClick) {
|
||||
ButtonWidget_Create(widget, text, width, font, onClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_MAX, 0, y);
|
||||
}
|
||||
|
||||
void Screen_MakeDefaultBack(ButtonWidget* widget, bool toGame, FontDesc* font, Gui_MouseHandler onClick) {
|
||||
Int32 width = Game_UseClassicOptions ? 400 : 200;
|
||||
if (toGame) {
|
||||
String msg = String_FromConst("Back to game");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
} else {
|
||||
String msg = String_FromConst("Cancel");
|
||||
Screen_MakeBack(widget, width, &msg, 25, font, onClick);
|
||||
}
|
||||
}
|
||||
|
||||
bool Screen_SwitchOptions(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
LeftOnly(Gui_SetNewScreen(OptionsGroupScreen_MakeInstance()));
|
||||
}
|
||||
bool Screen_SwitchPause(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
LeftOnly(Gui_SetNewScreen(PauseScreen_MakeInstance()));
|
||||
}
|
||||
|
||||
|
||||
void MenuScreen_RenderBounds(void) {
|
||||
/* These were sourced by taking a screenshot of vanilla
|
||||
Then using paint to extract the colour components
|
||||
Then using wolfram alpha to solve the glblendfunc equation */
|
||||
PackedCol topCol = PACKEDCOL_CONST(24, 24, 24, 105);
|
||||
PackedCol bottomCol = PACKEDCOL_CONST(51, 51, 98, 162);
|
||||
GfxCommon_Draw2DGradient(0, 0, Game_Width, Game_Height, topCol, bottomCol);
|
||||
}
|
||||
|
||||
bool Clickable_HandleMouseDown(Widget** widgets, Int32 count, Int32 x, Int32 y, MouseButton btn) {
|
||||
Int32 i;
|
||||
/* iterate backwards (because last elements rendered are shown over others) */
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL && Widget_Contains(widget, x, y)) {
|
||||
if (!widget->Disabled) {
|
||||
widget->VTABLE->HandlesMouseDown((GuiElement*)widget, x, y, btn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Int32 Clickable_HandleMouseMove(Widget** widgets, Int32 count, Int32 x, Int32 y) {
|
||||
Int32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL) widget->Active = false;
|
||||
}
|
||||
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
Widget* widget = widgets[i];
|
||||
if (widget != NULL && Widget_Contains(widget, x, y)) {
|
||||
widget->Active = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
GuiElementVTABLE InventoryScreen_VTABLE;
|
||||
InventoryScreen InventoryScreen_Instance;
|
||||
void InventoryScreen_OnBlockChanged(void* obj) {
|
||||
@ -339,7 +215,7 @@ bool InventoryScreen_HandlesMouseScroll(GuiElement* elem, Real32 delta) {
|
||||
|
||||
Screen* InventoryScreen_MakeInstance(void) {
|
||||
InventoryScreen* screen = &InventoryScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(InventoryScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(InventoryScreen));
|
||||
screen->VTABLE = &InventoryScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
@ -531,7 +407,7 @@ void StatusScreen_Free(GuiElement* elem) {
|
||||
|
||||
Screen* StatusScreen_MakeInstance(void) {
|
||||
StatusScreen* screen = &StatusScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(StatusScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(StatusScreen));
|
||||
screen->VTABLE = &StatusScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
@ -550,165 +426,6 @@ IGameComponent StatusScreen_MakeComponent(void) {
|
||||
}
|
||||
|
||||
|
||||
GuiElementVTABLE FilesScreen_VTABLE;
|
||||
FilesScreen FilesScreen_Instance;
|
||||
String FilesScreen_Get(FilesScreen* screen, UInt32 index) {
|
||||
if (index < screen->Entries.Count) {
|
||||
return StringsBuffer_UNSAFE_Get(&screen->Entries, index);
|
||||
} else {
|
||||
String str = String_FromConst("-----"); return str;
|
||||
}
|
||||
}
|
||||
|
||||
void FilesScreen_MakeText(FilesScreen* screen, Int32 idx, Int32 x, Int32 y, String* text) {
|
||||
ButtonWidget* widget = &screen->Buttons[idx];
|
||||
ButtonWidget_Create(widget, text, 300, &screen->Font, screen->TextButtonClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_CENTRE, x, y);
|
||||
}
|
||||
|
||||
void FilesScreen_Make(FilesScreen* screen, Int32 idx, Int32 x, Int32 y, String* text, Gui_MouseHandler onClick) {
|
||||
ButtonWidget* widget = &screen->Buttons[idx];
|
||||
ButtonWidget_Create(widget, text, 40, &screen->Font, onClick);
|
||||
Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_CENTRE, x, y);
|
||||
}
|
||||
|
||||
void FilesScreen_UpdateArrows(FilesScreen* screen) {
|
||||
Int32 start = FILES_SCREEN_ITEMS, end = screen->Entries.Count - FILES_SCREEN_ITEMS;
|
||||
screen->Buttons[5].Disabled = screen->CurrentIndex < start;
|
||||
screen->Buttons[6].Disabled = screen->CurrentIndex >= end;
|
||||
}
|
||||
|
||||
void FilesScreen_SetCurrentIndex(FilesScreen* screen, Int32 index) {
|
||||
if (index >= screen->Entries.Count) index -= FILES_SCREEN_ITEMS;
|
||||
if (index < 0) index = 0;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < FILES_SCREEN_ITEMS; i++) {
|
||||
String str = FilesScreen_Get(screen, index + i);
|
||||
ButtonWidget_SetText(&screen->Buttons[i], &str);
|
||||
}
|
||||
|
||||
screen->CurrentIndex = index;
|
||||
FilesScreen_UpdateArrows(screen);
|
||||
}
|
||||
|
||||
void FilesScreen_PageClick(FilesScreen* screen, bool forward) {
|
||||
Int32 delta = forward ? FILES_SCREEN_ITEMS : -FILES_SCREEN_ITEMS;
|
||||
FilesScreen_SetCurrentIndex(screen, screen->CurrentIndex + delta);
|
||||
}
|
||||
|
||||
bool FilesScreen_MoveBackwards(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
LeftOnly(FilesScreen_PageClick(screen, false));
|
||||
}
|
||||
|
||||
bool FilesScreen_MoveForwards(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
LeftOnly(FilesScreen_PageClick(screen, true));
|
||||
}
|
||||
|
||||
void FilesScreen_ContextLost(void* obj) {
|
||||
FilesScreen* screen = (FilesScreen*)obj;
|
||||
Screen_FreeWidgets(screen->Widgets, Array_Elems(screen->Widgets));
|
||||
}
|
||||
|
||||
void FilesScreen_ContextRecreated(void* obj) {
|
||||
FilesScreen* screen = (FilesScreen*)obj;
|
||||
TextWidget_Create(&screen->Title, &screen->TitleText, &screen->Font);
|
||||
Widget_SetLocation((Widget*)(&screen->Title), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -155);
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < FILES_SCREEN_ITEMS; i++) {
|
||||
String str = FilesScreen_Get(screen, i);
|
||||
FilesScreen_MakeText(screen, i, 0, 50 * (Int32)i - 100, &str);
|
||||
}
|
||||
|
||||
String lArrow = String_FromConst("<");
|
||||
FilesScreen_Make(screen, 5, -220, 0, &lArrow, FilesScreen_MoveBackwards);
|
||||
String rArrow = String_FromConst(">");
|
||||
FilesScreen_Make(screen, 6, 220, 0, &rArrow, FilesScreen_MoveForwards);
|
||||
Screen_MakeDefaultBack(&screen->Buttons[7], false, &screen->Font, Screen_SwitchPause);
|
||||
|
||||
screen->Widgets[0] = (Widget*)(&screen->Title);
|
||||
for (i = 0; i < FILES_SCREEN_BUTTONS; i++) {
|
||||
screen->Widgets[i + 1] = (Widget*)(&screen->Buttons[i]);
|
||||
}
|
||||
FilesScreen_UpdateArrows(screen);
|
||||
}
|
||||
|
||||
void FilesScreen_Init(GuiElement* elem) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
Platform_MakeFont(&screen->Font, &Game_FontName, 16, FONT_STYLE_BOLD);
|
||||
FilesScreen_ContextRecreated(screen);
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, screen, FilesScreen_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, screen, FilesScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void FilesScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
MenuScreen_RenderBounds();
|
||||
Gfx_SetTexturing(true);
|
||||
Screen_RenderWidgets(screen->Widgets, Array_Elems(screen->Widgets), delta);
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void FilesScreen_Free(GuiElement* elem) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
Platform_FreeFont(&screen->Font);
|
||||
FilesScreen_ContextLost(screen);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, screen, FilesScreen_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, screen, FilesScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
bool FilesScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
if (key == Key_Escape) {
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (key == Key_Left) {
|
||||
FilesScreen_PageClick(screen, false);
|
||||
} else if (key == Key_Right) {
|
||||
FilesScreen_PageClick(screen, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FilesScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
return Clickable_HandleMouseMove(screen->Widgets, Array_Elems(screen->Widgets), x, y) >= 0;
|
||||
}
|
||||
|
||||
bool FilesScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
return Clickable_HandleMouseDown(screen->Widgets, Array_Elems(screen->Widgets), x, y, btn);
|
||||
}
|
||||
|
||||
void FilesScreen_OnResize(GuiElement* elem) {
|
||||
FilesScreen* screen = (FilesScreen*)elem;
|
||||
Screen_RepositionWidgets(screen->Widgets, Array_Elems(screen->Widgets));
|
||||
}
|
||||
|
||||
Screen* FilesScreen_MakeInstance(void) {
|
||||
FilesScreen* screen = &FilesScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(FilesScreen) - sizeof(StringsBuffer));
|
||||
StringsBuffer_UNSAFE_Reset(&screen->Entries);
|
||||
screen->VTABLE = &FilesScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
screen->VTABLE->HandlesKeyDown = FilesScreen_HandlesKeyDown;
|
||||
screen->VTABLE->HandlesMouseDown = FilesScreen_HandlesMouseDown;
|
||||
screen->VTABLE->HandlesMouseMove = FilesScreen_HandlesMouseMove;
|
||||
|
||||
screen->OnResize = FilesScreen_OnResize;
|
||||
screen->VTABLE->Init = FilesScreen_Init;
|
||||
screen->VTABLE->Render = FilesScreen_Render;
|
||||
screen->VTABLE->Free = FilesScreen_Free;
|
||||
screen->HandlesAllInput = true;
|
||||
return (Screen*)screen;
|
||||
}
|
||||
|
||||
|
||||
GuiElementVTABLE LoadingScreen_VTABLE;
|
||||
LoadingScreen LoadingScreen_Instance;
|
||||
void LoadingScreen_SetTitle(LoadingScreen* screen) {
|
||||
@ -850,7 +567,7 @@ void LoadingScreen_Free(GuiElement* elem) {
|
||||
}
|
||||
|
||||
void LoadingScreen_Make(LoadingScreen* screen, GuiElementVTABLE* vtable, STRING_PURE String* title, STRING_PURE String* message) {
|
||||
Platform_MemSet(&screen, 0, sizeof(LoadingScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(LoadingScreen));
|
||||
screen->VTABLE = vtable;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
@ -1392,7 +1109,7 @@ void ChatScreen_Free(GuiElement* elem) {
|
||||
|
||||
Screen* ChatScreen_MakeInstance(void) {
|
||||
ChatScreen* screen = &ChatScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(ChatScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(ChatScreen));
|
||||
screen->VTABLE = &ChatScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
@ -1595,7 +1312,7 @@ void HUDScreen_Free(GuiElement* elem) {
|
||||
|
||||
Screen* HUDScreen_MakeInstance(void) {
|
||||
HUDScreen* screen = &HUDScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(HUDScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(HUDScreen));
|
||||
screen->VTABLE = &HUDScreenVTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
@ -1801,7 +1518,7 @@ bool DisconnectScreen_HandlesMouseUp(GuiElement* elem, Int32 x, Int32 y, MouseBu
|
||||
|
||||
Screen* DisconnectScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String* message) {
|
||||
DisconnectScreen* screen = &DisconnectScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(DisconnectScreen));
|
||||
Platform_MemSet(screen, 0, sizeof(DisconnectScreen));
|
||||
screen->VTABLE = &DisconnectScreen_VTABLE;
|
||||
Screen_Reset((Screen*)screen);
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
#ifndef CC_SCREEN_H
|
||||
#define CC_SCREEN_H
|
||||
#ifndef CC_SCREENS_H
|
||||
#define CC_SCREENS_H
|
||||
#include "Gui.h"
|
||||
#include "String.h"
|
||||
|
||||
/* Contains all 2D screen implementations.
|
||||
/* Contains all 2D non-menu screen implementations.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
|
@ -18,21 +18,6 @@
|
||||
#include "Game.h"
|
||||
#include "ErrorHandler.h"
|
||||
|
||||
#define Widget_Reposition(widget) (widget)->Reposition((GuiElement*)(widget));
|
||||
|
||||
#define Elem_Init(elem) (elem)->VTABLE->Init((GuiElement*)(elem))
|
||||
#define Elem_Render(elem, delta) (elem)->VTABLE->Render((GuiElement*)(elem), delta)
|
||||
#define Elem_Free(elem) (elem)->VTABLE->Free((GuiElement*)(elem))
|
||||
#define Elem_Recreate(elem) (elem)->VTABLE->Recreate((GuiElement*)(elem))
|
||||
|
||||
#define Elem_HandlesKeyPress(elem, key) (elem)->VTABLE->HandlesKeyPress((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyDown(elem, key) (elem)->VTABLE->HandlesKeyDown((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesKeyUp(elem, key) (elem)->VTABLE->HandlesKeyUp((GuiElement*)(elem), key)
|
||||
#define Elem_HandlesMouseDown(elem, x, y, btn) (elem)->VTABLE->HandlesMouseDown((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseUp(elem, x, y, btn) (elem)->VTABLE->HandlesMouseUp((GuiElement*)(elem), x, y, btn)
|
||||
#define Elem_HandlesMouseMove(elem, x, y) (elem)->VTABLE->HandlesMouseMove((GuiElement*)(elem), x, y)
|
||||
#define Elem_HandlesMouseScroll(elem, delta) (elem)->VTABLE->HandlesMouseScroll((GuiElement*)(elem), delta)
|
||||
|
||||
void Widget_SetLocation(Widget* widget, UInt8 horAnchor, UInt8 verAnchor, Int32 xOffset, Int32 yOffset) {
|
||||
widget->HorAnchor = horAnchor; widget->VerAnchor = verAnchor;
|
||||
widget->XOffset = xOffset; widget->YOffset = yOffset;
|
||||
@ -172,12 +157,8 @@ void ButtonWidget_Render(GuiElement* elem, Real64 delta) {
|
||||
Texture_RenderShaded(&widget->Texture, col);
|
||||
}
|
||||
|
||||
bool ButtonWidget_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
return ((ButtonWidget*)elem)->OnClick(x, y, btn);
|
||||
}
|
||||
|
||||
GuiElementVTABLE ButtonWidget_VTABLE;
|
||||
void ButtonWidget_Create(ButtonWidget* widget, STRING_PURE String* text, Int32 minWidth, FontDesc* font, Gui_MouseHandler onClick) {
|
||||
void ButtonWidget_Create(ButtonWidget* widget, STRING_PURE String* text, Int32 minWidth, FontDesc* font, ButtonWidget_Click onClick) {
|
||||
widget->VTABLE = &ButtonWidget_VTABLE;
|
||||
Widget_Init((Widget*)widget);
|
||||
widget->VTABLE->Init = ButtonWidget_Init;
|
||||
@ -190,7 +171,6 @@ void ButtonWidget_Create(ButtonWidget* widget, STRING_PURE String* text, Int32 m
|
||||
widget->MinWidth = minWidth; widget->MinHeight = 40;
|
||||
ButtonWidget_SetText(widget, text);
|
||||
widget->OnClick = onClick;
|
||||
widget->VTABLE->HandlesMouseDown = ButtonWidget_HandlesMouseDown;
|
||||
}
|
||||
|
||||
void ButtonWidget_SetText(ButtonWidget* widget, STRING_PURE String* text) {
|
||||
|
@ -1,9 +1,6 @@
|
||||
#ifndef CC_WIDGETS_H
|
||||
#define CC_WIDGETS_H
|
||||
#include "Gui.h"
|
||||
#include "Texture.h"
|
||||
#include "PackedCol.h"
|
||||
#include "String.h"
|
||||
#include "BlockID.h"
|
||||
#include "Constants.h"
|
||||
#include "Entity.h"
|
||||
@ -28,9 +25,10 @@ void TextWidget_Create(TextWidget* widget, STRING_PURE String* text, FontDesc* f
|
||||
void TextWidget_SetText(TextWidget* widget, STRING_PURE String* text);
|
||||
|
||||
|
||||
typedef void (*ButtonWidget_SetValue)(STRING_TRANSIENT String* raw);
|
||||
typedef void (*ButtonWidget_GetValue)(STRING_TRANSIENT String* raw);
|
||||
typedef bool (*Gui_MouseHandler)(GuiElement* elem, Int32 x, Int32 y, MouseButton btn);
|
||||
typedef void (*ButtonWidget_Set)(STRING_TRANSIENT String* raw);
|
||||
typedef void (*ButtonWidget_Get)(STRING_TRANSIENT String* raw);
|
||||
typedef void (*ButtonWidget_Click)(GuiElement* elem, Int32 x, Int32 y, MouseButton btn);
|
||||
|
||||
typedef struct ButtonWidget_ {
|
||||
Widget_Layout
|
||||
Texture Texture;
|
||||
@ -38,13 +36,13 @@ typedef struct ButtonWidget_ {
|
||||
FontDesc Font;
|
||||
|
||||
String OptName;
|
||||
Gui_MouseHandler OnClick;
|
||||
ButtonWidget_GetValue GetValue;
|
||||
ButtonWidget_SetValue SetValue;
|
||||
ButtonWidget_Click OnClick;
|
||||
ButtonWidget_Get GetValue;
|
||||
ButtonWidget_Set SetValue;
|
||||
Int32 MinWidth, MinHeight;
|
||||
} ButtonWidget;
|
||||
|
||||
void ButtonWidget_Create(ButtonWidget* widget, STRING_PURE String* text, Int32 minWidth, FontDesc* font, Gui_MouseHandler onClick);
|
||||
void ButtonWidget_Create(ButtonWidget* widget, STRING_PURE String* text, Int32 minWidth, FontDesc* font, Button_WidgetClick onClick);
|
||||
void ButtonWidget_SetText(ButtonWidget* widget, STRING_PURE String* text);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user