mirror of https://github.com/buggins/dlangui.git
Tetris example: add controls
This commit is contained in:
parent
a77a20e6e7
commit
981f53b825
Binary file not shown.
|
After Width: | Height: | Size: 843 B |
Binary file not shown.
|
After Width: | Height: | Size: 834 B |
Binary file not shown.
|
After Width: | Height: | Size: 810 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -14,14 +14,15 @@ enum TetrisAction : int {
|
||||||
LevelUp,
|
LevelUp,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Action ACTION_MOVE_LEFT = (new Action(TetrisAction.MoveLeft, KeyCode.LEFT)).addAccelerator(KeyCode.KEY_A);
|
const Action ACTION_MOVE_LEFT = (new Action(TetrisAction.MoveLeft, KeyCode.LEFT)).addAccelerator(KeyCode.KEY_A).iconId("arrow-left");
|
||||||
const Action ACTION_MOVE_RIGHT = (new Action(TetrisAction.MoveRight, KeyCode.RIGHT)).addAccelerator(KeyCode.KEY_D);
|
const Action ACTION_MOVE_RIGHT = (new Action(TetrisAction.MoveRight, KeyCode.RIGHT)).addAccelerator(KeyCode.KEY_D).iconId("arrow-right");
|
||||||
const Action ACTION_ROTATE = (new Action(TetrisAction.RotateCCW, KeyCode.UP)).addAccelerator(KeyCode.KEY_W);
|
const Action ACTION_ROTATE = (new Action(TetrisAction.RotateCCW, KeyCode.UP)).addAccelerator(KeyCode.KEY_W).iconId("rotate");
|
||||||
const Action ACTION_FAST_DOWN = (new Action(TetrisAction.FastDown, KeyCode.SPACE)).addAccelerator(KeyCode.KEY_S);
|
const Action ACTION_FAST_DOWN = (new Action(TetrisAction.FastDown, KeyCode.SPACE)).addAccelerator(KeyCode.KEY_S).iconId("arrow-down");
|
||||||
const Action ACTION_PAUSE = (new Action(TetrisAction.Pause, KeyCode.ESCAPE)).addAccelerator(KeyCode.PAUSE);
|
const Action ACTION_PAUSE = (new Action(TetrisAction.Pause, KeyCode.ESCAPE)).addAccelerator(KeyCode.PAUSE).iconId("pause");
|
||||||
const Action ACTION_LEVEL_UP = (new Action(TetrisAction.LevelUp, KeyCode.ADD)).addAccelerator(KeyCode.INS);
|
const Action ACTION_LEVEL_UP = (new Action(TetrisAction.LevelUp, KeyCode.ADD)).addAccelerator(KeyCode.INS).iconId("levelup");
|
||||||
|
|
||||||
const Action[] CUP_ACTIONS = [ACTION_MOVE_LEFT, ACTION_MOVE_RIGHT, ACTION_ROTATE, ACTION_FAST_DOWN, ACTION_PAUSE, ACTION_LEVEL_UP];
|
const Action[] CUP_ACTIONS = [ACTION_PAUSE, ACTION_ROTATE, ACTION_LEVEL_UP,
|
||||||
|
ACTION_MOVE_LEFT, ACTION_FAST_DOWN, ACTION_MOVE_RIGHT];
|
||||||
|
|
||||||
/// about dialog
|
/// about dialog
|
||||||
Widget createAboutWidget()
|
Widget createAboutWidget()
|
||||||
|
|
@ -88,12 +89,14 @@ class CupWidget : Widget {
|
||||||
|
|
||||||
protected int _totalRowsDestroyed;
|
protected int _totalRowsDestroyed;
|
||||||
|
|
||||||
static const int[10] LEVEL_SPEED = [15000000, 10000000, 7000000, 6000000, 5000000, 4000000, 3500000, 3000000, 2500000, 2000000];
|
static const int[10] LEVEL_SPEED = [15000000, 10000000, 7000000, 6000000, 5000000, 4000000, 300000, 2000000, 1500000, 1000000];
|
||||||
|
|
||||||
static const int RESERVED_ROWS = 5; // reserved for next figure
|
static const int RESERVED_ROWS = 5; // reserved for next figure
|
||||||
|
|
||||||
/// set difficulty level 1..10
|
/// set difficulty level 1..10
|
||||||
void setLevel(int level) {
|
void setLevel(int level) {
|
||||||
|
if (level > 10)
|
||||||
|
return;
|
||||||
_level = level;
|
_level = level;
|
||||||
_movementDuration = LEVEL_SPEED[level - 1];
|
_movementDuration = LEVEL_SPEED[level - 1];
|
||||||
_status.setLevel(_level);
|
_status.setLevel(_level);
|
||||||
|
|
@ -455,9 +458,7 @@ class CupWidget : Widget {
|
||||||
// TODO: implement pause
|
// TODO: implement pause
|
||||||
return true;
|
return true;
|
||||||
case TetrisAction.LevelUp:
|
case TetrisAction.LevelUp:
|
||||||
if (_level < 10)
|
setLevel(_level + 1);
|
||||||
_level++;
|
|
||||||
// TODO: update state
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
if (parent) // by default, pass to parent widget
|
if (parent) // by default, pass to parent widget
|
||||||
|
|
@ -474,7 +475,7 @@ class CupWidget : Widget {
|
||||||
this(StatusWidget status) {
|
this(StatusWidget status) {
|
||||||
super("CUP");
|
super("CUP");
|
||||||
this._status = status;
|
this._status = status;
|
||||||
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT).layoutWeight(3).setState(State.Default).focusable(true).padding(Rect(20, 20, 20, 20));
|
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT).layoutWeight(2).setState(State.Default).focusable(true).padding(Rect(20, 20, 20, 20));
|
||||||
|
|
||||||
_cols = 10;
|
_cols = 10;
|
||||||
_rows = 18;
|
_rows = 18;
|
||||||
|
|
@ -500,11 +501,36 @@ class StatusWidget : VerticalLayout {
|
||||||
res.layoutWidth(FILL_PARENT).alignment(Align.Center).fontSize(25).textColor(color);
|
res.layoutWidth(FILL_PARENT).alignment(Align.Center).fontSize(25).textColor(color);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget createControls() {
|
||||||
|
TableLayout res = new TableLayout();
|
||||||
|
res.colCount = 3;
|
||||||
|
foreach(const Action a; CUP_ACTIONS) {
|
||||||
|
ImageButton btn = new ImageButton(a);
|
||||||
|
btn.focusable = false;
|
||||||
|
res.addChild(btn);
|
||||||
|
}
|
||||||
|
res.layoutWidth(WRAP_CONTENT).layoutHeight(WRAP_CONTENT).margins(Rect(10, 10, 10, 10)).alignment(Align.Center);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
this() {
|
this() {
|
||||||
super("CUP_STATUS");
|
super("CUP_STATUS");
|
||||||
|
|
||||||
addChild(new VSpacer());
|
addChild(new VSpacer());
|
||||||
addChild((new ImageWidget(null, "tetris_logo_big")).layoutWidth(FILL_PARENT).alignment(Align.Center));
|
|
||||||
|
ImageWidget image = new ImageWidget(null, "tetris_logo_big");
|
||||||
|
image.layoutWidth(FILL_PARENT).alignment(Align.Center).clickable(true);
|
||||||
|
image.onClickListener = delegate(Widget src) {
|
||||||
|
_cup.handleAction(ACTION_PAUSE);
|
||||||
|
// about dialog when clicking on image
|
||||||
|
Window wnd = Platform.instance.createWindow("About...", window, WindowFlag.Modal);
|
||||||
|
wnd.mainWidget = createAboutWidget();
|
||||||
|
wnd.show();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
addChild(image);
|
||||||
|
|
||||||
addChild(new VSpacer());
|
addChild(new VSpacer());
|
||||||
addChild(createTextWidget("Level:"d, 0x008000));
|
addChild(createTextWidget("Level:"d, 0x008000));
|
||||||
addChild((_level = createTextWidget(""d, 0x008000)));
|
addChild((_level = createTextWidget(""d, 0x008000)));
|
||||||
|
|
@ -515,9 +541,10 @@ class StatusWidget : VerticalLayout {
|
||||||
addChild(createTextWidget("Score:"d, 0x800000));
|
addChild(createTextWidget("Score:"d, 0x800000));
|
||||||
addChild((_score = createTextWidget(""d, 0x800000)));
|
addChild((_score = createTextWidget(""d, 0x800000)));
|
||||||
addChild(new VSpacer());
|
addChild(new VSpacer());
|
||||||
|
addChild(createControls());
|
||||||
addChild(new VSpacer());
|
addChild(new VSpacer());
|
||||||
|
|
||||||
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT).layoutWeight(2).padding(Rect(20, 20, 20, 20));
|
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT).layoutWeight(2).padding(Rect(10, 10, 10, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLevel(int level) {
|
void setLevel(int level) {
|
||||||
|
|
@ -554,7 +581,7 @@ class CupPage : HorizontalLayout {
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
super.measure(parentWidth, parentHeight);
|
super.measure(parentWidth, parentHeight);
|
||||||
/// fixed size
|
/// fixed size
|
||||||
measuredContent(parentWidth, parentHeight, 550, 550);
|
measuredContent(parentWidth, parentHeight, 600, 550);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,59 +74,59 @@ const Figure[7] FIGURES = [
|
||||||
// ## ####
|
// ## ####
|
||||||
// 00## 00##
|
// 00## 00##
|
||||||
// ##
|
// ##
|
||||||
Figure([FigureShape([1, 0], [1, 1], [0, -1]),
|
Figure([FigureShape([1, 0], [ 1, 1], [0,-1]),
|
||||||
FigureShape([0, 1], [-1, 1], [1, 0]),
|
FigureShape([0, 1], [-1, 1], [1, 0]),
|
||||||
FigureShape([1, 0], [1, 1], [0, -1]),
|
FigureShape([1, 0], [ 1, 1], [0,-1]),
|
||||||
FigureShape([0, 1], [-1, 1], [1, 0])]),
|
FigureShape([0, 1], [-1, 1], [1, 0])]),
|
||||||
// FIGURE2 ===========================================
|
// FIGURE2 ===========================================
|
||||||
// ## ####
|
// ## ####
|
||||||
// 00## ##00
|
// 00## ##00
|
||||||
// ##
|
// ##
|
||||||
Figure([FigureShape([1, 0], [0, 1], [1, 1]),
|
Figure([FigureShape([1, 0], [0, 1], [ 1,-1]),
|
||||||
FigureShape([0, 1], [1, 1], [-1, 0]),
|
FigureShape([0, 1], [1, 1], [-1, 0]),
|
||||||
FigureShape([1, 0], [0, 1], [1, 1]),
|
FigureShape([1, 0], [0, 1], [ 1,-1]),
|
||||||
FigureShape([0, 1], [1, 1], [-1, 0])]),
|
FigureShape([0, 1], [1, 1], [-1, 0])]),
|
||||||
// FIGURE3 ===========================================
|
// FIGURE3 ===========================================
|
||||||
// ## ## ####
|
// ## ## ####
|
||||||
// ##00## 00 ##00## 00
|
// ##00## 00 ##00## 00
|
||||||
// ## #### ##
|
// ## #### ##
|
||||||
Figure([FigureShape([1, 0], [-1,0], [-1,-1]),
|
Figure([FigureShape([1, 0], [-1, 0], [-1,-1]),
|
||||||
FigureShape([0, 1], [0,-1], [ 1,-1]),
|
FigureShape([0, 1], [ 0,-1], [ 1,-1]),
|
||||||
FigureShape([1, 0], [-1,0], [1, 1]),
|
FigureShape([1, 0], [-1, 0], [ 1, 1]),
|
||||||
FigureShape([0, 1], [-1,1], [0,-1])]),
|
FigureShape([0, 1], [-1, 1], [ 0,-1])]),
|
||||||
// FIGURE4 ===========================================
|
// FIGURE4 ===========================================
|
||||||
// #### ## ##
|
// #### ## ##
|
||||||
// ##00## 00 ##00## 00
|
// ##00## 00 ##00## 00
|
||||||
// ## ## ####
|
// ## ## ####
|
||||||
Figure([FigureShape([1, 0], [-1,0], [ 1,-1]),
|
Figure([FigureShape([1, 0], [-1, 0], [ 1,-1]),
|
||||||
FigureShape([0, 1], [0,-1], [ 1, 1]),
|
FigureShape([0, 1], [ 0,-1], [ 1, 1]),
|
||||||
FigureShape([1, 0], [-1,0], [-1, 1]),
|
FigureShape([1, 0], [-1, 0], [-1, 1]),
|
||||||
FigureShape([0, 1], [-1,-1], [0, -1])]),
|
FigureShape([0, 1], [-1,-1], [ 0,-1])]),
|
||||||
// FIGURE5 ===========================================
|
// FIGURE5 ===========================================
|
||||||
// ####
|
// ####
|
||||||
// 00##
|
// 00##
|
||||||
//
|
//
|
||||||
Figure([FigureShape([1, 0], [0, 1], [ 1, 1]),
|
Figure([FigureShape([1, 0], [0, 1], [ 1, 1]),
|
||||||
FigureShape([1, 0], [0, 1], [ 1, 1]),
|
FigureShape([1, 0], [0, 1], [ 1, 1]),
|
||||||
FigureShape([1, 0], [0, 1], [ 1, 1]),
|
FigureShape([1, 0], [0, 1], [ 1, 1]),
|
||||||
FigureShape([1, 0], [0, 1], [ 1, 1])]),
|
FigureShape([1, 0], [0, 1], [ 1, 1])]),
|
||||||
// FIGURE6 ===========================================
|
// FIGURE6 ===========================================
|
||||||
// ##
|
// ##
|
||||||
// ##
|
// ##
|
||||||
// 00 ##00####
|
// 00 ##00####
|
||||||
// ##
|
// ##
|
||||||
Figure([FigureShape([0, 1], [0, 2], [ 0,-1]),
|
Figure([FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||||
FigureShape([1, 0], [2, 0], [-1, 0]),
|
FigureShape([1, 0], [2, 0], [-1, 0]),
|
||||||
FigureShape([0, 1], [0, 2], [ 0,-1]),
|
FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||||
FigureShape([1, 0], [2, 0], [-1, 0])]),
|
FigureShape([1, 0], [2, 0], [-1, 0])]),
|
||||||
// FIGURE7 ===========================================
|
// FIGURE7 ===========================================
|
||||||
// ## ## ##
|
// ## ## ##
|
||||||
// ##00## 00## ##00## ##00
|
// ##00## 00## ##00## ##00
|
||||||
// ## ## ##
|
// ## ## ##
|
||||||
Figure([FigureShape([1, 0], [-1,0], [ 0,-1]),
|
Figure([FigureShape([1, 0], [-1,0], [ 0,-1]),
|
||||||
FigureShape([0, 1], [0,-1], [ 1, 0]),
|
FigureShape([0, 1], [0,-1], [ 1, 0]),
|
||||||
FigureShape([1, 0], [-1,0], [ 0, 1]),
|
FigureShape([1, 0], [-1,0], [ 0, 1]),
|
||||||
FigureShape([0, 1], [0,-1], [-1, 0])]),
|
FigureShape([0, 1], [0,-1], [-1, 0])]),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// colors for different figure types
|
/// colors for different figure types
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ module dlangui.widgets.controls;
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
import dlangui.widgets.layouts;
|
import dlangui.widgets.layouts;
|
||||||
|
|
||||||
import std.algorithm;
|
private import std.algorithm;
|
||||||
|
private import std.conv : to;
|
||||||
|
|
||||||
/// vertical spacer to fill empty space in vertical layouts
|
/// vertical spacer to fill empty space in vertical layouts
|
||||||
class VSpacer : Widget {
|
class VSpacer : Widget {
|
||||||
|
|
@ -171,6 +172,7 @@ class ImageWidget : Widget {
|
||||||
}
|
}
|
||||||
measuredContent(parentWidth, parentHeight, w, h);
|
measuredContent(parentWidth, parentHeight, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
if (visibility != Visibility.Visible)
|
if (visibility != Visibility.Visible)
|
||||||
return;
|
return;
|
||||||
|
|
@ -194,6 +196,7 @@ class ImageWidget : Widget {
|
||||||
|
|
||||||
/// button with image only
|
/// button with image only
|
||||||
class ImageButton : ImageWidget {
|
class ImageButton : ImageWidget {
|
||||||
|
/// constructor by id and icon resource id
|
||||||
this(string ID = null, string drawableId = null) {
|
this(string ID = null, string drawableId = null) {
|
||||||
super(ID, drawableId);
|
super(ID, drawableId);
|
||||||
styleId = "BUTTON";
|
styleId = "BUTTON";
|
||||||
|
|
@ -202,8 +205,11 @@ class ImageButton : ImageWidget {
|
||||||
focusable = true;
|
focusable = true;
|
||||||
trackHover = true;
|
trackHover = true;
|
||||||
}
|
}
|
||||||
|
/// constructor from action
|
||||||
|
this(const Action a) {
|
||||||
|
this("imagebutton-action" ~ to!string(a.id), a.iconId);
|
||||||
|
action = a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// button with image and text
|
/// button with image and text
|
||||||
|
|
@ -265,6 +271,14 @@ class ImageTextButton : HorizontalLayout {
|
||||||
UIString caption = rawText;
|
UIString caption = rawText;
|
||||||
init(drawableId, caption);
|
init(drawableId, caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// constructor from action
|
||||||
|
this(const Action a) {
|
||||||
|
super("imagetextbutton-action" ~ to!string(a.id));
|
||||||
|
init(a.iconId, a.labelValue);
|
||||||
|
action = a;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// checkbox
|
/// checkbox
|
||||||
|
|
@ -353,6 +367,12 @@ class Button : Widget {
|
||||||
focusable = true;
|
focusable = true;
|
||||||
trackHover = true;
|
trackHover = true;
|
||||||
}
|
}
|
||||||
|
/// constructor from action
|
||||||
|
this(const Action a) {
|
||||||
|
this("button-action" ~ to!string(a.id));
|
||||||
|
_text = a.labelValue;
|
||||||
|
action = a;
|
||||||
|
}
|
||||||
|
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
|
|
|
||||||
|
|
@ -625,7 +625,7 @@ class FrameLayout : WidgetGroup {
|
||||||
/// layout children as table with rows and columns
|
/// layout children as table with rows and columns
|
||||||
class TableLayout : WidgetGroup {
|
class TableLayout : WidgetGroup {
|
||||||
|
|
||||||
this(string ID) {
|
this(string ID = null) {
|
||||||
super(ID);
|
super(ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -598,7 +598,9 @@ class Widget {
|
||||||
|
|
||||||
protected Action _action;
|
protected Action _action;
|
||||||
/// action to emit on click
|
/// action to emit on click
|
||||||
@property Action action() { return _action; }
|
@property const(Action) action() { return _action; }
|
||||||
|
/// action to emit on click
|
||||||
|
@property void action(const Action action) { _action = action.clone; }
|
||||||
/// action to emit on click
|
/// action to emit on click
|
||||||
@property void action(Action action) { _action = action; }
|
@property void action(Action action) { _action = action; }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue