fix issues with sometimes being invisible when it should be visible, and vice versa

This commit is contained in:
UnknownShadow200 2018-08-09 19:31:58 +10:00
parent b72e5e3aaf
commit f15ee65018
25 changed files with 588 additions and 631 deletions

View File

@ -43,7 +43,7 @@ namespace ClassicalSharp.Gui {
public abstract class Screen : GuiElement {
public Screen(Game game) : base(game) { }
public bool HandlesAllInput, BlocksWorld, HidesHud, RenderHudOver;
public bool HandlesAllInput = true, BlocksWorld, HidesHud, RenderHudOver;
public abstract void OnResize();
protected abstract void ContextLost();

View File

@ -14,6 +14,7 @@ namespace ClassicalSharp.Gui.Screens {
public ChatScreen(Game game, HudScreen hud) : base(game) {
chatLines = game.ChatLines;
this.hud = hud;
HandlesAllInput = false;
}
HudScreen hud;
@ -275,7 +276,6 @@ namespace ClassicalSharp.Gui.Screens {
protected override void ContextLost() {
if (HandlesAllInput) {
chatInInputBuffer = input.Text.ToString();
game.CursorVisible = false;
} else {
chatInInputBuffer = null;
}
@ -330,7 +330,6 @@ namespace ClassicalSharp.Gui.Screens {
}
public void OpenInput(string initialText) {
game.CursorVisible = true;
suppressNextPress = true;
SetHandlesAllInput(true);
Keyboard.KeyRepeat = true;
@ -350,9 +349,6 @@ namespace ClassicalSharp.Gui.Screens {
if (HandlesAllInput) { // text input bar
if (key == game.Mapping(KeyBind.SendChat) || key == Key.KeypadEnter || key == game.Mapping(KeyBind.PauseOrExit)) {
SetHandlesAllInput(false);
// when underlying screen is HUD, user is interacting with the world normally
game.CursorVisible = game.Gui.UnderlyingScreen != game.Gui.hudScreen;
game.Camera.RegrabMouse();
Keyboard.KeyRepeat = false;
if (key == game.Mapping(KeyBind.PauseOrExit))
@ -466,6 +462,7 @@ namespace ClassicalSharp.Gui.Screens {
void SetHandlesAllInput(bool handles) {
HandlesAllInput = handles;
game.Gui.hudScreen.HandlesAllInput = handles;
game.Gui.CalcCursorVisible();
}
}
}

View File

@ -25,7 +25,6 @@ namespace ClassicalSharp.Gui.Screens {
messageFont = new Font(game.FontName, 16);
BlocksWorld = true;
HidesHud = true;
HandlesAllInput = true;
}
public override void Init() {

View File

@ -8,7 +8,9 @@ using OpenTK.Input;
namespace ClassicalSharp.Gui.Screens {
public class HudScreen : Screen, IGameComponent {
public HudScreen(Game game) : base(game) { }
public HudScreen(Game game) : base(game) {
HandlesAllInput = false;
}
ChatScreen chat;
internal Widget hotbar;

View File

@ -5,13 +5,24 @@ using ClassicalSharp.Gui.Widgets;
using OpenTK.Input;
namespace ClassicalSharp.Gui.Screens {
public partial class InventoryScreen : Screen {
public class InventoryScreen : Screen {
TableWidget table;
Font font;
bool deferredSelect;
public InventoryScreen(Game game) : base(game) {
font = new Font(game.FontName, 16);
HandlesAllInput = true;
}
void MoveToSelected() {
table.SetBlockTo(game.Inventory.Selected);
table.Recreate();
deferredSelect = false;
// User is holding invalid block
if (table.SelectedIndex == -1) {
table.MakeDescTex(game.Inventory.Selected);
}
}
public override void Init() {
@ -20,10 +31,10 @@ namespace ClassicalSharp.Gui.Screens {
table.ElementsPerRow = game.PureClassic ? 9 : 10;
table.Init();
// User is holding invalid block
if (table.SelectedIndex == -1) {
table.MakeDescTex(game.Inventory.Selected);
}
// Can't immediately move to selected here, because cursor visibility
// might be toggled after Init() is called. This causes the cursor to
// be moved back to the middle of the window.
deferredSelect = true;
game.Events.BlockPermissionsChanged += OnBlockChanged;
game.Events.BlockDefinitionChanged += OnBlockChanged;
@ -32,7 +43,10 @@ namespace ClassicalSharp.Gui.Screens {
game.Graphics.ContextRecreated += ContextRecreated;
}
public override void Render(double delta) { table.Render(delta); }
public override void Render(double delta) {
if (deferredSelect) MoveToSelected();
table.Render(delta);
}
public override void Dispose() {
font.Dispose();

View File

@ -21,7 +21,6 @@ namespace ClassicalSharp.Gui.Screens {
font = new Font(game.FontName, 16);
BlocksWorld = true;
RenderHudOver = true;
HandlesAllInput = true;
}
string title, message;

View File

@ -7,9 +7,7 @@ using OpenTK.Input;
namespace ClassicalSharp.Gui.Screens {
public abstract class ListScreen : ClickableScreen {
public ListScreen(Game game) : base(game) {
HandlesAllInput = true;
}
public ListScreen(Game game) : base(game) { }
protected Font font;
protected string[] entries;

View File

@ -6,9 +6,7 @@ using OpenTK.Input;
namespace ClassicalSharp.Gui.Screens {
public abstract class MenuScreen : ClickableScreen {
public MenuScreen(Game game) : base(game) {
HandlesAllInput = true;
}
public MenuScreen(Game game) : base(game) { }
protected Widget[] widgets;
protected Font titleFont, textFont;

View File

@ -19,6 +19,7 @@ namespace ClassicalSharp.Gui.Screens {
public StatusScreen(Game game) : base(game) {
statusBuffer = new StringBuffer(128);
HandlesAllInput = false;
}
void IGameComponent.Init(Game game) { }

View File

@ -106,8 +106,6 @@ namespace ClassicalSharp.Gui.Widgets {
scroll = new ScrollbarWidget(game);
RecreateElements();
Reposition();
SetBlockTo(game.Inventory.Selected);
Recreate();
}
public override void Dispose() {
@ -177,7 +175,7 @@ namespace ClassicalSharp.Gui.Widgets {
void MoveCursorToSelected() {
if (SelectedIndex == -1) return;
game.DesktopCursorPos = GetMouseCoords(SelectedIndex);
game.window.DesktopCursorPos = GetMouseCoords(SelectedIndex);
}
void UpdateBlockInfoString(BlockID block) {

View File

@ -97,15 +97,12 @@ namespace ClassicalSharp.Entities {
return m;
}
/// <summary> Gets the brightness colour of this entity. </summary>
public virtual PackedCol Colour() {
Vector3I P = Vector3I.Floor(EyePosition);
return game.World.IsValidPos(P) ? game.Lighting.LightCol(P.X, P.Y, P.Z) : game.Lighting.Outside;
}
/// <summary> Sets the model associated with this entity. </summary>
/// <param name="model"> Can be either 'name' or 'name'|'scale'. </param>
public void SetModel(string model) {
ModelScale = new Vector3(1.0f);
int sep = model.IndexOf('|');

View File

@ -205,30 +205,6 @@ namespace ClassicalSharp {
}
public INativeWindow window;
public int Width, Height;
public bool Focused { get { return window.Focused; } }
bool visible = true;
internal bool realVisible = true;
public bool CursorVisible {
get { return visible; }
set {
// Defer mouse visibility changes.
realVisible = value;
if (Gui.overlays.Count > 0) return;
// Only set the value when it has changes.
if (visible == value) return;
window.CursorVisible = value;
visible = value;
}
}
public Point DesktopCursorPos {
get { return window.DesktopCursorPos; }
set { window.DesktopCursorPos = value; }
}
}
}

View File

@ -306,7 +306,7 @@ namespace ClassicalSharp {
Vertices = 0;
Camera.UpdateMouse();
if (!Focused && !Gui.ActiveScreen.HandlesAllInput) {
if (!window.Focused && !Gui.ActiveScreen.HandlesAllInput) {
Gui.SetNewScreen(new PauseScreen(this));
}

View File

@ -84,41 +84,28 @@ namespace ClassicalSharp {
if (activeScreen != null && disposeOld)
activeScreen.Dispose();
if (screen == null) {
game.CursorVisible = false;
if (game.Focused) game.Camera.RegrabMouse();
} else if (activeScreen == null) {
game.CursorVisible = true;
}
if (screen != null)
screen.Init();
if (screen != null) screen.Init();
activeScreen = screen;
CalcCursorVisible();
}
public void RefreshHud() { hudScreen.Recreate(); }
public void ShowOverlay(Overlay overlay, bool inFront) {
bool cursorVis = game.CursorVisible;
if (overlays.Count == 0) game.CursorVisible = true;
if (inFront) {
overlays.Insert(0, overlay);
} else {
overlays.Add(overlay);
}
if (overlays.Count == 1) game.CursorVisible = cursorVis;
// Save cursor visibility state
overlay.Init();
CalcCursorVisible();
}
public void DisposeOverlay(Overlay overlay) {
overlay.Dispose();
overlays.Remove(overlay);
if (overlays.Count == 0)
game.CursorVisible = game.realVisible;
game.Camera.RegrabMouse();
CalcCursorVisible();
}
@ -144,5 +131,16 @@ namespace ClassicalSharp {
overlays[i].OnResize();
}
}
bool cursorVisible = true;
public void CalcCursorVisible() {
bool vis = ActiveScreen.HandlesAllInput;
if (vis == cursorVisible) return;
cursorVisible = vis;
game.window.CursorVisible = vis;
if (game.window.Focused)
game.Camera.RegrabMouse();
}
}
}

View File

@ -32,7 +32,7 @@ using OpenTK;
namespace OpenTK.Graphics.OpenGL {
[InteropPatch]
public unsafe static partial class GL {
public unsafe static class GL {
public static void AlphaFunc(Compare func, float value) {
Interop.Calli((int)func, value, AlphaFuncAddress);
@ -243,6 +243,83 @@ namespace OpenTK.Graphics.OpenGL {
public static void Viewport(int x, int y, int width, int height) {
Interop.Calli(x, y, width, height, ViewportAddress);
} static IntPtr ViewportAddress;
internal static void LoadEntryPoints(IGraphicsContext context) {
Debug.Print("Loading OpenGL function pointers... ");
AlphaFuncAddress = context.GetAddress("glAlphaFunc");
BeginAddress = context.GetAddress("glBegin");
BindBufferAddress = context.GetAddress("glBindBuffer");
BindBufferARBAddress = context.GetAddress("glBindBufferARB");
BindTextureAddress = context.GetAddress("glBindTexture");
BlendFuncAddress = context.GetAddress("glBlendFunc");
BufferDataAddress = context.GetAddress("glBufferData");
BufferDataARBAddress = context.GetAddress("glBufferDataARB");
BufferSubDataAddress = context.GetAddress("glBufferSubData");
BufferSubDataARBAddress = context.GetAddress("glBufferSubDataARB");
CallListAddress = context.GetAddress("glCallList");
ClearAddress = context.GetAddress("glClear");
ClearColorAddress = context.GetAddress("glClearColor");
Color4ubAddress = context.GetAddress("glColor4ub");
ColorMaskAddress = context.GetAddress("glColorMask");
ColorPointerAddress = context.GetAddress("glColorPointer");
CullFaceAddress = context.GetAddress("glCullFace");
DeleteBuffersAddress = context.GetAddress("glDeleteBuffers");
DeleteBuffersARBAddress = context.GetAddress("glDeleteBuffersARB");
DeleteListsAddress = context.GetAddress("glDeleteLists");
DeleteTexturesAddress = context.GetAddress("glDeleteTextures");
DepthFuncAddress = context.GetAddress("glDepthFunc");
DepthMaskAddress = context.GetAddress("glDepthMask");
DisableAddress = context.GetAddress("glDisable");
DisableClientStateAddress = context.GetAddress("glDisableClientState");
DrawArraysAddress = context.GetAddress("glDrawArrays");
DrawElementsAddress = context.GetAddress("glDrawElements");
EnableAddress = context.GetAddress("glEnable");
EnableClientStateAddress = context.GetAddress("glEnableClientState");
EndAddress = context.GetAddress("glEnd");
EndListAddress = context.GetAddress("glEndList");
FogfAddress = context.GetAddress("glFogf");
FogfvAddress = context.GetAddress("glFogfv");
FogiAddress = context.GetAddress("glFogi");
GenBuffersAddress = context.GetAddress("glGenBuffers");
GenBuffersARBAddress = context.GetAddress("glGenBuffersARB");
GenListsAddress = context.GetAddress("glGenLists");
GenTexturesAddress = context.GetAddress("glGenTextures");
GetErrorAddress = context.GetAddress("glGetError");
GetIntegervAddress = context.GetAddress("glGetIntegerv");
GetStringAddress = context.GetAddress("glGetString");
GetTexImageAddress = context.GetAddress("glGetTexImage");
HintAddress = context.GetAddress("glHint");
LoadIdentityAddress = context.GetAddress("glLoadIdentity");
LoadMatrixfAddress = context.GetAddress("glLoadMatrixf");
MatrixModeAddress = context.GetAddress("glMatrixMode");
MultMatrixfAddress = context.GetAddress("glMultMatrixf");
NewListAddress = context.GetAddress("glNewList");
ReadPixelsAddress = context.GetAddress("glReadPixels");
TexCoord2fAddress = context.GetAddress("glTexCoord2f");
TexCoordPointerAddress = context.GetAddress("glTexCoordPointer");
TexImage2DAddress = context.GetAddress("glTexImage2D");
TexParameteriAddress = context.GetAddress("glTexParameteri");
TexSubImage2DAddress = context.GetAddress("glTexSubImage2D");
Vertex3fAddress = context.GetAddress("glVertex3f");
VertexPointerAddress = context.GetAddress("glVertexPointer");
ViewportAddress = context.GetAddress("glViewport");
}
public static void UseArbVboAddresses() {
BindBufferAddress = BindBufferARBAddress;
BufferDataAddress = BufferDataARBAddress;
BufferSubDataAddress = BufferSubDataARBAddress;
DeleteBuffersAddress = DeleteBuffersARBAddress;
GenBuffersAddress = GenBuffersARBAddress;
}
}
public enum ArrayCap : int {
@ -418,83 +495,5 @@ namespace OpenTK.Graphics.OpenGL {
public enum TextureTarget : int {
Texture2D = 0x0DE1,
}
public unsafe static partial class GL {
internal static void LoadEntryPoints(IGraphicsContext context) {
Debug.Print("Loading OpenGL function pointers... ");
AlphaFuncAddress = context.GetAddress("glAlphaFunc");
BeginAddress = context.GetAddress("glBegin");
BindBufferAddress = context.GetAddress("glBindBuffer");
BindBufferARBAddress = context.GetAddress("glBindBufferARB");
BindTextureAddress = context.GetAddress("glBindTexture");
BlendFuncAddress = context.GetAddress("glBlendFunc");
BufferDataAddress = context.GetAddress("glBufferData");
BufferDataARBAddress = context.GetAddress("glBufferDataARB");
BufferSubDataAddress = context.GetAddress("glBufferSubData");
BufferSubDataARBAddress = context.GetAddress("glBufferSubDataARB");
CallListAddress = context.GetAddress("glCallList");
ClearAddress = context.GetAddress("glClear");
ClearColorAddress = context.GetAddress("glClearColor");
Color4ubAddress = context.GetAddress("glColor4ub");
ColorMaskAddress = context.GetAddress("glColorMask");
ColorPointerAddress = context.GetAddress("glColorPointer");
CullFaceAddress = context.GetAddress("glCullFace");
DeleteBuffersAddress = context.GetAddress("glDeleteBuffers");
DeleteBuffersARBAddress = context.GetAddress("glDeleteBuffersARB");
DeleteListsAddress = context.GetAddress("glDeleteLists");
DeleteTexturesAddress = context.GetAddress("glDeleteTextures");
DepthFuncAddress = context.GetAddress("glDepthFunc");
DepthMaskAddress = context.GetAddress("glDepthMask");
DisableAddress = context.GetAddress("glDisable");
DisableClientStateAddress = context.GetAddress("glDisableClientState");
DrawArraysAddress = context.GetAddress("glDrawArrays");
DrawElementsAddress = context.GetAddress("glDrawElements");
EnableAddress = context.GetAddress("glEnable");
EnableClientStateAddress = context.GetAddress("glEnableClientState");
EndAddress = context.GetAddress("glEnd");
EndListAddress = context.GetAddress("glEndList");
FogfAddress = context.GetAddress("glFogf");
FogfvAddress = context.GetAddress("glFogfv");
FogiAddress = context.GetAddress("glFogi");
GenBuffersAddress = context.GetAddress("glGenBuffers");
GenBuffersARBAddress = context.GetAddress("glGenBuffersARB");
GenListsAddress = context.GetAddress("glGenLists");
GenTexturesAddress = context.GetAddress("glGenTextures");
GetErrorAddress = context.GetAddress("glGetError");
GetIntegervAddress = context.GetAddress("glGetIntegerv");
GetStringAddress = context.GetAddress("glGetString");
GetTexImageAddress = context.GetAddress("glGetTexImage");
HintAddress = context.GetAddress("glHint");
LoadIdentityAddress = context.GetAddress("glLoadIdentity");
LoadMatrixfAddress = context.GetAddress("glLoadMatrixf");
MatrixModeAddress = context.GetAddress("glMatrixMode");
MultMatrixfAddress = context.GetAddress("glMultMatrixf");
NewListAddress = context.GetAddress("glNewList");
ReadPixelsAddress = context.GetAddress("glReadPixels");
TexCoord2fAddress = context.GetAddress("glTexCoord2f");
TexCoordPointerAddress = context.GetAddress("glTexCoordPointer");
TexImage2DAddress = context.GetAddress("glTexImage2D");
TexParameteriAddress = context.GetAddress("glTexParameteri");
TexSubImage2DAddress = context.GetAddress("glTexSubImage2D");
Vertex3fAddress = context.GetAddress("glVertex3f");
VertexPointerAddress = context.GetAddress("glVertexPointer");
ViewportAddress = context.GetAddress("glViewport");
}
public static void UseArbVboAddresses() {
BindBufferAddress = BindBufferARBAddress;
BufferDataAddress = BufferDataARBAddress;
BufferSubDataAddress = BufferSubDataARBAddress;
DeleteBuffersAddress = DeleteBuffersARBAddress;
GenBuffersAddress = GenBuffersARBAddress;
}
}
}
#endif

View File

@ -25,7 +25,6 @@ namespace ClassicalSharp.Network.Protocols {
byte[] mapSize = new byte[4], map;
FixedBufferStream mapPartStream;
Screen prevScreen;
bool prevCursorVisible;
public override void Reset() {
if (mapPartStream == null) mapPartStream = new FixedBufferStream(net.reader.buffer);
@ -95,9 +94,7 @@ namespace ClassicalSharp.Network.Protocols {
game.WorldEvents.RaiseOnNewMap();
prevScreen = game.Gui.activeScreen;
if (prevScreen is LoadingScreen)
prevScreen = null;
prevCursorVisible = game.CursorVisible;
if (prevScreen is LoadingScreen) prevScreen = null;
game.Gui.SetNewScreen(new LoadingScreen(game, net.ServerName, net.ServerMotd), false);
net.wom.CheckMotd();
@ -177,9 +174,7 @@ namespace ClassicalSharp.Network.Protocols {
void HandleLevelFinalise() {
game.Gui.SetNewScreen(null);
game.Gui.activeScreen = prevScreen;
if (prevScreen != null && prevCursorVisible != game.CursorVisible) {
game.CursorVisible = prevCursorVisible;
}
game.Gui.CalcCursorVisible();
prevScreen = null;
int mapWidth = reader.ReadUInt16();

View File

@ -67,9 +67,9 @@ namespace ClassicalSharp {
int cenX = topLeft.X + game.Width / 2;
int cenY = topLeft.Y + game.Height / 2;
game.DesktopCursorPos = new Point(cenX, cenY);
game.window.DesktopCursorPos = new Point(cenX, cenY);
// Fixes issues with large DPI displays on Windows >= 8.0.
previous = game.DesktopCursorPos;
previous = game.window.DesktopCursorPos;
}
public override void RegrabMouse() {
@ -127,8 +127,8 @@ namespace ClassicalSharp {
public override void UpdateMouse() {
if (game.Gui.ActiveScreen.HandlesAllInput) {
delta = Point.Empty;
} else if (game.Focused) {
Point pos = game.DesktopCursorPos;
} else if (game.window.Focused) {
Point pos = game.window.DesktopCursorPos;
delta = new Point(pos.X - previous.X, pos.Y - previous.Y);
CentreMousePosition();
}

View File

@ -120,21 +120,6 @@ void Game_SetDefaultTexturePack(STRING_PURE String* texPack) {
Options_Set(OPT_DEFAULT_TEX_PACK, texPack);
}
bool game_CursorVisible = true, game_realCursorVisible = true;
bool Game_GetCursorVisible(void) { return game_CursorVisible; }
bool Game_GetRealCursorVisible(void) { return game_realCursorVisible; }
void Game_SetCursorVisible(bool visible) {
/* Defer mouse visibility changes */
game_realCursorVisible = visible;
if (Gui_OverlaysCount > 0) return;
/* Only set the value when it has changed */
if (game_CursorVisible == visible) return;
Window_SetCursorVisible(visible);
game_CursorVisible = visible;
}
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas) {
String terrain = String_FromConst("terrain.png");
if (!Game_ValidateBitmap(&terrain, atlas)) return false;

View File

@ -76,9 +76,6 @@ Real32 Game_GetChatScale(void);
void Game_GetDefaultTexturePack(STRING_TRANSIENT String* texPack);
void Game_SetDefaultTexturePack(STRING_PURE String* texPack);
bool Game_GetCursorVisible(void);
bool Game_GetRealCursorVisible(void);
void Game_SetCursorVisible(bool visible);
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas);
void Game_SetViewDistance(Int32 distance, bool userDist);

View File

@ -42,7 +42,7 @@ void GuiElement_Reset(struct GuiElem* elem) {
void Screen_Reset(struct Screen* screen) {
GuiElement_Reset((struct GuiElem*)screen);
screen->HandlesAllInput = false;
screen->HandlesAllInput = true;
screen->BlocksWorld = false;
screen->HidesHUD = false;
screen->RenderHUDOver = false;
@ -147,16 +147,10 @@ void Gui_FreeActive(void) {
void Gui_SetActive(struct Screen* screen) {
InputHandler_ScreenChanged(Gui_Active, screen);
if (!screen) {
Game_SetCursorVisible(false);
if (Window_Focused) { Camera_Active->RegrabMouse(); }
} else if (!Gui_Active) {
Game_SetCursorVisible(true);
}
if (screen) { Elem_Init(screen); }
Gui_Active = screen;
Gui_CalcCursorVisible();
}
void Gui_RefreshHud(void) { Elem_Recreate(Gui_HUD); }
@ -164,8 +158,6 @@ void Gui_ShowOverlay(struct Screen* overlay, bool atFront) {
if (Gui_OverlaysCount == GUI_MAX_OVERLAYS) {
ErrorHandler_Fail("Cannot have more than 6 overlays");
}
bool visible = Game_GetCursorVisible();
if (!Gui_OverlaysCount) Game_SetCursorVisible(true);
if (atFront) {
Int32 i;
@ -179,8 +171,8 @@ void Gui_ShowOverlay(struct Screen* overlay, bool atFront) {
}
Gui_OverlaysCount++;
if (Gui_OverlaysCount == 1) Game_SetCursorVisible(visible); /* Save cursor visibility state */
Elem_Init(overlay);
Gui_CalcCursorVisible();
}
Int32 Gui_IndexOverlay(struct Screen* overlay) {
@ -202,9 +194,7 @@ void Gui_FreeOverlay(struct Screen* overlay) {
Gui_OverlaysCount--;
Gui_Overlays[Gui_OverlaysCount] = NULL;
if (!Gui_OverlaysCount) { Game_SetCursorVisible(Game_GetRealCursorVisible()); }
Camera_Active->RegrabMouse();
Gui_CalcCursorVisible();
}
void Gui_RenderGui(Real64 delta) {
@ -233,6 +223,17 @@ void Gui_OnResize(void) {
}
}
bool gui_cursorVisible = true;
void Gui_CalcCursorVisible(void) {
bool vis = Gui_GetActiveScreen()->HandlesAllInput;
if (vis == gui_cursorVisible) return;
gui_cursorVisible = vis;
Window_SetCursorVisible(vis);
if (Window_Focused)
Camera_Active->RegrabMouse();
}
void TextAtlas_Make(struct TextAtlas* atlas, STRING_PURE String* chars, struct FontDesc* font, STRING_PURE String* prefix) {
struct DrawTextArgs args; DrawTextArgs_Make(&args, prefix, font, true);

View File

@ -87,7 +87,7 @@ Int32 Gui_IndexOverlay(struct Screen* overlay);
void Gui_FreeOverlay(struct Screen* overlay);
void Gui_RenderGui(Real64 delta);
void Gui_OnResize(void);
void Gui_CalcCursorVisible(void);
#define TEXTATLAS_MAX_WIDTHS 16
struct TextAtlas {

View File

@ -523,7 +523,6 @@ struct ListScreen* ListScreen_MakeInstance(void) {
screen->VTABLE->Init = ListScreen_Init;
screen->VTABLE->Render = ListScreen_Render;
screen->VTABLE->Free = ListScreen_Free;
screen->HandlesAllInput = true;
return screen;
}
@ -622,7 +621,6 @@ static void MenuScreen_MakeInstance(struct MenuScreen* screen, struct Widget** w
screen->VTABLE->Render = MenuScreen_Render;
screen->VTABLE->Free = MenuScreen_Free;
screen->HandlesAllInput = true;
screen->Widgets = widgets;
screen->WidgetsCount = count;
screen->ContextLost = MenuScreen_ContextLost;

View File

@ -312,7 +312,7 @@ UInt8 mapSize[4];
UInt8* map;
struct Stream mapPartStream;
struct Screen* prevScreen;
bool prevCursorVisible, receivedFirstPosition;
bool receivedFirstPosition;
void Classic_WriteChat(struct Stream* stream, STRING_PURE String* text, bool partial) {
Int32 payload = !ServerConnection_SupportsPartialMessages ? ENTITIES_SELF_ID : (partial ? 1 : 0);
@ -385,7 +385,6 @@ static void Classic_StartLoading(struct Stream* stream) {
Gui_FreeActive();
prevScreen = NULL;
}
prevCursorVisible = Game_GetCursorVisible();
Gui_SetActive(LoadingScreen_MakeInstance(&ServerConnection_ServerName, &ServerConnection_ServerMOTD));
WoM_CheckMotd();
@ -458,10 +457,8 @@ static void Classic_LevelDataChunk(struct Stream* stream) {
static void Classic_LevelFinalise(struct Stream* stream) {
Gui_ReplaceActive(NULL);
Gui_Active = prevScreen;
if (prevScreen && prevCursorVisible != Game_GetCursorVisible()) {
Game_SetCursorVisible(prevCursorVisible);
}
prevScreen = NULL;
Gui_CalcCursorVisible();
Int32 mapWidth = Stream_ReadU16_BE(stream);
Int32 mapHeight = Stream_ReadU16_BE(stream);

View File

@ -25,7 +25,7 @@ struct InventoryScreen {
Screen_Layout
struct FontDesc Font;
struct TableWidget Table;
bool ReleasedInv;
bool ReleasedInv, DeferredSelect;
};
struct StatusScreen {
@ -126,6 +126,18 @@ static void InventoryScreen_ContextRecreated(void* obj) {
Elem_Recreate(&screen->Table);
}
static void InventoryScreen_MoveToSelected(struct InventoryScreen* screen) {
struct TableWidget* table = &screen->Table;
TableWidget_SetBlockTo(table, Inventory_SelectedBlock);
Elem_Recreate(table);
screen->DeferredSelect = false;
/* User is holding invalid block */
if (table->SelectedIndex == -1) {
TableWidget_MakeDescTex(table, Inventory_SelectedBlock);
}
}
static void InventoryScreen_Init(struct GuiElem* elem) {
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
Font_Make(&screen->Font, &Game_FontName, 16, FONT_STYLE_NORMAL);
@ -135,10 +147,10 @@ static void InventoryScreen_Init(struct GuiElem* elem) {
screen->Table.ElementsPerRow = Game_PureClassic ? 9 : 10;
Elem_Init(&screen->Table);
/* User is holding invalid block */
if (screen->Table.SelectedIndex == -1) {
TableWidget_MakeDescTex(&screen->Table, Inventory_SelectedBlock);
}
/* Can't immediately move to selected here, because cursor visibility
might be toggled after Init() is called. This causes the cursor to
be moved back to the middle of the window. */
screen->DeferredSelect = true;
Key_KeyRepeat = true;
Event_RegisterVoid(&BlockEvents_PermissionsChanged, screen, InventoryScreen_OnBlockChanged);
@ -149,6 +161,7 @@ static void InventoryScreen_Init(struct GuiElem* elem) {
static void InventoryScreen_Render(struct GuiElem* elem, Real64 delta) {
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
if (screen->DeferredSelect) InventoryScreen_MoveToSelected(screen);
Elem_Render(&screen->Table, delta);
}
@ -238,7 +251,6 @@ struct Screen* InventoryScreen_MakeInstance(void) {
Mem_Set(screen, 0, sizeof(struct InventoryScreen));
screen->VTABLE = &InventoryScreen_VTABLE;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = true;
screen->VTABLE->HandlesKeyDown = InventoryScreen_HandlesKeyDown;
screen->VTABLE->HandlesKeyUp = InventoryScreen_HandlesKeyUp;
@ -424,6 +436,7 @@ struct Screen* StatusScreen_MakeInstance(void) {
Mem_Set(screen, 0, sizeof(struct StatusScreen));
screen->VTABLE = &StatusScreen_VTABLE;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = false;
screen->OnResize = StatusScreen_OnResize;
screen->VTABLE->Init = StatusScreen_Init;
@ -592,7 +605,6 @@ static void LoadingScreen_Make(struct LoadingScreen* screen, struct GuiElementVT
Mem_Set(screen, 0, sizeof(struct LoadingScreen));
screen->VTABLE = vtable;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = true;
screen->VTABLE->HandlesKeyDown = LoadingScreen_HandlesKeyDown;
screen->VTABLE->HandlesKeyPress = LoadingScreen_HandlesKeyPress;
@ -721,10 +733,10 @@ static void ChatScreen_UpdateAltTextY(struct ChatScreen* screen) {
static void ChatScreen_SetHandlesAllInput(struct ChatScreen* screen, bool handles) {
screen->HandlesAllInput = handles;
Gui_HUD->HandlesAllInput = handles;
Gui_CalcCursorVisible();
}
static void ChatScreen_OpenInput(struct ChatScreen* screen, STRING_PURE String* initialText) {
Game_SetCursorVisible(true);
screen->SuppressNextPress = true;
ChatScreen_SetHandlesAllInput(screen, true);
Key_KeyRepeat = true;
@ -908,9 +920,6 @@ static bool ChatScreen_HandlesKeyDown(struct GuiElem* elem, Key key) {
if (screen->HandlesAllInput) { /* text input bar */
if (key == KeyBind_Get(KeyBind_SendChat) || key == Key_KeypadEnter || key == KeyBind_Get(KeyBind_PauseOrExit)) {
ChatScreen_SetHandlesAllInput(screen, false);
/* when underlying screen is HUD, user is interacting with the world normally */
Game_SetCursorVisible(Gui_GetUnderlyingScreen() != Gui_HUD);
Camera_Active->RegrabMouse();
Key_KeyRepeat = false;
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {
@ -1064,7 +1073,7 @@ static void ChatScreen_ContextLost(void* obj) {
if (screen->HandlesAllInput) {
String_AppendString(&chatInInput, &screen->Input.Base.Text);
Game_SetCursorVisible(false);
Gui_CalcCursorVisible();
}
Elem_TryFree(&screen->Chat);
@ -1181,6 +1190,7 @@ struct Screen* ChatScreen_MakeInstance(void) {
Mem_Set(screen, 0, sizeof(struct ChatScreen));
screen->VTABLE = &ChatScreen_VTABLE;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = false;
screen->InputOldHeight = -1;
screen->LastDownloadStatus = Int32_MinValue;
@ -1378,6 +1388,7 @@ struct Screen* HUDScreen_MakeInstance(void) {
Mem_Set(screen, 0, sizeof(struct HUDScreen));
screen->VTABLE = &HUDScreenVTABLE;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = false;
screen->OnResize = HUDScreen_OnResize;
screen->VTABLE->Init = HUDScreen_Init;
@ -1577,7 +1588,6 @@ struct Screen* DisconnectScreen_MakeInstance(STRING_PURE String* title, STRING_P
Mem_Set(screen, 0, sizeof(struct DisconnectScreen));
screen->VTABLE = &DisconnectScreen_VTABLE;
Screen_Reset((struct Screen*)screen);
screen->HandlesAllInput = true;
String titleScreen = String_InitAndClearArray(screen->TitleBuffer);
String_AppendString(&titleScreen, title);

View File

@ -658,8 +658,6 @@ static void TableWidget_Init(struct GuiElem* elem) {
ScrollbarWidget_Create(&widget->Scroll);
TableWidget_RecreateElements(widget);
Widget_Reposition(widget);
TableWidget_SetBlockTo(widget, Inventory_SelectedBlock);
Elem_Recreate(widget);
}
static void TableWidget_Render(struct GuiElem* elem, Real64 delta) {