mirror of
https://github.com/bradgrantham/apple2e.git
synced 2024-12-26 10:29:32 +00:00
initial breakout of UI widget classes
This commit is contained in:
parent
420f016098
commit
a9e48a509a
261
interface.cpp
261
interface.cpp
@ -28,6 +28,8 @@
|
||||
#define GLFW_INCLUDE_GLCOREARB
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "ui_widgets.h"
|
||||
|
||||
#include "glwidget.h"
|
||||
|
||||
#include "interface.h"
|
||||
@ -601,265 +603,6 @@ void set_shader(float to_screen[9], DisplayMode display_mode, bool mixed_mode, i
|
||||
}
|
||||
}
|
||||
|
||||
typedef pair<float, float> width_height;
|
||||
|
||||
struct widget
|
||||
{
|
||||
virtual width_height get_min_dimensions() const = 0;
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h) {};
|
||||
virtual bool click(double now, float x, float y) { return false; };
|
||||
virtual void hover(double now, float x, float y) {};
|
||||
virtual void drag(double now, float x, float y) {};
|
||||
virtual void release(double now, float x, float y) {};
|
||||
virtual bool drop(double now, float x, float y, int count, const char** paths) { return false; };
|
||||
};
|
||||
|
||||
struct switcher
|
||||
{
|
||||
float w, h;
|
||||
int which;
|
||||
vector<widget*> children;
|
||||
switcher(vector<widget*> children_) :
|
||||
w(0),
|
||||
h(0),
|
||||
which(0),
|
||||
children(children_)
|
||||
{
|
||||
for(auto it : children) {
|
||||
float cw, ch;
|
||||
tie(cw, ch) = it->get_min_dimensions();
|
||||
w = max(w, cw);
|
||||
h = max(h, ch);
|
||||
}
|
||||
}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h)
|
||||
{
|
||||
children[which]->draw(now, to_screen, x, y, w, h);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return children[which]->click(now, x, y);
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
children[which]->hover(now, x, y);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
children[which]->drag(now, x, y);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
children[which]->release(now, x, y);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char** paths)
|
||||
{
|
||||
return children[which]->drop(now, x, y, count, paths);
|
||||
}
|
||||
};
|
||||
|
||||
struct spacer : public widget
|
||||
{
|
||||
float w, h;
|
||||
spacer(float w_, float h_) :
|
||||
w(w_),
|
||||
h(h_)
|
||||
{}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
};
|
||||
|
||||
struct placed_widget
|
||||
{
|
||||
widget *widg;
|
||||
float x, y, w, h;
|
||||
};
|
||||
|
||||
struct padding : public widget
|
||||
{
|
||||
widget* child;
|
||||
float w, h;
|
||||
float left_pad, right_pad, top_pad, bottom_pad;
|
||||
float cw, ch;
|
||||
|
||||
padding(float left_pad_, float right_pad_, float top_pad_, float bottom_pad_, widget* child_) :
|
||||
child(child_),
|
||||
left_pad(left_pad_),
|
||||
right_pad(right_pad_),
|
||||
top_pad(top_pad_),
|
||||
bottom_pad(bottom_pad_)
|
||||
{
|
||||
tie(cw, ch) = child->get_min_dimensions();
|
||||
w = cw + left_pad_ + right_pad_;
|
||||
h = ch + top_pad_ + bottom_pad_;
|
||||
}
|
||||
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w_, float h_)
|
||||
{
|
||||
child->draw(now, to_screen, x + left_pad, y + top_pad, w_ - left_pad - right_pad, h_ - top_pad - bottom_pad);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
return child->drop(now, x + left_pad, y + top_pad, count, paths);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return child->click(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
child->hover(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
child->drag(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
child->release(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
};
|
||||
|
||||
struct centering : public widget
|
||||
{
|
||||
float w, h;
|
||||
float cw, ch;
|
||||
widget* child;
|
||||
|
||||
centering(widget* child_) : child(child_)
|
||||
{
|
||||
tie(cw, ch) = child->get_min_dimensions();
|
||||
}
|
||||
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {cw, ch};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w_, float h_)
|
||||
{
|
||||
w = w_;
|
||||
h = h_;
|
||||
child->draw(now, to_screen, x + (w - cw) / 2, y + (h - ch) / 2, cw, ch);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
return child->drop(now, x - (w - cw) / 2, y - (h - ch) / 2, count, paths);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return child->click(now, x - (w - cw) / 2, y - (h - ch) / 2); // XXX should limit to cw,ch too
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
child->hover(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
child->drag(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
child->release(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
};
|
||||
|
||||
struct widgetbox : public widget
|
||||
{
|
||||
enum Direction {VERTICAL, HORIZONTAL} dir;
|
||||
float w, h;
|
||||
vector<placed_widget> children;
|
||||
placed_widget focus;
|
||||
|
||||
widgetbox(Direction dir_, vector<widget*> children_) :
|
||||
dir(dir_),
|
||||
w(0),
|
||||
h(0),
|
||||
focus({nullptr, 0, 0, 0, 0})
|
||||
{
|
||||
for(auto it : children_) {
|
||||
widget *child = it;
|
||||
float cw, ch;
|
||||
tie(cw, ch) = child->get_min_dimensions();
|
||||
if(dir == HORIZONTAL) {
|
||||
w += cw;
|
||||
h = std::max(h, ch);
|
||||
} else {
|
||||
w = std::max(w, cw);
|
||||
h += ch;
|
||||
}
|
||||
}
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
for(auto it : children_) {
|
||||
widget *child = it;
|
||||
float cw, ch;
|
||||
tie(cw, ch) = child->get_min_dimensions();
|
||||
if(dir == HORIZONTAL) {
|
||||
children.push_back({child, x, y, cw, h});
|
||||
x += cw;
|
||||
} else {
|
||||
children.push_back({child, x, y, w, ch});
|
||||
y += ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h)
|
||||
{
|
||||
for(auto child : children) {
|
||||
child.widg->draw(now, to_screen, x + child.x, y + child.y, child.w, child.h);
|
||||
}
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(child.widg->drop(now, x - child.x, y - child.y, count, paths)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(child.widg->click(now, x - child.x, y - child.y)) {
|
||||
focus = child;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(x >= child.x && x < child.x + child.w && y >= child.y && y < child.y + child.h)
|
||||
child.widg->hover(now, x - child.x, y - child.y);
|
||||
}
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
focus.widg->click(now, x - focus.x, y - focus.y);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
focus.widg->release(now, x - focus.x, y - focus.y);
|
||||
focus = {nullptr, 0, 0};
|
||||
}
|
||||
};
|
||||
|
||||
void set(float v[4], float x, float y, float z, float w)
|
||||
{
|
||||
v[0] = x;
|
||||
|
267
ui_widgets.h
Normal file
267
ui_widgets.h
Normal file
@ -0,0 +1,267 @@
|
||||
#ifndef _UI_WIDGETS_H_
|
||||
#define _UI_WIDGETS_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
typedef std::pair<float, float> width_height;
|
||||
|
||||
struct widget
|
||||
{
|
||||
virtual width_height get_min_dimensions() const = 0;
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h) {};
|
||||
virtual bool click(double now, float x, float y) { return false; };
|
||||
virtual void hover(double now, float x, float y) {};
|
||||
virtual void drag(double now, float x, float y) {};
|
||||
virtual void release(double now, float x, float y) {};
|
||||
virtual bool drop(double now, float x, float y, int count, const char** paths) { return false; };
|
||||
};
|
||||
|
||||
struct switcher
|
||||
{
|
||||
float w, h;
|
||||
int which;
|
||||
std::vector<widget*> children;
|
||||
switcher(std::vector<widget*> children_) :
|
||||
w(0),
|
||||
h(0),
|
||||
which(0),
|
||||
children(children_)
|
||||
{
|
||||
for(auto it : children) {
|
||||
float cw, ch;
|
||||
std::tie(cw, ch) = it->get_min_dimensions();
|
||||
w = std::max(w, cw);
|
||||
h = std::max(h, ch);
|
||||
}
|
||||
}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h)
|
||||
{
|
||||
children[which]->draw(now, to_screen, x, y, w, h);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return children[which]->click(now, x, y);
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
children[which]->hover(now, x, y);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
children[which]->drag(now, x, y);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
children[which]->release(now, x, y);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char** paths)
|
||||
{
|
||||
return children[which]->drop(now, x, y, count, paths);
|
||||
}
|
||||
};
|
||||
|
||||
struct spacer : public widget
|
||||
{
|
||||
float w, h;
|
||||
spacer(float w_, float h_) :
|
||||
w(w_),
|
||||
h(h_)
|
||||
{}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
};
|
||||
|
||||
struct placed_widget
|
||||
{
|
||||
widget *widg;
|
||||
float x, y, w, h;
|
||||
};
|
||||
|
||||
struct padding : public widget
|
||||
{
|
||||
widget* child;
|
||||
float w, h;
|
||||
float left_pad, right_pad, top_pad, bottom_pad;
|
||||
float cw, ch;
|
||||
|
||||
padding(float left_pad_, float right_pad_, float top_pad_, float bottom_pad_, widget* child_) :
|
||||
child(child_),
|
||||
left_pad(left_pad_),
|
||||
right_pad(right_pad_),
|
||||
top_pad(top_pad_),
|
||||
bottom_pad(bottom_pad_)
|
||||
{
|
||||
std::tie(cw, ch) = child->get_min_dimensions();
|
||||
w = cw + left_pad_ + right_pad_;
|
||||
h = ch + top_pad_ + bottom_pad_;
|
||||
}
|
||||
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w_, float h_)
|
||||
{
|
||||
child->draw(now, to_screen, x + left_pad, y + top_pad, w_ - left_pad - right_pad, h_ - top_pad - bottom_pad);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
return child->drop(now, x + left_pad, y + top_pad, count, paths);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return child->click(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
child->hover(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
child->drag(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
child->release(now, x + left_pad, y + top_pad);
|
||||
}
|
||||
};
|
||||
|
||||
struct centering : public widget
|
||||
{
|
||||
float w, h;
|
||||
float cw, ch;
|
||||
widget* child;
|
||||
|
||||
centering(widget* child_) : child(child_)
|
||||
{
|
||||
std::tie(cw, ch) = child->get_min_dimensions();
|
||||
}
|
||||
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {cw, ch};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w_, float h_)
|
||||
{
|
||||
w = w_;
|
||||
h = h_;
|
||||
child->draw(now, to_screen, x + (w - cw) / 2, y + (h - ch) / 2, cw, ch);
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
return child->drop(now, x - (w - cw) / 2, y - (h - ch) / 2, count, paths);
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
return child->click(now, x - (w - cw) / 2, y - (h - ch) / 2); // XXX should limit to cw,ch too
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
child->hover(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
child->drag(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
child->release(now, x - (w - cw) / 2, y - (h - ch) / 2);
|
||||
}
|
||||
};
|
||||
|
||||
struct widgetbox : public widget
|
||||
{
|
||||
enum Direction {VERTICAL, HORIZONTAL} dir;
|
||||
float w, h;
|
||||
std::vector<placed_widget> children;
|
||||
placed_widget focus;
|
||||
|
||||
widgetbox(Direction dir_, std::vector<widget*> children_) :
|
||||
dir(dir_),
|
||||
w(0),
|
||||
h(0),
|
||||
focus({nullptr, 0, 0, 0, 0})
|
||||
{
|
||||
for(auto it : children_) {
|
||||
widget *child = it;
|
||||
float cw, ch;
|
||||
std::tie(cw, ch) = child->get_min_dimensions();
|
||||
if(dir == HORIZONTAL) {
|
||||
w += cw;
|
||||
h = std::max(h, ch);
|
||||
} else {
|
||||
w = std::max(w, cw);
|
||||
h += ch;
|
||||
}
|
||||
}
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
for(auto it : children_) {
|
||||
widget *child = it;
|
||||
float cw, ch;
|
||||
std::tie(cw, ch) = child->get_min_dimensions();
|
||||
if(dir == HORIZONTAL) {
|
||||
children.push_back({child, x, y, cw, h});
|
||||
x += cw;
|
||||
} else {
|
||||
children.push_back({child, x, y, w, ch});
|
||||
y += ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual width_height get_min_dimensions() const
|
||||
{
|
||||
return {w, h};
|
||||
}
|
||||
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h)
|
||||
{
|
||||
for(auto child : children) {
|
||||
child.widg->draw(now, to_screen, x + child.x, y + child.y, child.w, child.h);
|
||||
}
|
||||
}
|
||||
virtual bool drop(double now, float x, float y, int count, const char **paths)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(child.widg->drop(now, x - child.x, y - child.y, count, paths)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual bool click(double now, float x, float y)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(child.widg->click(now, x - child.x, y - child.y)) {
|
||||
focus = child;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void hover(double now, float x, float y)
|
||||
{
|
||||
for(auto child : children) {
|
||||
if(x >= child.x && x < child.x + child.w && y >= child.y && y < child.y + child.h)
|
||||
child.widg->hover(now, x - child.x, y - child.y);
|
||||
}
|
||||
}
|
||||
virtual void drag(double now, float x, float y)
|
||||
{
|
||||
focus.widg->click(now, x - focus.x, y - focus.y);
|
||||
}
|
||||
virtual void release(double now, float x, float y)
|
||||
{
|
||||
focus.widg->release(now, x - focus.x, y - focus.y);
|
||||
focus = {nullptr, 0, 0};
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _UI_WIDGETS_H_ */
|
Loading…
Reference in New Issue
Block a user