Files
starruler-linux/scripts/toolkit/dialogs/MaterialChooser.as
T
2018-07-17 14:15:37 +02:00

227 lines
6.3 KiB
ActionScript

import dialogs.Dialog;
enum MaterialChooserMode {
MCM_All,
MCM_Materials,
MCM_Spritesheets,
};
MaterialChooser@ openMaterialChooser(MaterialChoiceCallback@ callback, MaterialChooserMode mode = MCM_All) {
MaterialChooser@ matDialog = MaterialChooser(callback, null, mode);
addDialog(matDialog);
return matDialog;
}
interface MaterialChoiceCallback {
void onMaterialChosen(const Material@ material, const string& id);
void onSpriteSheetChosen(const SpriteSheet@ spritebank, uint spriteIndex, const string& id);
};
class MaterialChooser : Dialog {
MaterialList@ materials;
MaterialChoiceCallback@ matCallback;
MaterialChooser(MaterialChoiceCallback@ userCallback, IGuiElement@ bind, MaterialChooserMode mode) {
super(bind);
width = 1024;
height = 768;
@materials = MaterialList(window, recti(4,4,1020,764), mode);
@matCallback = userCallback;
}
bool onMouseEvent(const MouseEvent& event, IGuiElement@ source) {
return false;
}
bool onKeyEvent(const KeyboardEvent& event, IGuiElement@ source) {
return false;
}
bool onGuiEvent(const GuiEvent& event) {
if(event.type == GUI_Clicked && event.caller is materials) {
if(materials.material !is null)
matCallback.onMaterialChosen(materials.material, materials.identifier);
else if(materials.spriteSheet !is null)
matCallback.onSpriteSheetChosen(materials.spriteSheet, materials.spriteIndex, materials.identifier);
closeDialog(this);
return true;
}
return false;
}
};
class MaterialList : BaseGuiElement {
const Material@ material;
const SpriteSheet@ spriteSheet;
string identifier;
uint spriteIndex;
MaterialChooserMode mode;
int scroll;
int iconSize, margin;
uint rowIconCount;
vec2i hoverPos, clickPos;
MaterialList(IGuiElement@ parent, const recti& position, MaterialChooserMode Mode) {
super(parent, position);
hoverPos = vec2i(-1,-1);
iconSize = 96;
margin = 2;
mode = Mode;
rowIconCount = (AbsolutePosition.width - (2 * margin) / (iconSize + margin));
}
vec2i absoluteToMatPos(int x, int y) const {
return vec2i((x - (AbsolutePosition.topLeft.x + 4)) / (iconSize + margin),
(y - (AbsolutePosition.topLeft.y + 4) + scroll) / (iconSize + margin));
}
void draw() {
@material = null;
@spriteSheet = null;
vec2i at;
int x = margin, y = margin - scroll;
int height = AbsolutePosition.height;
int row = 0, col = 0;
//Draw each material
uint count = getMaterialCount();
if(mode == MCM_All || mode == MCM_Materials) {
for(uint i = 0; i < count; ++i) {
if(y + iconSize >= 0 && y - iconSize < height) {
const Material@ mat = getMaterial(i);
if(hoverPos.x == col && hoverPos.y == row) {
@material = mat;
identifier = getMaterialName(i);
at = vec2i(x-iconSize/2,y-iconSize/2);
}
else {
mat.draw(recti(x,y,x+iconSize,y+iconSize) + AbsolutePosition.topLeft, Color(0xffffffff), shader::BaseTexture);
}
}
x += iconSize + margin;
col += 1;
if(x+iconSize > AbsolutePosition.width - margin) {
x = margin;
y += iconSize + margin;
col = 0;
row += 1;
}
}
//Start on a new line when we switch to sprite sheets
if(col != 0) {
x = margin;
y += iconSize + margin;
col = 0;
row += 1;
}
}
//Draw each sprite in each sprite sheet
if(mode == MCM_All || mode == MCM_Spritesheets) {
count = getSpriteSheetCount();
for(uint i = 0; i < count; ++i) {
const SpriteSheet@ sheet = getSpriteSheet(i);
uint spriteCount = sheet.count;
for(uint j = 0; j < spriteCount; ++j) {
if(y + iconSize >= 0 && y - iconSize < height) {
if(hoverPos.x == col && hoverPos.y == row) {
at = vec2i(x-iconSize/2,y-iconSize/2);
@spriteSheet = sheet;
spriteIndex = j;
identifier = getSpriteSheetName(i);
}
else {
sheet.draw(j, recti_area(vec2i(x,y),vec2i(iconSize)) + AbsolutePosition.topLeft, shader::BaseTexture);
}
}
x += iconSize + margin;
col += 1;
if(x+iconSize > AbsolutePosition.width - margin) {
x = margin;
y += iconSize + margin;
col = 0;
row += 1;
}
}
}
}
if(material !is null || spriteSheet !is null) {
if(at.x < margin)
at.x = margin;
else if(at.x + (iconSize*2) > AbsolutePosition.width - margin)
at.x = AbsolutePosition.width - margin - (iconSize*2);
if(at.y < margin)
at.y = margin;
else if(at.y + (iconSize*2) > AbsolutePosition.height - margin)
at.y = AbsolutePosition.height - margin - (iconSize*2);
recti bgRect = recti(at.x - margin, at.y - margin, at.x + (iconSize*2) + margin, at.y + (iconSize*2) + margin) + AbsolutePosition.topLeft;
if(material !is null) {
drawRectangle(bgRect, Color(0x70a070ff));
vec2i size = material.size;
if(size.x > iconSize * 2 || size.y > iconSize * 2) {
double factor = max(double(size.x), double(size.y)) / double(iconSize * 2);
size /= factor;
}
material.draw(recti_area(at + vec2i(iconSize) - size * 0.5,size) + AbsolutePosition.topLeft, Color(0xffffffff), shader::BaseTexture);
skin.getFont(FT_Normal).draw(bgRect, identifier, Color(0x000000ff), vertAlign = 0.0);
}
else if(spriteSheet !is null) {
drawRectangle(bgRect, Color(0x70a070ff));
vec2i size = spriteSheet.size;
if(size.x > iconSize * 2 || size.y > iconSize * 2) {
double factor = max(double(size.x), double(size.y)) / double(iconSize * 2);
size /= factor;
}
spriteSheet.draw(spriteIndex, recti_area(at + vec2i(iconSize) - size * 0.5,size) + AbsolutePosition.topLeft, shader::BaseTexture);
skin.getFont(FT_Normal).draw(bgRect, identifier, Color(0x000000ff), vertAlign = 0.0);
}
}
BaseGuiElement::draw();
}
bool onMouseEvent(const MouseEvent& event, IGuiElement@ source) {
if(event.type == MET_Button_Up) {
vec2i pos = absoluteToMatPos(event.x, event.y);
if(pos == clickPos) {
emitClicked();
}
return true;
}
else if(event.type == MET_Button_Down) {
clickPos = absoluteToMatPos(event.x, event.y);
return true;
}
else if(event.type == MET_Moved) {
hoverPos = absoluteToMatPos(event.x, event.y);
}
else if(event.type == MET_Scrolled) {
scroll -= int(event.y * 32.0);
if(scroll < 0)
scroll = 0;
}
return BaseGuiElement::onMouseEvent(event, source);
}
};