#include "ofxBaseGui.h"
#include "ofImage.h"
#include "ofBitmapFont.h"
#include "ofXml.h"
#include "ofJson.h"
using namespace std;
void ofxGuiSetFont(const string & fontPath, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, int dpi){
ofxBaseGui::loadFont(fontPath, fontsize, _bAntiAliased, _bFullCharacterSet, dpi);
}
void ofxGuiSetFont(const ofTrueTypeFontSettings & fontSettings){
ofxBaseGui::loadFont(fontSettings);
}
void ofxGuiSetBitmapFont(){
ofxBaseGui::setUseTTF(false);
}
void ofxGuiSetHeaderColor(const ofColor & color){
ofxBaseGui::setDefaultHeaderBackgroundColor(color);
}
void ofxGuiSetBackgroundColor(const ofColor & color){
ofxBaseGui::setDefaultBackgroundColor(color);
}
void ofxGuiSetBorderColor(const ofColor & color){
ofxBaseGui::setDefaultBorderColor(color);
}
void ofxGuiSetTextColor(const ofColor & color){
ofxBaseGui::setDefaultTextColor(color);
}
void ofxGuiSetFillColor(const ofColor & color){
ofxBaseGui::setDefaultFillColor(color);
}
void ofxGuiSetTextPadding(int padding){
ofxBaseGui::setDefaultTextPadding(padding);
}
void ofxGuiSetDefaultWidth(int width){
ofxBaseGui::setDefaultWidth(width);
}
void ofxGuiSetDefaultHeight(int height){
ofxBaseGui::setDefaultHeight(height);
}
void ofxGuiSetDefaultEventsPriority(ofEventOrder eventsPriority){
ofxBaseGui::setDefaultEventsPriority(eventsPriority);
}
void ofxGuiEnableHiResDisplay(){
ofxBaseGui::enableHiDpi();
}
void ofxGuiDisableHiResDisplay(){
ofxBaseGui::disableHiDpi();
}
ofColor
ofxBaseGui::headerBackgroundColor(80),
ofxBaseGui::backgroundColor(0),
ofxBaseGui::borderColor(120, 100),
ofxBaseGui::textColor(255),
ofxBaseGui::fillColor(128);
int ofxBaseGui::textPadding = 4;
int ofxBaseGui::defaultWidth = 200;
int ofxBaseGui::defaultHeight = 18;
ofTrueTypeFont ofxBaseGui::font;
bool ofxBaseGui::fontLoaded = false;
bool ofxBaseGui::useTTF = false;
ofBitmapFont ofxBaseGui::bitmapFont;
ofEventOrder ofxBaseGui::defaultEventsPriority = OF_EVENT_ORDER_BEFORE_APP;
float ofxBaseGui::hiDpiScale =1;
ofxBaseGui::ofxBaseGui(){
parent = nullptr;
currentFrame = ofGetFrameNum();
thisHeaderBackgroundColor = headerBackgroundColor;
thisBackgroundColor = backgroundColor;
thisBorderColor = borderColor;
thisTextColor = textColor;
thisFillColor = fillColor;
bRegisteredForMouseEvents = false;
needsRedraw = true;
}
void ofxBaseGui::loadFont(const std::string& filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, int dpi){
font.load(filename, fontsize, _bAntiAliased, _bFullCharacterSet, false, 0, dpi);
fontLoaded = true;
useTTF = true;
}
void ofxBaseGui::loadFont(const ofTrueTypeFontSettings & fontSettings){
font.load(fontSettings);
fontLoaded = true;
useTTF = true;
}
void ofxBaseGui::setUseTTF(bool bUseTTF){
if(bUseTTF && !fontLoaded){
loadFont(OF_TTF_MONO, 10, true, true);
}
useTTF = bUseTTF;
}
ofxBaseGui::~ofxBaseGui(){
unregisterMouseEvents();
}
void ofxBaseGui::registerMouseEvents(){
if(bRegisteredForMouseEvents == true){
return;
}
bRegisteredForMouseEvents = true;
ofRegisterMouseEvents(this, defaultEventsPriority);
}
void ofxBaseGui::unregisterMouseEvents(){
if(bRegisteredForMouseEvents == false){
return;
}
ofUnregisterMouseEvents(this, defaultEventsPriority);
bRegisteredForMouseEvents = false;
}
void ofxBaseGui::setEvents(ofCoreEvents & _events){
if(&_events != events){
bool wasMouseInputEnabled = bRegisteredForMouseEvents;
unregisterMouseEvents();
events = &_events;
if (wasMouseInputEnabled) {
registerMouseEvents();
}
}
}
void ofxBaseGui::draw(){
setEvents(ofEvents());
if(needsRedraw){
generateDraw();
needsRedraw = false;
}
currentFrame = ofGetFrameNum();
render();
}
bool ofxBaseGui::isGuiDrawing(){
if(ofGetFrameNum() - currentFrame > 1){
return false;
}else{
return true;
}
}
void ofxBaseGui::bindFontTexture(){
if(useTTF){
font.getFontTexture().bind();
}else{
bitmapFont.getTexture().bind();
}
}
void ofxBaseGui::unbindFontTexture(){
if(useTTF){
font.getFontTexture().unbind();
}else{
bitmapFont.getTexture().unbind();
}
}
ofMesh ofxBaseGui::getTextMesh(const string & text, float x, float y){
if(useTTF){
return font.getStringMesh(text, x, y);
}else{
auto m = bitmapFont.getMesh(text, x, y);
if(isHiDpiEnabled()){
auto bb = getTextBoundingBox(text, x, y);
bb.standardize();
for(auto& v: m.getVertices()){
v = (v - bb.getPosition())*hiDpiScale + bb.getPosition();
}
}
return m;
}
}
ofRectangle ofxBaseGui::getTextBoundingBox(const string & text, float x, float y){
if(useTTF){
return font.getStringBoundingBox(text, x, y);
}else{
auto r = bitmapFont.getBoundingBox(text, x, y);
if(isHiDpiEnabled()){
r.width *= hiDpiScale;
r.height *= hiDpiScale;
}
return r;
}
}
float ofxBaseGui::getTextVCenteredInRect(const ofRectangle& container){
if(useTTF){
return container.getCenter().y + (font.getAscenderHeight() + font.getDescenderHeight()) *0.5;
}else{
auto bb = getTextBoundingBox(" ",0,0);
return container.getCenter().y - bb.height*0.5 - bb.y;
}
}
void ofxBaseGui::saveToFile(const std::string& filename){
auto extension = ofToLower(ofFilePath::getFileExt(filename));
if(extension == "xml"){
ofXml xml;
if(ofFile(filename, ofFile::Reference).exists()){
xml.load(filename);
}
saveTo(xml);
xml.save(filename);
}else
if(extension == "json"){
ofJson json = ofLoadJson(filename);
saveTo(json);
ofSavePrettyJson(filename, json);
}else{
ofLogError("ofxGui") << extension << " not recognized, only .xml and .json supported by now";
}
}
void ofxBaseGui::loadFromFile(const std::string& filename){
auto extension = ofToLower(ofFilePath::getFileExt(filename));
if(extension == "xml"){
ofXml xml;
xml.load(filename);
loadFrom(xml);
}else
if(extension == "json"){
ofFile jsonFile(filename);
ofJson json = ofLoadJson(jsonFile);
loadFrom(json);
}else{
ofLogError("ofxGui") << extension << " not recognized, only .xml and .json supported by now";
}
}
string ofxBaseGui::getName(){
return getParameter().getName();
}
void ofxBaseGui::setName(const std::string& _name){
getParameter().setName(_name);
setNeedsRedraw();
}
void ofxBaseGui::setPosition(const glm::vec3 & p){
setPosition(p.x, p.y);
}
void ofxBaseGui::setPosition(float x, float y){
b.x = x;
b.y = y;
setNeedsRedraw();
}
void ofxBaseGui::setSize(float w, float h){
b.width = w;
b.height = h;
sizeChangedCB();
}
void ofxBaseGui::setShape(ofRectangle r){
b = r;
sizeChangedCB();
}
void ofxBaseGui::setShape(float x, float y, float w, float h){
b.set(x, y, w, h);
sizeChangedCB();
}
void ofxBaseGui::setShapeNoNotification(const ofRectangle& r){
b = r;
setNeedsRedraw();
}
void ofxBaseGui::setShapeNoNotification(float x, float y, float w, float h){
b.set(x, y, w, h);
setNeedsRedraw();
}
glm::vec3 ofxBaseGui::getPosition() const {
return glm::vec3(b.x, b.y, 0);
}
ofRectangle ofxBaseGui::getShape() const {
return b;
}
float ofxBaseGui::getWidth() const {
return b.width;
}
float ofxBaseGui::getHeight() const {
return b.height;
}
ofColor ofxBaseGui::getHeaderBackgroundColor() const {
return thisHeaderBackgroundColor;
}
ofColor ofxBaseGui::getBackgroundColor() const {
return thisBackgroundColor;
}
ofColor ofxBaseGui::getBorderColor() const {
return thisBorderColor;
}
ofColor ofxBaseGui::getTextColor() const {
return thisTextColor;
}
ofColor ofxBaseGui::getFillColor() const {
return thisFillColor;
}
void ofxBaseGui::setHeaderBackgroundColor(const ofColor & color){
setNeedsRedraw();
thisHeaderBackgroundColor = color;
}
void ofxBaseGui::setBackgroundColor(const ofColor & color){
setNeedsRedraw();
thisBackgroundColor = color;
}
void ofxBaseGui::setBorderColor(const ofColor & color){
setNeedsRedraw();
thisBorderColor = color;
}
void ofxBaseGui::setTextColor(const ofColor & color){
setNeedsRedraw();
thisTextColor = color;
}
void ofxBaseGui::setFillColor(const ofColor & color){
setNeedsRedraw();
thisFillColor = color;
}
void ofxBaseGui::setDefaultHeaderBackgroundColor(const ofColor & color){
headerBackgroundColor = color;
}
void ofxBaseGui::setDefaultBackgroundColor(const ofColor & color){
backgroundColor = color;
}
void ofxBaseGui::setDefaultBorderColor(const ofColor & color){
borderColor = color;
}
void ofxBaseGui::setDefaultTextColor(const ofColor & color){
textColor = color;
}
void ofxBaseGui::setDefaultFillColor(const ofColor & color){
fillColor = color;
}
void ofxBaseGui::setDefaultTextPadding(int padding){
textPadding = padding;
}
void ofxBaseGui::setDefaultWidth(int width){
defaultWidth = width;
}
void ofxBaseGui::setDefaultHeight(int height){
defaultHeight = height;
}
void ofxBaseGui::setDefaultEventsPriority(ofEventOrder eventsPriority){
defaultEventsPriority = eventsPriority;
}
void ofxBaseGui::sizeChangedCB(){
if(parent){
parent->sizeChangedCB();
}
setNeedsRedraw();
}
void ofxBaseGui::setNeedsRedraw(){
needsRedraw = true;
}
string ofxBaseGui::saveStencilToHex(const ofImage & img){
stringstream strm;
int width = img.getWidth();
int height = img.getHeight();
int n = width * height;
unsigned char cur = 0;
int shift = 0;
strm << "{";
for(int i = 0; i < n;){
if(img.getPixels()[i * 4 + 3] > 0){
cur |= 1 << shift;
}
i++;
if(i % 8 == 0){
strm << "0x" << hex << (unsigned int)cur;
cur = 0;
shift = 0;
if(i < n){
strm << ",";
}
}else{
shift++;
}
}
strm << "}";
return strm.str();
}
void ofxBaseGui::loadStencilFromHex(ofImage & img, unsigned char * data){
int width = img.getWidth();
int height = img.getHeight();
int i = 0;
ofColor on(255, 255);
ofColor off(255, 0);
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int shift = i % 8;
int offset = i / 8;
bool cur = (data[offset] >> shift) & 1;
img.setColor(x, y, cur ? on : off);
i++;
}
}
img.update();
}
void ofxBaseGui::setParent(ofxBaseGui * parent){
this->parent = parent;
}
ofxBaseGui * ofxBaseGui::getParent(){
return parent;
}
void ofxBaseGui::enableHiDpi(){
ofxBaseGui::hiDpiScale = 2;
ofxBaseGui::textPadding = 8;
ofxBaseGui::defaultWidth = 400;
ofxBaseGui::defaultHeight = 36;
}
void ofxBaseGui::disableHiDpi(){
ofxBaseGui::hiDpiScale = 1;
ofxBaseGui::textPadding = 4;
ofxBaseGui::defaultWidth = 200;
ofxBaseGui::defaultHeight = 18;
}
bool ofxBaseGui::isHiDpiEnabled(){
return hiDpiScale == 2;
}
Comments