mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 20:15:35 -04:00
Start porting SpecialInputWidget to C.
This commit is contained in:
parent
a69a285222
commit
82c464b426
@ -10,6 +10,7 @@ Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
|||||||
#include "2DStructs.h"
|
#include "2DStructs.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
|
||||||
|
typedef struct DrawTextArgs_ { String Text; FontDesc Font; bool UseShadow; } DrawTextArgs;
|
||||||
void DrawTextArgs_Make(DrawTextArgs* args, STRING_REF String* text, FontDesc* font, bool useShadow);
|
void DrawTextArgs_Make(DrawTextArgs* args, STRING_REF String* text, FontDesc* font, bool useShadow);
|
||||||
|
|
||||||
const float Offset = 1.3f;
|
const float Offset = 1.3f;
|
||||||
|
@ -101,7 +101,7 @@ void Gui_Reset(void) {
|
|||||||
|
|
||||||
void Gui_Free(void) {
|
void Gui_Free(void) {
|
||||||
Event_UnregisterStream(&TextureEvents_FileChanged, Gui_FileChanged);
|
Event_UnregisterStream(&TextureEvents_FileChanged, Gui_FileChanged);
|
||||||
Gui_SetScreen(NULL);
|
Gui_SetNewScreen(NULL);
|
||||||
Gui_Status->Base.Free(&Gui_Status->Base);
|
Gui_Status->Base.Free(&Gui_Status->Base);
|
||||||
|
|
||||||
if (Gui_Active != NULL) {
|
if (Gui_Active != NULL) {
|
||||||
@ -129,10 +129,11 @@ Screen* Gui_GetUnderlyingScreen(void) {
|
|||||||
return Gui_Active == NULL ? Gui_HUD : Gui_Active;
|
return Gui_Active == NULL ? Gui_HUD : Gui_Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui_SetScreen(Screen* screen) {
|
void Gui_SetScreen(Screen* screen, bool freeOld) {
|
||||||
game.Input.ScreenChanged(activeScreen, screen);
|
game.Input.ScreenChanged(Gui_Active, screen);
|
||||||
if (activeScreen != NULL && disposeOld)
|
if (Gui_Active != NULL && freeOld) {
|
||||||
activeScreen.Dispose();
|
Gui_Active->Base.Free(&Gui_Active->Base);
|
||||||
|
}
|
||||||
|
|
||||||
if (screen == NULL) {
|
if (screen == NULL) {
|
||||||
hudScreen.GainFocus();
|
hudScreen.GainFocus();
|
||||||
@ -146,6 +147,8 @@ void Gui_SetScreen(Screen* screen) {
|
|||||||
Gui_Active = screen;
|
Gui_Active = screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gui_SetNewScreen(Screen* screen) { Gui_SetScreen(screen, true); }
|
||||||
|
|
||||||
void Gui_RefreshHud(void) {
|
void Gui_RefreshHud(void) {
|
||||||
Gui_HUD->Base.Recreate(&Gui_HUD->Base);
|
Gui_HUD->Base.Recreate(&Gui_HUD->Base);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,8 @@ Screen* Gui_GetActiveScreen(void);
|
|||||||
/* Gets the non-overlay screen that the user is currently interacting with.
|
/* Gets the non-overlay screen that the user is currently interacting with.
|
||||||
This means if an overlay is active, it will return the screen under it. */
|
This means if an overlay is active, it will return the screen under it. */
|
||||||
Screen* Gui_GetUnderlyingScreen(void);
|
Screen* Gui_GetUnderlyingScreen(void);
|
||||||
void Gui_SetScreen(Screen* screen);
|
void Gui_SetScreen(Screen* screen, bool freeOld);
|
||||||
|
void Gui_SetNewScreen(Screen* screen);
|
||||||
void Gui_RefreshHud(void);
|
void Gui_RefreshHud(void);
|
||||||
void Gui_ShowOverlay(Screen* overlay);
|
void Gui_ShowOverlay(Screen* overlay);
|
||||||
void Gui_RenderGui(Real64 delta);
|
void Gui_RenderGui(Real64 delta);
|
||||||
|
@ -83,3 +83,6 @@ void ClickableScreen_Create(ClickableScreen* screen) {
|
|||||||
screen->LastX = -1; screen->LastY = -1;
|
screen->LastX = -1; screen->LastY = -1;
|
||||||
screen->OnWidgetSelected = ClickableScreen_DefaultWidgetSelected;
|
screen->OnWidgetSelected = ClickableScreen_DefaultWidgetSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Screen AA;
|
||||||
|
extern Screen* InventoryScreen_Unsafe_RawPointer = &AA;
|
||||||
|
@ -16,4 +16,6 @@ typedef struct ClickableScreen_ {
|
|||||||
} ClickableScreen;
|
} ClickableScreen;
|
||||||
void ClickableScreen_Create(ClickableScreen* screen);
|
void ClickableScreen_Create(ClickableScreen* screen);
|
||||||
|
|
||||||
|
/* Raw pointer to inventory screen. DO NOT USE THIS. Use InventoryScreen_GetInstance() */
|
||||||
|
extern Screen* InventoryScreen_Unsafe_RawPointer;
|
||||||
#endif
|
#endif
|
@ -46,7 +46,6 @@ typedef UInt8 Face;
|
|||||||
typedef UInt8 SkinType;
|
typedef UInt8 SkinType;
|
||||||
|
|
||||||
typedef struct FontDesc_ { void* Handle; UInt16 Size, Style; } FontDesc;
|
typedef struct FontDesc_ { void* Handle; UInt16 Size, Style; } FontDesc;
|
||||||
typedef struct DrawTextArgs_ { String Text; FontDesc Font; bool UseShadow; } DrawTextArgs;
|
|
||||||
|
|
||||||
#define UInt8_MaxValue ((UInt8)0xFF)
|
#define UInt8_MaxValue ((UInt8)0xFF)
|
||||||
#define Int16_MaxValue ((Int16)0x7FFF)
|
#define Int16_MaxValue ((Int16)0x7FFF)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "IsometricDrawer.h"
|
#include "IsometricDrawer.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "ModelCache.h"
|
#include "ModelCache.h"
|
||||||
|
#include "Screens.h"
|
||||||
|
|
||||||
void Widget_SetLocation(Widget* widget, Anchor horAnchor, Anchor verAnchor, Int32 xOffset, Int32 yOffset) {
|
void Widget_SetLocation(Widget* widget, Anchor horAnchor, Anchor verAnchor, Int32 xOffset, Int32 yOffset) {
|
||||||
widget->HorAnchor = horAnchor; widget->VerAnchor = verAnchor;
|
widget->HorAnchor = horAnchor; widget->VerAnchor = verAnchor;
|
||||||
@ -429,8 +430,8 @@ bool HotbarWidget_HandlesKeyUp(GuiElement* elem, Key key) {
|
|||||||
bool HotbarWidget_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
bool HotbarWidget_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||||
Widget* w = (Widget*)elem;
|
Widget* w = (Widget*)elem;
|
||||||
if (btn != MouseButton_Left || !Gui_Contains(w->X, w->Y, w->Width, w->Height, x, y)) return false;
|
if (btn != MouseButton_Left || !Gui_Contains(w->X, w->Y, w->Width, w->Height, x, y)) return false;
|
||||||
InventoryScreen screen = game.Gui.ActiveScreen as InventoryScreen;
|
Screen* screen = Gui_GetActiveScreen();
|
||||||
if (screen == null) return false;
|
if (screen != InventoryScreen_Unsafe_RawPointer) return false;
|
||||||
|
|
||||||
HotbarWidget* widget = (HotbarWidget*)elem;
|
HotbarWidget* widget = (HotbarWidget*)elem;
|
||||||
Int32 width = (Int32)(widget->ElemSize * widget->BorderSize);
|
Int32 width = (Int32)(widget->ElemSize * widget->BorderSize);
|
||||||
@ -834,3 +835,233 @@ void TableWidget_OnInventoryChanged(TableWidget* widget) {
|
|||||||
ScrollbarWidget_ClampScrollY(&widget->Scroll);
|
ScrollbarWidget_ClampScrollY(&widget->Scroll);
|
||||||
TableWidget_RecreateDescTex(widget);
|
TableWidget_RecreateDescTex(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpecialInputWidget_UpdateCols(SpecialInputWidget* widget) {
|
||||||
|
elements[0] = new SpecialInputTab("Colours", 10, 4, GetColourString());
|
||||||
|
Redraw();
|
||||||
|
SpecialInputWidget_SetActive(widget, widget->Base.Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active) {
|
||||||
|
widget->Base.Active = active;
|
||||||
|
widget->Base.Height = active ? widget->Tex.Height : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Redraw(SpecialInputWidget* widget) {
|
||||||
|
SpecialInputWidget_Make(widget, &widget->Tabs[widget->SelectedIndex]);
|
||||||
|
widget->Base.Width = widget->Tex.Width;
|
||||||
|
widget->Base.Height = widget->Tex.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Make(SpecialInputWidget* widget, SpecialInputTab* e) {
|
||||||
|
Size2D sizes = stackalloc Size[e.Contents.Length / e.CharsPerItem];
|
||||||
|
MeasureContentSizes(e, font, sizes);
|
||||||
|
Size2D bodySize = CalculateContentSize(e, sizes, out elementSize);
|
||||||
|
Int32 titleWidth = MeasureTitles(font);
|
||||||
|
Int32 titleHeight = widget->Tabs[0].TitleSize.Height;
|
||||||
|
Size2D size = Size2D_Make(max(bodySize.Width, titleWidth), bodySize.Height + titleHeight);
|
||||||
|
Gfx_DeleteTexture(&widget->Tex.ID);
|
||||||
|
|
||||||
|
Bitmap bmp;
|
||||||
|
Bitmap_AllocatePow2(&bmp, size.Width, size.Height);
|
||||||
|
Drawer2D_Begin(&bmp);
|
||||||
|
|
||||||
|
DrawTitles(drawer, font);
|
||||||
|
PackedCol col = PACKEDCOL_CONST(30, 30, 30, 200);
|
||||||
|
Drawer2D_Clear(col, 0, titleHeight, size.Width, bodySize.Height);
|
||||||
|
DrawContent(drawer, font, e, titleHeight);
|
||||||
|
texture = drawer.Make2DTexture(bmp, size, X, Y);
|
||||||
|
|
||||||
|
Drawer2D_End();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IntersectsHeader(int widgetX, int widgetY) {
|
||||||
|
Rectangle bounds = new Rectangle(0, 0, 0, 0);
|
||||||
|
for (int i = 0; i < elements.Length; i++) {
|
||||||
|
Size size = elements[i].TitleSize;
|
||||||
|
bounds.Width = size.Width; bounds.Height = size.Height;
|
||||||
|
if (bounds.Contains(widgetX, widgetY)) {
|
||||||
|
selectedIndex = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bounds.X += size.Width;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntersectsBody(int widgetX, int widgetY) {
|
||||||
|
widgetY -= elements[0].TitleSize.Height;
|
||||||
|
widgetX /= elementSize.Width; widgetY /= elementSize.Height;
|
||||||
|
SpecialInputTab e = elements[selectedIndex];
|
||||||
|
int index = widgetY * e.ItemsPerRow + widgetX;
|
||||||
|
if (index * e.CharsPerItem < e.Contents.Length) {
|
||||||
|
if (selectedIndex == 0) {
|
||||||
|
// TODO: need to insert characters that don't affect caret index, adjust caret colour
|
||||||
|
input.Append(e.Contents[index * e.CharsPerItem]);
|
||||||
|
input.Append(e.Contents[index * e.CharsPerItem + 1]);
|
||||||
|
} else {
|
||||||
|
input.Append(e.Contents[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpecialInputWidget_HandlesMouseClick(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||||
|
SpecialInputWidget* widget = (SpecialInputWidget*)elem;
|
||||||
|
x -= widget->Base.X; y -= widget->Base.Y;
|
||||||
|
|
||||||
|
if (IntersectsHeader(x, y)) {
|
||||||
|
Redraw();
|
||||||
|
} else {
|
||||||
|
IntersectsBody(x, y);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputTab_Init(SpecialInputTab* tab, STRING_REF String title,
|
||||||
|
Int32 itemsPerRow, Int32 charsPerItem, STRING_REF String contents) {
|
||||||
|
tab->Title = title;
|
||||||
|
tab->TitleSize = Size2D_Empty;
|
||||||
|
tab->Contents = contents;
|
||||||
|
tab->ItemsPerRow = itemsPerRow;
|
||||||
|
tab->CharsPerItem = charsPerItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_InitTabs(SpecialInputWidget* widget) {
|
||||||
|
String title_cols = String_FromConstant("Colours");
|
||||||
|
SpecialInputTab_Init(&widget->Tabs[0], &title_cols, 10, 4, GetColourString());
|
||||||
|
|
||||||
|
String title_math = String_FromConstant("Math");
|
||||||
|
String tab_math = String_FromConstant("\x9F\xAB\xAC\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xFB\xFC\xFD");
|
||||||
|
SpecialInputTab_Init(&widget->Tabs[1], &title_math, 16, 1, &tab_math);
|
||||||
|
|
||||||
|
String title_line = String_FromConstant("Line/Box");
|
||||||
|
String tab_line = String_FromConstant("\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFE");
|
||||||
|
SpecialInputTab_Init(&widget->Tabs[2], &title_line, 17, 1, &tab_line);
|
||||||
|
|
||||||
|
String title_letters = String_FromConstant("Letters");
|
||||||
|
String tab_letters = String_FromConstant("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\xA0\xA1\xA2\xA3\xA4\xA5");
|
||||||
|
SpecialInputTab_Init(&widget->Tabs[3], &title_letters, 17, 1, &tab_letters);
|
||||||
|
|
||||||
|
String title_other = String_FromConstant("Other");
|
||||||
|
String tab_other = String_FromConstant("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x9B\x9C\x9D\x9E\xA6\xA7\xA8\xA9\xAA\xAD\xAE\xAF\xF9\xFA");
|
||||||
|
SpecialInputTab_Init(&widget->Tabs[4], &title_other, 16, 1, &tab_other);
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetColourString() {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = ' '; i <= '~'; i++) {
|
||||||
|
if (i >= 'A' && i <= 'F') continue;
|
||||||
|
if (IDrawer2D.Cols[i].A > 0) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer(count * 4);
|
||||||
|
int index = 0;
|
||||||
|
for (int i = ' '; i <= '~'; i++) {
|
||||||
|
if (i >= 'A' && i <= 'F') continue;
|
||||||
|
if (IDrawer2D.Cols[i].A == 0) continue;
|
||||||
|
|
||||||
|
buffer.Append(ref index, '&').Append(ref index, (char)i)
|
||||||
|
.Append(ref index, '%').Append(ref index, (char)i);
|
||||||
|
}
|
||||||
|
return buffer.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpecialInputWidget_MeasureContentSizes(SpecialInputTab* e, FontDesc* font, Size2D* sizes) {
|
||||||
|
string s = new String('\0', e.CharsPerItem);
|
||||||
|
DrawTextArgs args;
|
||||||
|
DrawTextArgs_Make(&args, &s, font, false);
|
||||||
|
// avoid allocating temporary strings here
|
||||||
|
fixed(char* ptr = s) {
|
||||||
|
for (int i = 0; i < e.Contents.Length; i += e.CharsPerItem) {
|
||||||
|
for (int j = 0; j < e.CharsPerItem; j++)
|
||||||
|
ptr[j] = e.Contents[i + j];
|
||||||
|
sizes[i / e.CharsPerItem] = game.Drawer2D.MeasureSize(ref args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2D SpecialInputWidget_CalculateContentSize(SpecialInputTab* e, Size2D* sizes, Size2D* elemSize) {
|
||||||
|
*elemSize = Size2D_Empty;
|
||||||
|
Int32 i;
|
||||||
|
for (i = 0; i < e->Contents.length; i += e->CharsPerItem) {
|
||||||
|
elemSize->Width = max(elemSize->Width, sizes[i / e->CharsPerItem].Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
elemSize->Width += contentSpacing;
|
||||||
|
elemSize->Height = sizes[0].Height + contentSpacing;
|
||||||
|
Int32 rows = Math_CeilDiv(e->Contents.length / e->CharsPerItem, e->ItemsPerRow);
|
||||||
|
return Size2D_Make(elemSize->Width * e->ItemsPerRow, elemSize->Height * rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int titleSpacing = 10, contentSpacing = 5;
|
||||||
|
int MeasureTitles(Font font) {
|
||||||
|
int totalWidth = 0;
|
||||||
|
DrawTextArgs args = new DrawTextArgs(null, font, false);
|
||||||
|
for (int i = 0; i < elements.Length; i++) {
|
||||||
|
args.Text = elements[i].Title;
|
||||||
|
elements[i].TitleSize = game.Drawer2D.MeasureSize(ref args);
|
||||||
|
elements[i].TitleSize.Width += titleSpacing;
|
||||||
|
totalWidth += elements[i].TitleSize.Width;
|
||||||
|
}
|
||||||
|
return totalWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawTitles(IDrawer2D drawer, Font font) {
|
||||||
|
int x = 0;
|
||||||
|
DrawTextArgs args = new DrawTextArgs(null, font, false);
|
||||||
|
for (int i = 0; i < elements.Length; i++) {
|
||||||
|
args.Text = elements[i].Title;
|
||||||
|
FastColour col = i == selectedIndex ? new FastColour(30, 30, 30, 200) :
|
||||||
|
new FastColour(0, 0, 0, 127);
|
||||||
|
Size size = elements[i].TitleSize;
|
||||||
|
|
||||||
|
drawer.Clear(col, x, 0, size.Width, size.Height);
|
||||||
|
drawer.DrawText(ref args, x + titleSpacing / 2, 0);
|
||||||
|
x += size.Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawContent(IDrawer2D drawer, Font font, SpecialInputTab e, int yOffset) {
|
||||||
|
string s = new String('\0', e.CharsPerItem);
|
||||||
|
int wrap = e.ItemsPerRow;
|
||||||
|
DrawTextArgs args = new DrawTextArgs(s, font, false);
|
||||||
|
|
||||||
|
fixed(char* ptr = s) {
|
||||||
|
for (int i = 0; i < e.Contents.Length; i += e.CharsPerItem) {
|
||||||
|
for (int j = 0; j < e.CharsPerItem; j++)
|
||||||
|
ptr[j] = e.Contents[i + j];
|
||||||
|
int item = i / e.CharsPerItem;
|
||||||
|
|
||||||
|
int x = (item % wrap) * elementSize.Width, y = (item / wrap) * elementSize.Height;
|
||||||
|
y += yOffset;
|
||||||
|
drawer.DrawText(ref args, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Init(GuiElement* elem) {
|
||||||
|
SpecialInputWidget* widget = (SpecialInputWidget*)elem;
|
||||||
|
widget->Base.X = 5; widget->Base.Y = 5;
|
||||||
|
SpecialInputWidget_InitTabs(widget);
|
||||||
|
SpecialInputWidget_Redraw(widget);
|
||||||
|
SpecialInputWidget_SetActive(widget->Base.Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Render(GuiElement* elem, Real64 delta) {
|
||||||
|
SpecialInputWidget* widget = (SpecialInputWidget*)elem;
|
||||||
|
Texture_Render(&widget->Tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Free(GuiElement* elem) {
|
||||||
|
SpecialInputWidget* widget = (SpecialInputWidget*)elem;
|
||||||
|
Gfx_DeleteTexture(&widget->Tex.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpecialInputWidget_Create(SpecialInputWidget* widget, FontDesc* font, InputWidget input) {
|
||||||
|
Widget_Init(&widget->Base);
|
||||||
|
widget->Base.VerAnchor = ANCHOR_BOTTOM_OR_RIGHT;
|
||||||
|
widget->Font = *font;
|
||||||
|
widget->AppendFunc = input;
|
||||||
|
}
|
@ -102,17 +102,17 @@ void SpecialInputTab_Init(SpecialInputTab* tab, STRING_REF String* title,
|
|||||||
|
|
||||||
typedef struct SpecialInputWidget_ {
|
typedef struct SpecialInputWidget_ {
|
||||||
Widget Base;
|
Widget Base;
|
||||||
|
Size2D ElementSize;
|
||||||
|
Int32 SelectedIndex;
|
||||||
|
SpecialInputAppendFunc AppendFunc;
|
||||||
Texture Tex;
|
Texture Tex;
|
||||||
FontDesc Font;
|
FontDesc Font;
|
||||||
SpecialInputAppendFunc AppendFunc;
|
|
||||||
Size2D ElementSize;
|
|
||||||
SpecialInputTab Tabs[5];
|
SpecialInputTab Tabs[5];
|
||||||
} SpecialInputWidget;
|
} SpecialInputWidget;
|
||||||
|
|
||||||
void SpecialInputWidget_Create(SpecialInputWidget* widget, FontDesc* font, SpecialInputAppendFunc appendFunc);
|
void SpecialInputWidget_Create(SpecialInputWidget* widget, FontDesc* font, SpecialInputAppendFunc appendFunc);
|
||||||
void SpecialInputWidget_UpdateColours(SpecialInputWidget* widget);
|
void SpecialInputWidget_UpdateColours(SpecialInputWidget* widget);
|
||||||
void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active);
|
void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active);
|
||||||
void SpecialInputWidget_Redraw(SpecialInputWidget* widget);
|
|
||||||
|
|
||||||
|
|
||||||
#define INPUTWIDGET_MAX_LINES 4
|
#define INPUTWIDGET_MAX_LINES 4
|
||||||
|
@ -20,7 +20,7 @@ void ErrorHandler_Init(void) {
|
|||||||
/* TODO: Open log file */
|
/* TODO: Open log file */
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorHandler_Log(String msg) {
|
void ErrorHandler_Log(STRING_TRANSIENT String* msg) {
|
||||||
/* TODO: write to log file */
|
/* TODO: write to log file */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user