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,
|
||||
}
|
||||
|
||||
const Action ACTION_MOVE_LEFT = (new Action(TetrisAction.MoveLeft, KeyCode.LEFT)).addAccelerator(KeyCode.KEY_A);
|
||||
const Action ACTION_MOVE_RIGHT = (new Action(TetrisAction.MoveRight, KeyCode.RIGHT)).addAccelerator(KeyCode.KEY_D);
|
||||
const Action ACTION_ROTATE = (new Action(TetrisAction.RotateCCW, KeyCode.UP)).addAccelerator(KeyCode.KEY_W);
|
||||
const Action ACTION_FAST_DOWN = (new Action(TetrisAction.FastDown, KeyCode.SPACE)).addAccelerator(KeyCode.KEY_S);
|
||||
const Action ACTION_PAUSE = (new Action(TetrisAction.Pause, KeyCode.ESCAPE)).addAccelerator(KeyCode.PAUSE);
|
||||
const Action ACTION_LEVEL_UP = (new Action(TetrisAction.LevelUp, KeyCode.ADD)).addAccelerator(KeyCode.INS);
|
||||
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).iconId("arrow-right");
|
||||
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).iconId("arrow-down");
|
||||
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).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
|
||||
Widget createAboutWidget()
|
||||
|
|
@ -88,12 +89,14 @@ class CupWidget : Widget {
|
|||
|
||||
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
|
||||
|
||||
/// set difficulty level 1..10
|
||||
void setLevel(int level) {
|
||||
if (level > 10)
|
||||
return;
|
||||
_level = level;
|
||||
_movementDuration = LEVEL_SPEED[level - 1];
|
||||
_status.setLevel(_level);
|
||||
|
|
@ -455,9 +458,7 @@ class CupWidget : Widget {
|
|||
// TODO: implement pause
|
||||
return true;
|
||||
case TetrisAction.LevelUp:
|
||||
if (_level < 10)
|
||||
_level++;
|
||||
// TODO: update state
|
||||
setLevel(_level + 1);
|
||||
return true;
|
||||
default:
|
||||
if (parent) // by default, pass to parent widget
|
||||
|
|
@ -474,7 +475,7 @@ class CupWidget : Widget {
|
|||
this(StatusWidget status) {
|
||||
super("CUP");
|
||||
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;
|
||||
_rows = 18;
|
||||
|
|
@ -500,11 +501,36 @@ class StatusWidget : VerticalLayout {
|
|||
res.layoutWidth(FILL_PARENT).alignment(Align.Center).fontSize(25).textColor(color);
|
||||
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() {
|
||||
super("CUP_STATUS");
|
||||
|
||||
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(createTextWidget("Level:"d, 0x008000));
|
||||
addChild((_level = createTextWidget(""d, 0x008000)));
|
||||
|
|
@ -515,9 +541,10 @@ class StatusWidget : VerticalLayout {
|
|||
addChild(createTextWidget("Score:"d, 0x800000));
|
||||
addChild((_score = createTextWidget(""d, 0x800000)));
|
||||
addChild(new VSpacer());
|
||||
addChild(createControls());
|
||||
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) {
|
||||
|
|
@ -554,7 +581,7 @@ class CupPage : HorizontalLayout {
|
|||
override void measure(int parentWidth, int parentHeight) {
|
||||
super.measure(parentWidth, parentHeight);
|
||||
/// fixed size
|
||||
measuredContent(parentWidth, parentHeight, 550, 550);
|
||||
measuredContent(parentWidth, parentHeight, 600, 550);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,59 +74,59 @@ const Figure[7] FIGURES = [
|
|||
// ## ####
|
||||
// 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([1, 0], [1, 1], [0, -1]),
|
||||
FigureShape([1, 0], [ 1, 1], [0,-1]),
|
||||
FigureShape([0, 1], [-1, 1], [1, 0])]),
|
||||
// FIGURE2 ===========================================
|
||||
// ## ####
|
||||
// 00## ##00
|
||||
// ##
|
||||
Figure([FigureShape([1, 0], [0, 1], [1, 1]),
|
||||
FigureShape([0, 1], [1, 1], [-1, 0]),
|
||||
FigureShape([1, 0], [0, 1], [1, 1]),
|
||||
FigureShape([0, 1], [1, 1], [-1, 0])]),
|
||||
Figure([FigureShape([1, 0], [0, 1], [ 1,-1]),
|
||||
FigureShape([0, 1], [1, 1], [-1, 0]),
|
||||
FigureShape([1, 0], [0, 1], [ 1,-1]),
|
||||
FigureShape([0, 1], [1, 1], [-1, 0])]),
|
||||
// FIGURE3 ===========================================
|
||||
// ## ## ####
|
||||
// ##00## 00 ##00## 00
|
||||
// ## #### ##
|
||||
Figure([FigureShape([1, 0], [-1,0], [-1,-1]),
|
||||
FigureShape([0, 1], [0,-1], [ 1,-1]),
|
||||
FigureShape([1, 0], [-1,0], [1, 1]),
|
||||
FigureShape([0, 1], [-1,1], [0,-1])]),
|
||||
Figure([FigureShape([1, 0], [-1, 0], [-1,-1]),
|
||||
FigureShape([0, 1], [ 0,-1], [ 1,-1]),
|
||||
FigureShape([1, 0], [-1, 0], [ 1, 1]),
|
||||
FigureShape([0, 1], [-1, 1], [ 0,-1])]),
|
||||
// FIGURE4 ===========================================
|
||||
// #### ## ##
|
||||
// ##00## 00 ##00## 00
|
||||
// ## ## ####
|
||||
Figure([FigureShape([1, 0], [-1,0], [ 1,-1]),
|
||||
FigureShape([0, 1], [0,-1], [ 1, 1]),
|
||||
FigureShape([1, 0], [-1,0], [-1, 1]),
|
||||
FigureShape([0, 1], [-1,-1], [0, -1])]),
|
||||
Figure([FigureShape([1, 0], [-1, 0], [ 1,-1]),
|
||||
FigureShape([0, 1], [ 0,-1], [ 1, 1]),
|
||||
FigureShape([1, 0], [-1, 0], [-1, 1]),
|
||||
FigureShape([0, 1], [-1,-1], [ 0,-1])]),
|
||||
// FIGURE5 ===========================================
|
||||
// ####
|
||||
// 00##
|
||||
//
|
||||
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])]),
|
||||
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])]),
|
||||
// FIGURE6 ===========================================
|
||||
// ##
|
||||
// ##
|
||||
// 00 ##00####
|
||||
// ##
|
||||
Figure([FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||
FigureShape([1, 0], [2, 0], [-1, 0]),
|
||||
FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||
FigureShape([1, 0], [2, 0], [-1, 0])]),
|
||||
Figure([FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||
FigureShape([1, 0], [2, 0], [-1, 0]),
|
||||
FigureShape([0, 1], [0, 2], [ 0,-1]),
|
||||
FigureShape([1, 0], [2, 0], [-1, 0])]),
|
||||
// FIGURE7 ===========================================
|
||||
// ## ## ##
|
||||
// ##00## 00## ##00## ##00
|
||||
// ## ## ##
|
||||
Figure([FigureShape([1, 0], [-1,0], [ 0,-1]),
|
||||
FigureShape([0, 1], [0,-1], [ 1, 0]),
|
||||
FigureShape([1, 0], [-1,0], [ 0, 1]),
|
||||
FigureShape([0, 1], [0,-1], [-1, 0])]),
|
||||
Figure([FigureShape([1, 0], [-1,0], [ 0,-1]),
|
||||
FigureShape([0, 1], [0,-1], [ 1, 0]),
|
||||
FigureShape([1, 0], [-1,0], [ 0, 1]),
|
||||
FigureShape([0, 1], [0,-1], [-1, 0])]),
|
||||
];
|
||||
|
||||
/// colors for different figure types
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ module dlangui.widgets.controls;
|
|||
import dlangui.widgets.widget;
|
||||
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
|
||||
class VSpacer : Widget {
|
||||
|
|
@ -171,6 +172,7 @@ class ImageWidget : Widget {
|
|||
}
|
||||
measuredContent(parentWidth, parentHeight, w, h);
|
||||
}
|
||||
|
||||
override void onDraw(DrawBuf buf) {
|
||||
if (visibility != Visibility.Visible)
|
||||
return;
|
||||
|
|
@ -194,6 +196,7 @@ class ImageWidget : Widget {
|
|||
|
||||
/// button with image only
|
||||
class ImageButton : ImageWidget {
|
||||
/// constructor by id and icon resource id
|
||||
this(string ID = null, string drawableId = null) {
|
||||
super(ID, drawableId);
|
||||
styleId = "BUTTON";
|
||||
|
|
@ -202,8 +205,11 @@ class ImageButton : ImageWidget {
|
|||
focusable = 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
|
||||
|
|
@ -265,6 +271,14 @@ class ImageTextButton : HorizontalLayout {
|
|||
UIString caption = rawText;
|
||||
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
|
||||
|
|
@ -353,6 +367,12 @@ class Button : Widget {
|
|||
focusable = 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) {
|
||||
FontRef font = font();
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ class FrameLayout : WidgetGroup {
|
|||
/// layout children as table with rows and columns
|
||||
class TableLayout : WidgetGroup {
|
||||
|
||||
this(string ID) {
|
||||
this(string ID = null) {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -598,7 +598,9 @@ class Widget {
|
|||
|
||||
protected Action _action;
|
||||
/// 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
|
||||
@property void action(Action action) { _action = action; }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue