@@ -15,109 +15,106 @@ using namespace Variables::Visual::LevelSelection;
15
15
16
16
namespace States {
17
17
18
- void WorldSelectionState::onInit (Context &context) {
19
- auto saves = Util::FileSystem ().getFilenamesInDirectory (levelDirectory);
20
- saves.erase (std::remove_if (saves.begin (), saves.end (), [](const std::string &v) {
21
- constexpr std::string_view extension = LEVEL_EXTENSION;
22
- const auto canFit = extension.size () <= v.size ();
23
- const auto matchesEnd = std::equal (v.begin () + v.size () - extension.size (), v.end (), extension.begin ());
24
- return !(canFit && matchesEnd);
25
- }), saves.end ());
26
-
27
- std::copy_n (saves.begin (), std::min (levels.size (), saves.size ()), levels.begin ());
28
-
29
- renderDevice = Renderer::Graphics::OpenGL::OGLRenderDevice::getRenderDevice ();
30
- renderDevice->setClearColour (1 .f , 1 .f , 1 .f , 1 .f );
31
-
32
- makeButtons (context);
33
- }
34
-
35
- void WorldSelectionState::makeButtons (Context &context) {
36
- constexpr auto width = (2 - OUTER_MARGIN * 2 ) / COLUMNS - GRID_MARGIN;
37
- constexpr auto height = (1 .5f - OUTER_MARGIN * 2 ) / ROWS - GRID_MARGIN;
38
-
39
- Menu::MenuBuilder menuBuilder;
40
- menuBuilder.addControl (-0 .5f , 0.5 , 1 , 0.24 , Sprites::GAME_OVER);
41
- // TODO: Make a uniform GUI design with a standard location for this button.
42
- menuBuilder.addControl (-0 .9f , 0.8 , 0.3 , 0.1 , Sprites::BACK, [&context]() {
43
- context.stateMachine ->setState <MainMenuState>(context);
44
- });
45
-
46
-
47
- const auto pageCount = std::ceil (1.0 * levels.size () / pageSize) + 1 ;
48
- const auto pageStr = fmt::format (" {:^25}" , fmt::format (" {} / {}" , currentPage + 1 ,
49
- pageCount));
50
- menuBuilder.addTextControl (-.25f , -.95f , 0 .001f , Math::Vector3f (0 , 0 , 0 ), pageStr);
51
-
52
- if (currentPage > 0 ) {
53
- menuBuilder.addControl (-0 .4f , -.95f , 0.1 , 0.1 , Sprites::LEVEL_SLOT_FILLED, [&]() {
54
- currentPage -= 1 ;
55
- makeButtons (context);
56
- });
57
- } else {
58
- menuBuilder.addControl (-0 .4f , -.95f , 0.1 , 0.1 , Sprites::LEVEL_SLOT_EMPTY);
59
- }
60
-
61
- if (currentPage < pageCount - 1 ) {
62
- menuBuilder.addControl (0 .3f , -.95f , 0.1 , 0.1 , Sprites::LEVEL_SLOT_FILLED, [&]() {
63
- currentPage += 1 ;
64
- makeButtons (context);
65
- });
66
- } else {
67
- menuBuilder.addControl (0 .3f , -.95f , 0.1 , 0.1 , Sprites::LEVEL_SLOT_EMPTY);
68
- }
69
-
70
-
71
- const int pageOffset = currentPage * COLUMNS * ROWS;
72
- // TODO: Draw these from top-left to bottom-right
73
- for (int r = 0 ; r < ROWS; ++r) {
74
- for (int c = 0 ; c < COLUMNS; ++c) {
75
- const auto levelIndex = pageOffset + r * ROWS + c;
76
-
77
- const auto x = -1 + OUTER_MARGIN + c * (width + GRID_MARGIN);// + -.045 * r;
78
- const auto y = -1 + OUTER_MARGIN + (ROWS - 1 - r) * (height + GRID_MARGIN);
79
-
80
- // TODO: Use proper button images
81
- // TODO: Show the level names
82
- if (levels.size () > levelIndex) {
83
- const auto levelName = levels[levelIndex];
84
- const auto path = levelDirectory + ' /' + levelName;
85
- const auto readableLevelName = levelName.substr (0 , levelName.find (" .json" ));
86
- menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_FILLED, [&context, path]() {
87
- if (context.stateMachine ->hasState <PrismGame>()) {
88
- context.stateMachine ->removeState <PrismGame>();
89
- }
90
- context.stateMachine ->addState <PrismGame>(context, path);
91
- context.stateMachine ->setState <PrismGame>(context);
92
- });
93
- menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_FILLED);
94
- menuBuilder.addTextControl (x + .03f , y + height / 2 , 0.001 , Math::Vector3f (1 , 1 , 1 ),
95
- fmt::format (" {:^13}" , readableLevelName));
96
- } else {
97
- menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_EMPTY);
98
-
99
- menuBuilder.addControl (x + .025f , y + height / 4 + .09f , width - 0 .05f , .11 ,
100
- Sprites::WHITE_BORDERED);
101
-
102
- menuBuilder.addTextControl (x + .05f , y + height / 2 , 0.001 , Math::Vector3f (0 , 0 , 0 ), " Empty Slot" );
103
- }
104
-
105
- }
106
- }
107
- menu = menuBuilder.buildMenu ();
108
- }
109
-
110
- void WorldSelectionState::onUpdate (Context &context) {
111
- // TODO: Move this generic code to shared function or superclass.
112
- renderDevice->clearScreen ();
113
- menuRenderer.renderMenu (*menu, float (context.window ->width ) / float (context.window ->height ));
114
-
115
- auto input = context.inputManager ;
116
- if (menu->handleInput (*context.inputManager , context.window ->width , context.window ->height )) {
117
- return ;
118
- }
119
-
120
- context.window ->swapScreen ();
121
- }
18
+ void WorldSelectionState::onInit (Context &context) {
19
+ levels = Util::FileSystem ().getFilenamesInDirectory (levelDirectory);
20
+ levels.erase (std::remove_if (levels.begin (), levels.end (), [](const std::string &v) {
21
+ constexpr std::string_view extension = LEVEL_EXTENSION;
22
+ const auto canFit = extension.size () <= v.size ();
23
+ const auto matchesEnd = std::equal (v.begin () + v.size () - extension.size (), v.end (), extension.begin ());
24
+ return !(canFit && matchesEnd);
25
+ }), levels.end ());
26
+
27
+ renderDevice = Renderer::Graphics::OpenGL::OGLRenderDevice::getRenderDevice ();
28
+ renderDevice->setClearColour (1 .f , 1 .f , 1 .f , 1 .f );
29
+
30
+ makeButtons (context);
31
+ }
32
+
33
+ void WorldSelectionState::makeButtons (Context &context) {
34
+ constexpr auto width{(2 - OUTER_MARGIN * 2 ) / COLUMNS - GRID_MARGIN};
35
+ constexpr auto height{(1 .5f - OUTER_MARGIN * 2 ) / ROWS - GRID_MARGIN};
36
+
37
+ Menu::MenuBuilder menuBuilder;
38
+ menuBuilder.addControl (-0 .5f , 0.5 , 1 , 0.24 , Sprites::GAME_OVER);
39
+ // TODO: Make a uniform GUI design with a standard location for this button.
40
+ menuBuilder.addControl (-0 .9f , 0.8 , 0.3 , 0.1 , Sprites::BACK, [&context]() {
41
+ context.stateMachine ->setState <MainMenuState>(context);
42
+ });
43
+
44
+ const auto pageCount{std::ceil (1.0 * levels.size () / pageSize) + 1 };
45
+ const auto pageStr{fmt::format (" {: ^7}" , fmt::format (" {} / {}" , currentPage + 1 , pageCount))};
46
+ menuBuilder.addTextControl (-.08f , -.95f , 0 .001f , Math::Vector3f (0 , 0 , 0 ), pageStr);
47
+
48
+ if (currentPage > 0 ) {
49
+ menuBuilder.addControl (-0 .32f , -.95f , 0.05 , 0.080 , Sprites::PREVIOUS_BUTTON, [&]() {
50
+ currentPage -= 1 ;
51
+ makeButtons (context);
52
+ });
53
+ } else {
54
+ menuBuilder.addControl (-0 .32f , -.95f , 0.05 , 0.080 , Sprites::PREVIOUS_BUTTON_DISABLED);
55
+ }
56
+
57
+ if (currentPage < pageCount - 1 ) {
58
+ menuBuilder.addControl (0 .24f , -.95f , 0.05 , 0.080 , Sprites::NEXT_BUTTON, [&]() {
59
+ currentPage += 1 ;
60
+ makeButtons (context);
61
+ });
62
+ } else {
63
+ menuBuilder.addControl (0 .24f , -.95f , 0.05 , 0.080 , Sprites::NEXT_BUTTON_DISABLED);
64
+ }
65
+
66
+
67
+ const int pageOffset{currentPage * COLUMNS * ROWS};
68
+ // TODO: Draw these from top-left to bottom-right
69
+ for (int r{0 }; r < ROWS; ++r) {
70
+ for (int c = 0 ; c < COLUMNS; ++c) {
71
+ const auto levelIndex = pageOffset + r * COLUMNS + c;
72
+
73
+ const auto x{-1 + OUTER_MARGIN + c * (width + GRID_MARGIN)};
74
+ const auto y{-1 + OUTER_MARGIN + (ROWS - 1 - r) * (height + GRID_MARGIN)};
75
+
76
+ if (levels.size () > levelIndex) {
77
+ const auto levelName{levels[levelIndex]};
78
+ const auto path{levelDirectory + ' /' + levelName};
79
+ std::string readableLevelName{levelName.substr (0 , levelName.find (" .json" ))};
80
+ menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_FILLED, [&context, path]() {
81
+ if (context.stateMachine ->hasState <PrismGame>()) {
82
+ context.stateMachine ->removeState <PrismGame>();
83
+ }
84
+ context.stateMachine ->addState <PrismGame>(context, path);
85
+ context.stateMachine ->setState <PrismGame>(context);
86
+ });
87
+ readableLevelName = fmt::format (" {:^13}" , readableLevelName);
88
+ if (readableLevelName.size () > 13 )
89
+ readableLevelName = readableLevelName.substr (0 , 10 ) + " ..." ;
90
+
91
+ menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_FILLED);
92
+ menuBuilder.addTextControl (x + .03f , y + height / 2 , 0.001 , Math::Vector3f (1 , 1 , 1 ),
93
+ readableLevelName);
94
+ } else {
95
+ menuBuilder.addControl (x, y, width, height, Sprites::LEVEL_SLOT_EMPTY);
96
+
97
+ menuBuilder.addControl (x + .025f , y + height / 4 + .09f , width - 0 .05f , .11 ,
98
+ Sprites::WHITE_BORDERED);
99
+
100
+ menuBuilder.addTextControl (x + .05f , y + height / 2 , 0.001 , Math::Vector3f (0 , 0 , 0 ), " Empty Slot" );
101
+ }
102
+
103
+ }
104
+ }
105
+ menu = menuBuilder.buildMenu ();
106
+ }
107
+
108
+ void WorldSelectionState::onUpdate (Context &context) {
109
+ // TODO: Move this generic code to shared function or superclass.
110
+ renderDevice->clearScreen ();
111
+ menuRenderer.renderMenu (*menu, float (context.window ->width ) / float (context.window ->height ));
112
+
113
+ if (menu->handleInput (*context.inputManager , context.window ->width , context.window ->height )) {
114
+ return ;
115
+ }
116
+
117
+ context.window ->swapScreen ();
118
+ }
122
119
123
120
}
0 commit comments