1
0
Files
otyaSMILEBASIC/SMILEBASIC/dialog.d

275 lines
7.9 KiB
D
Raw Normal View History

2016-12-25 20:10:36 +09:00
module otya.smilebasic.dialog;
import otya.smilebasic.petitcomputer;
2016-12-25 22:48:29 +09:00
import otya.smilebasic.project;
2016-12-25 20:10:36 +09:00
import derelict.sdl2.sdl;
import derelict.sdl2.image;
2016-12-26 15:47:52 +09:00
import derelict.sdl2.ttf;
2016-12-25 20:10:36 +09:00
import derelict.opengl3.gl;
import derelict.opengl3.gl3;
class DialogBase
{
abstract void render();
}
enum SelectionType
{
ok,
noYes,
backNext,
cancelConfirm,
cancelExecute,
next,
}
enum ButtonResult
{
a = 128,
b = 129,
x = 130,
y = 131,
up = 132,
down = 133,
left = 134,
right = 135,
l = 136,
r = 137,
touch = 140,
}
2016-12-25 22:48:29 +09:00
class DialogButton
{
int x, y, width, height;
2016-12-26 15:47:52 +09:00
SDL_Rect foregroundRect;
2016-12-25 22:48:29 +09:00
GraphicPage background;
2016-12-26 15:47:52 +09:00
GraphicPage foreground;
2016-12-25 22:48:29 +09:00
DialogResult result;
bool isPressed;
2016-12-26 15:47:52 +09:00
this(GraphicPage background, GraphicPage foreground, int x, int y, DialogResult result, int fx, int fy)
2016-12-25 22:48:29 +09:00
{
this.background = background;
2016-12-26 15:47:52 +09:00
this.foreground = foreground;
2016-12-25 22:48:29 +09:00
this.x = x;
this.y = y;
this.width = background.surface.w;
this.height = background.surface.h;
this.result = result;
2016-12-26 15:47:52 +09:00
foregroundRect.x = fx;
foregroundRect.y = fy;
foregroundRect.w = foreground.surface.w;
foregroundRect.h = foreground.surface.h;
2016-12-25 22:48:29 +09:00
}
2016-12-25 23:14:29 +09:00
bool colDetect(int x, int y)
{
return x >= this.x && y >= this.y && this.x + this.width > x && this.y + this.height > y;
}
2016-12-25 22:48:29 +09:00
}
class DialogResources
{
public GraphicPage button1;
public GraphicPage button2;
2016-12-26 15:47:52 +09:00
public TTF_Font* font;
2016-12-25 22:48:29 +09:00
public this(SDL_Renderer* renderer, GLenum textureScaleMode)
{
button1 = new GraphicPage("dialogresource/yes.png");
button1.createTexture(renderer, textureScaleMode);
button2 = new GraphicPage("dialogresource/no.png");
button2.createTexture(renderer, textureScaleMode);
2016-12-26 15:47:52 +09:00
font = TTF_OpenFont("dialogresource/mplus-1c-regular.ttf", 14);
2016-12-25 22:48:29 +09:00
}
}
2016-12-26 15:47:52 +09:00
struct Text
{
GraphicPage texture;
this(PetitComputer petitcom, wstring text, SDL_Color color)
{
text ~= '\0';
auto surface = petitcom.dialogResource.font.TTF_RenderUNICODE_Blended((cast(ushort[])text).ptr, color);
texture = new GraphicPage(surface);
texture.createTexture(petitcom.renderer, petitcom.textureScaleMode);
}
this(PetitComputer petitcom, wchar* text, SDL_Color color, uint width)
{
auto surface = petitcom.dialogResource.font.TTF_RenderUNICODE_Blended_Wrapped((cast(ushort*)text), color, width);
texture = new GraphicPage(surface);
texture.createTexture(petitcom.renderer, petitcom.textureScaleMode);
}
2016-12-26 15:47:52 +09:00
~this()
{
texture.deleteGL();
texture.deleteSDL();
}
}
2016-12-25 20:10:36 +09:00
class Dialog : DialogBase
{
private PetitComputer petitcom;
this(PetitComputer petitcom)
{
this.petitcom = petitcom;
}
private int result;
2016-12-25 22:05:18 +09:00
private SDL_Rect area;
2016-12-25 22:48:29 +09:00
DialogButton[] buttons;
2016-12-25 20:10:36 +09:00
2016-12-25 22:05:18 +09:00
void renderBackground()
{
int w = 16, h = 16;
glDepthMask(GL_FALSE);
glDisable(GL_TEXTURE_2D);
glColor3ub(248, 248, 248);
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(area.w, 0);
glVertex2i(area.w, area.h);
glVertex2i(0, area.h);
glEnd();
glColor3ub(192, 192, 192);
glBegin(GL_LINES);
for (int y = 0; y < area.h; y += h)
{
glVertex2i(0, y);
glVertex2i(area.w, y);
}
for (int x = 0; x < area.w; x += w)
{
glVertex2i(x, 0);
glVertex2i(x, area.h);
}
glEnd();
glDepthMask(GL_TRUE);
}
2016-12-26 15:47:52 +09:00
void renderQuad(SDL_Rect rect)
{
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(rect.x, rect.y);
glTexCoord2i(1, 0);
glVertex2i(rect.x + rect.w, rect.y);
glTexCoord2i(1, 1);
glVertex2i(rect.x + rect.w, rect.y + rect.h);
glTexCoord2i(0, 1);
glVertex2i(rect.x, rect.y + rect.h);
glEnd();
}
2016-12-25 22:48:29 +09:00
void renderButton(DialogButton button)
{
2016-12-25 23:14:29 +09:00
int mx, my;
if (button.isPressed)
{
mx += 2;
my += 2;
}
2016-12-25 22:48:29 +09:00
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
2016-12-26 15:47:52 +09:00
glEnable(GL_BLEND);
2016-12-25 22:48:29 +09:00
glColor3ub(255, 255, 255);
glBindTexture(GL_TEXTURE_2D, button.background.glTexture);
2016-12-26 15:47:52 +09:00
renderQuad(SDL_Rect(button.x + mx, button.y + my, button.width, button.height));
if (button.foreground)
{
glBindTexture(GL_TEXTURE_2D, button.foreground.glTexture);
renderQuad(SDL_Rect(button.x + button.foregroundRect.x + mx, button.y + button.foregroundRect.y + my, button.foregroundRect.w, button.foregroundRect.h));
}
glDisable(GL_BLEND);
2016-12-25 22:48:29 +09:00
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
}
void renderContent()
{
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glColor3ub(255, 255, 255);
glBindTexture(GL_TEXTURE_2D, message.glTexture);
renderQuad(SDL_Rect(12, 24, message.surface.w, message.surface.h));
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
}
2016-12-25 20:10:36 +09:00
override void render()
{
2016-12-25 22:05:18 +09:00
petitcom.chScreen2(area.x, area.y, area.w, area.h);
renderBackground();
2016-12-25 22:48:29 +09:00
foreach (b; buttons)
{
renderButton(b);
}
renderContent();
2016-12-25 20:10:36 +09:00
}
GraphicPage message;
2016-12-26 15:47:52 +09:00
2016-12-25 20:10:36 +09:00
int show(wstring text)
{
2016-12-25 22:05:18 +09:00
area = petitcom.showTouchScreen();
wchar[257] buffer;
if (text.length > 256)
{
buffer[0..256] = text[0..256];
buffer[256] = '\0';
}
else
{
buffer[0..text.length] = text[];
buffer[text.length] = '\0';
}
Text messageText = Text(petitcom, buffer.ptr, SDL_Color(0, 0, 0, 255), area.w - 24);
message = messageText.texture;
2016-12-25 22:48:29 +09:00
int buttonMarginWidth = 12;
int buttonMarginHeight = 12;
2016-12-26 15:47:52 +09:00
auto button1text = Text(petitcom, "はい", SDL_Color(0, 0, 0, 255));
ubyte sr, sg, sb, sa;
SDL_GetRGBA((cast(uint*)petitcom.dialogResource.button2.surface.pixels)[0], petitcom.dialogResource.button2.surface.format, &sr, &sg, &sb, &sa);
auto button2text = Text(petitcom, "いいえ", SDL_Color(sr, sg, sb, 255));
2016-12-25 22:48:29 +09:00
buttons = [
new DialogButton(
petitcom.dialogResource.button1,
2016-12-26 15:47:52 +09:00
button1text.texture,
2016-12-25 22:48:29 +09:00
area.w - buttonMarginWidth - petitcom.dialogResource.button1.surface.w,
area.h - buttonMarginHeight - petitcom.dialogResource.button1.surface.h,
2016-12-26 15:47:52 +09:00
DialogResult.SUCCESS,
22,
1
2016-12-25 22:48:29 +09:00
),
new DialogButton(
petitcom.dialogResource.button2,
2016-12-26 15:47:52 +09:00
button2text.texture,
2016-12-25 22:48:29 +09:00
buttonMarginWidth,
area.h - buttonMarginHeight - petitcom.dialogResource.button1.surface.h,
2016-12-26 15:47:52 +09:00
DialogResult.CANCEL,
22,
1
2016-12-25 22:48:29 +09:00
)
];
petitcom.dialog = this;
2016-12-25 23:14:29 +09:00
bool isPressed;
while (!isPressed)
2016-12-25 20:10:36 +09:00
{
auto to = petitcom.touchPosition();
2016-12-25 23:14:29 +09:00
auto x = to.display1X;
auto y = to.display1Y;
foreach (b; buttons)
{
if (to.tm == 1 && b.colDetect(x, y))
{
b.isPressed = true;
}
else if (b.isPressed && to.tm < 1)
{
result = b.result;
isPressed = true;
}
}
2016-12-25 22:05:18 +09:00
SDL_Delay(16);
2016-12-25 20:10:36 +09:00
}
petitcom.dialog = null;
2016-12-25 20:10:36 +09:00
petitcom.hideTouchScreen();
return result;
}
}