Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user