add widget containers and widget mouse picking
This commit is contained in:
parent
ec517fb455
commit
d69b2245b8
@ -9,6 +9,8 @@
|
||||
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
#include "math/math.hpp"
|
||||
|
||||
#include "input.hpp"
|
||||
#include "cursor.hpp"
|
||||
#include "framebuffer.hpp"
|
||||
@ -39,10 +41,12 @@ namespace cursor {
|
||||
|
||||
auto& data = data_fields.data;
|
||||
|
||||
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * 0.015;
|
||||
float dy = static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * -0.015;
|
||||
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * 0.015;
|
||||
float dy = static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * 0.015;
|
||||
state[port_ix].x += dx;
|
||||
state[port_ix].y += dy;
|
||||
state[port_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0;
|
||||
state[port_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0;
|
||||
|
||||
state[port_ix].active = true;
|
||||
} else if ((port.function_type & function_type::pointing) != 0 && port.host_response_data_transfer_ft9 != nullptr) {
|
||||
@ -51,13 +55,18 @@ namespace cursor {
|
||||
if ((std::byteswap(data_fields.function_type) & function_type::pointing) == 0)
|
||||
continue;
|
||||
auto& data = data_fields.data;
|
||||
float dx = static_cast<float>(data.analog_coordinate_axis[0] - 0x200) * 0.065;
|
||||
float dy = static_cast<float>(data.analog_coordinate_axis[1] - 0x200) * -0.065;
|
||||
float dx = static_cast<float>(data.analog_coordinate_axis[0] - 0x200) * 0.65;
|
||||
float dy = static_cast<float>(data.analog_coordinate_axis[1] - 0x200) * 0.65;
|
||||
state[port_ix].x += dx;
|
||||
state[port_ix].y += dy;
|
||||
state[port_ix].a = ft9::data_transfer::digital_button::a(data.digital_button) == 0;
|
||||
state[port_ix].b = ft9::data_transfer::digital_button::b(data.digital_button) == 0;
|
||||
|
||||
state[port_ix].active = true;
|
||||
}
|
||||
|
||||
state[port_ix].x = clamp<float>(state[port_ix].x, 0, framebuffer.px_width - 1);
|
||||
state[port_ix].y = clamp<float>(state[port_ix].y, 0, framebuffer.px_height - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@ namespace cursor {
|
||||
bool active;
|
||||
float x;
|
||||
float y;
|
||||
bool a;
|
||||
bool b;
|
||||
};
|
||||
|
||||
extern struct cursor state[4];
|
||||
|
70
src/main.cpp
70
src/main.cpp
@ -59,75 +59,6 @@ void vbr600()
|
||||
asm volatile ("ldc %0,sr" : : "r" (sr));
|
||||
}
|
||||
|
||||
/*
|
||||
void input_update()
|
||||
{
|
||||
int ra = ft0::data_transfer::digital_button::ra(data[0].digital_button) == 0;
|
||||
int la = ft0::data_transfer::digital_button::la(data[0].digital_button) == 0;
|
||||
int da = ft0::data_transfer::digital_button::da(data[0].digital_button) == 0;
|
||||
int ua = ft0::data_transfer::digital_button::ua(data[0].digital_button) == 0;
|
||||
|
||||
int x = ft0::data_transfer::digital_button::x(data[0].digital_button) == 0;
|
||||
int y = ft0::data_transfer::digital_button::y(data[0].digital_button) == 0;
|
||||
int a = ft0::data_transfer::digital_button::a(data[0].digital_button) == 0;
|
||||
int b = ft0::data_transfer::digital_button::b(data[0].digital_button) == 0;
|
||||
|
||||
static int last_ra = 0;
|
||||
static int last_la = 0;
|
||||
static int last_da = 0;
|
||||
static int last_ua = 0;
|
||||
|
||||
static int last_x = 0;
|
||||
static int last_y = 0;
|
||||
static int last_a = 0;
|
||||
static int last_b = 0;
|
||||
|
||||
if (ra && ra != last_ra) {
|
||||
sandbox_state.channel_ix += 1;
|
||||
if (sandbox_state.channel_ix > 63)
|
||||
sandbox_state.channel_ix = 0;
|
||||
}
|
||||
if (la && la != last_la) {
|
||||
sandbox_state.channel_ix -= 1;
|
||||
if (sandbox_state.channel_ix < 0)
|
||||
sandbox_state.channel_ix = 63;
|
||||
}
|
||||
if (da && da != last_da) {
|
||||
sandbox_state.pointer_row += 1;
|
||||
if (sandbox_state.pointer_row >= sandbox_labels_length)
|
||||
sandbox_state.pointer_row = 0;
|
||||
}
|
||||
if (ua && ua != last_ua) {
|
||||
sandbox_state.pointer_row -= 1;
|
||||
if (sandbox_state.pointer_row < 0)
|
||||
sandbox_state.pointer_row = sandbox_labels_length - 1;
|
||||
}
|
||||
|
||||
if (x && x != last_x) {
|
||||
label_update(-1);
|
||||
}
|
||||
if (y && y != last_y) {
|
||||
execute_key(0);
|
||||
}
|
||||
if (a && a != last_a) {
|
||||
execute_key(1);
|
||||
}
|
||||
if (b && b != last_b) {
|
||||
label_update(1);
|
||||
}
|
||||
|
||||
last_ra = ra;
|
||||
last_la = la;
|
||||
last_ua = ua;
|
||||
last_da = da;
|
||||
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
last_a = a;
|
||||
last_b = b;
|
||||
}
|
||||
*/
|
||||
|
||||
void load_xm(float clock_multiplier)
|
||||
{
|
||||
using namespace interpreter;
|
||||
@ -194,7 +125,6 @@ void main()
|
||||
//test_pattern();
|
||||
|
||||
interrupt_init();
|
||||
//channel_sandbox_defaults();
|
||||
|
||||
system.IML6NRM = istnrm::end_of_render_tsp
|
||||
| istnrm::v_blank_in
|
||||
|
@ -8,6 +8,50 @@
|
||||
#include "channel_status.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "widget/button.hpp"
|
||||
#include "widget/left_aligned.hpp"
|
||||
#include "widget/top_aligned.hpp"
|
||||
|
||||
#include "cursor.hpp"
|
||||
|
||||
void prev_click()
|
||||
{
|
||||
printf("prev\n");
|
||||
}
|
||||
|
||||
widget::button prev_button(50, 50, "prev", prev_click);
|
||||
widget::button play_button(50, 50, "play");
|
||||
widget::button pause_button(50, 50, "pause");
|
||||
widget::button stop_button(50, 50, "stop");
|
||||
widget::button next_button(50, 50, "next");
|
||||
|
||||
widget::widget * left1_children[] = {
|
||||
&prev_button,
|
||||
&play_button,
|
||||
&pause_button,
|
||||
&stop_button,
|
||||
&next_button,
|
||||
};
|
||||
int left1_length = (sizeof (left1_children)) / (sizeof (left1_children[0]));
|
||||
|
||||
widget::button up_button(50, 50, "up");
|
||||
widget::button down_button(50, 50, "down");
|
||||
|
||||
widget::widget * left2_children[] = {
|
||||
&up_button,
|
||||
&down_button,
|
||||
};
|
||||
int left2_length = (sizeof (left2_children)) / (sizeof (left2_children[0]));
|
||||
|
||||
widget::left_aligned left_container1(0, 0, 5, left1_children, left1_length);
|
||||
widget::left_aligned left_container2(0, 0, 5, left2_children, left2_length);
|
||||
|
||||
widget::widget * top_children[] = {
|
||||
&left_container1,
|
||||
&left_container2,
|
||||
};
|
||||
int top_length = (sizeof (top_children)) / (sizeof (top_children[0]));
|
||||
|
||||
widget::top_aligned top = widget::top_aligned(100, 100, 5, top_children, top_length);
|
||||
|
||||
namespace scene::tracker {
|
||||
|
||||
@ -25,10 +69,31 @@ namespace scene::tracker {
|
||||
.punch_through = 32 * 4
|
||||
},
|
||||
.transfer = transfer,
|
||||
.init = init,
|
||||
};
|
||||
|
||||
void init()
|
||||
{
|
||||
top.freeze(0, 0);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
cursor::cursor& c = cursor::state[i];
|
||||
if (c.active && c.a) {
|
||||
widget::widget * w = top.pick(c.x, c.y);
|
||||
if (w != nullptr) {
|
||||
w->click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transfer(ta_multiwriter& multi)
|
||||
{
|
||||
update();
|
||||
|
||||
const int x = 3;
|
||||
const int y = 100;
|
||||
|
||||
@ -69,7 +134,8 @@ namespace scene::tracker {
|
||||
|
||||
//tracker::channel_status::transfer(multi.op, 0, 0);
|
||||
|
||||
widget::button(60, 60, 50, 50, "test").draw(multi);
|
||||
}
|
||||
//test_container.draw(multi);
|
||||
top.draw(multi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,5 +8,7 @@ namespace scene::tracker {
|
||||
|
||||
void transfer(ta_multiwriter& multi);
|
||||
|
||||
void init();
|
||||
|
||||
extern const struct scene::scene scene;
|
||||
}
|
||||
|
@ -3,10 +3,35 @@
|
||||
namespace widget {
|
||||
|
||||
struct bounding_box {
|
||||
const float x;
|
||||
const float y;
|
||||
const float width;
|
||||
const float height;
|
||||
};
|
||||
float _x;
|
||||
float _y;
|
||||
float width;
|
||||
float height;
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
constexpr inline bounding_box(float __x, float __y, float _width, float _height)
|
||||
: _x(__x), _y(__y), width(_width), height(_height), dx(0), dy(0)
|
||||
{ }
|
||||
|
||||
constexpr inline float x()
|
||||
{
|
||||
return dx + _x;
|
||||
}
|
||||
|
||||
constexpr inline float y()
|
||||
{
|
||||
return dy + _y;
|
||||
}
|
||||
|
||||
constexpr inline bool inside(float __x, float __y)
|
||||
{
|
||||
return
|
||||
(__x >= x())
|
||||
&& (__y >= y())
|
||||
&& (__x <= (x() + width))
|
||||
&& (__y <= (y() + height))
|
||||
;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ namespace widget {
|
||||
const static float highlight_depth = 1.0 / 8.0;
|
||||
const static int highlight_color = 0x353a3a;
|
||||
|
||||
const static int highlight_click_color = 0x141616;
|
||||
|
||||
const static float background_depth = 1.0 / 7.0;
|
||||
const static int background_color = 0x282c2c;
|
||||
|
||||
@ -23,10 +25,10 @@ namespace widget {
|
||||
void button::draw_shadow(ta_parameter_writer& writer)
|
||||
{
|
||||
{
|
||||
float x0 = x + 1;
|
||||
float x1 = x + width - 1;
|
||||
float y0 = y;
|
||||
float y1 = y + height;
|
||||
float x0 = x() + 1;
|
||||
float x1 = x() + width - 1;
|
||||
float y0 = y();
|
||||
float y1 = y() + height;
|
||||
quad_type_0(writer,
|
||||
{x0, y0, shadow_depth},
|
||||
{x1, y0, shadow_depth},
|
||||
@ -35,10 +37,10 @@ namespace widget {
|
||||
shadow_color);
|
||||
}
|
||||
{
|
||||
float x0 = x;
|
||||
float x1 = x + width;
|
||||
float y0 = y + 1;
|
||||
float y1 = y + height - 1;
|
||||
float x0 = x();
|
||||
float x1 = x() + width;
|
||||
float y0 = y() + 1;
|
||||
float y1 = y() + height - 1;
|
||||
quad_type_0(writer,
|
||||
{x0, y0, shadow_depth},
|
||||
{x1, y0, shadow_depth},
|
||||
@ -50,10 +52,10 @@ namespace widget {
|
||||
|
||||
void button::draw_lowlight(ta_parameter_writer& writer)
|
||||
{
|
||||
float x0 = x + 1;
|
||||
float x1 = x + width - 1;
|
||||
float y0 = y + 1;
|
||||
float y1 = y + height - 1;
|
||||
float x0 = x() + 1;
|
||||
float x1 = x() + width - 1;
|
||||
float y0 = y() + 1;
|
||||
float y1 = y() + height - 1;
|
||||
quad_type_0(writer,
|
||||
{x0, y0, lowlight_depth},
|
||||
{x1, y0, lowlight_depth},
|
||||
@ -64,24 +66,26 @@ namespace widget {
|
||||
|
||||
void button::draw_highlight(ta_parameter_writer& writer)
|
||||
{
|
||||
float x0 = x + 1;
|
||||
float x1 = x + width - 2;
|
||||
float y0 = y + 1;
|
||||
float y1 = y + height - 2;
|
||||
float x0 = x() + 1;
|
||||
float x1 = x() + width - 2;
|
||||
float y0 = y() + 1;
|
||||
float y1 = y() + height - 2;
|
||||
|
||||
int color = (click_state == click_type::release) ? highlight_color : highlight_click_color;
|
||||
quad_type_0(writer,
|
||||
{x0, y0, highlight_depth},
|
||||
{x1, y0, highlight_depth},
|
||||
{x1, y1, highlight_depth},
|
||||
{x0, y1, highlight_depth},
|
||||
highlight_color);
|
||||
color);
|
||||
}
|
||||
|
||||
void button::draw_background(ta_parameter_writer& writer)
|
||||
{
|
||||
float x0 = x + 2;
|
||||
float x1 = x + width - 2;
|
||||
float y0 = y + 2;
|
||||
float y1 = y + height - 2;
|
||||
float x0 = x() + 2;
|
||||
float x1 = x() + width - 2;
|
||||
float y0 = y() + 2;
|
||||
float y1 = y() + height - 2;
|
||||
quad_type_0(writer,
|
||||
{x0, y0, background_depth},
|
||||
{x1, y0, background_depth},
|
||||
@ -92,8 +96,10 @@ namespace widget {
|
||||
|
||||
void button::draw_label(ta_parameter_writer& writer)
|
||||
{
|
||||
float cx = x + width / 2 - (glyph::hori_advance * label_length) / 2;
|
||||
float cy = y + height / 2 - glyph::vert_advance / 2;
|
||||
float y_offset = (float)(click_state != click_type::release);
|
||||
|
||||
float cx = x() + width / 2 - (glyph::hori_advance * label_length) / 2;
|
||||
float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset;
|
||||
|
||||
transfer_string(writer, label, cx, cy, label_depth, label_color);
|
||||
}
|
||||
@ -115,5 +121,15 @@ namespace widget {
|
||||
transfer_global_polygon_glyph(multi.pt);
|
||||
|
||||
draw_label(multi.pt);
|
||||
|
||||
widget::draw(multi);
|
||||
}
|
||||
|
||||
void button::click()
|
||||
{
|
||||
if (click_state == click_type::release && on_click != nullptr)
|
||||
on_click();
|
||||
|
||||
widget::click();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "holly/ta_parameter.hpp"
|
||||
#include "ta_multiwriter.hpp"
|
||||
#include "widget/bounding_box.hpp"
|
||||
#include "widget/widget.hpp"
|
||||
|
||||
namespace widget {
|
||||
|
||||
@ -15,20 +15,34 @@ namespace widget {
|
||||
return l;
|
||||
}
|
||||
|
||||
struct button : bounding_box {
|
||||
struct button : widget {
|
||||
const char * const label;
|
||||
const int label_length;
|
||||
void (* const on_click)();
|
||||
|
||||
button(float _x, float _y, float _width, float _height, const char * _label)
|
||||
: bounding_box(_x, _y, _width, _height), label(_label), label_length(str_length(_label))
|
||||
{
|
||||
}
|
||||
inline button(float _width, float _height, const char * _label)
|
||||
: widget(0, 0, _width, _height), label(_label), label_length(str_length(_label)), on_click(nullptr)
|
||||
{ }
|
||||
|
||||
inline button(float _width, float _height, const char * _label, void (* const _on_click)())
|
||||
: widget(0, 0, _width, _height), label(_label), label_length(str_length(_label)), on_click(_on_click)
|
||||
{ }
|
||||
|
||||
inline button(float _x, float _y, float _width, float _height, const char * _label)
|
||||
: widget(_x, _y, _width, _height), label(_label), label_length(str_length(_label)), on_click(nullptr)
|
||||
{ }
|
||||
|
||||
inline button(float _x, float _y, float _width, float _height, const char * _label, void (* const _on_click)())
|
||||
: widget(_x, _y, _width, _height), label(_label), label_length(str_length(_label)), on_click(_on_click)
|
||||
{ }
|
||||
|
||||
void draw_shadow(ta_parameter_writer& writer);
|
||||
void draw_lowlight(ta_parameter_writer& writer);
|
||||
void draw_highlight(ta_parameter_writer& writer);
|
||||
void draw_background(ta_parameter_writer& writer);
|
||||
void draw_label(ta_parameter_writer& writer);
|
||||
void draw(ta_multiwriter& multi);
|
||||
void draw(ta_multiwriter& multi) override;
|
||||
|
||||
void click() override;
|
||||
};
|
||||
}
|
||||
|
47
src/widget/container.hpp
Normal file
47
src/widget/container.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "printf/printf.h"
|
||||
|
||||
namespace widget {
|
||||
|
||||
struct container : widget {
|
||||
widget ** children;
|
||||
int length;
|
||||
|
||||
inline container(float _x, float _y, float _width, float _height,
|
||||
widget ** _children, int _length)
|
||||
: widget(_x, _y, _width, _height), children(_children), length(_length)
|
||||
{}
|
||||
|
||||
inline void freeze(float _dx, float _dy)
|
||||
{
|
||||
dx = _dx;
|
||||
dy = _dy;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
children[i]->freeze(x(), y());
|
||||
}
|
||||
}
|
||||
|
||||
void draw(ta_multiwriter& multi)
|
||||
{
|
||||
for (int i = 0; i < length; i++) {
|
||||
children[i]->draw(multi);
|
||||
}
|
||||
}
|
||||
|
||||
inline widget * pick(float _x, float _y)
|
||||
{
|
||||
if (!inside(_x, _y))
|
||||
return nullptr;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
widget * w = children[i]->pick(_x, _y);
|
||||
if (w != nullptr)
|
||||
return w;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
}
|
23
src/widget/left_aligned.hpp
Normal file
23
src/widget/left_aligned.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "widget/container.hpp"
|
||||
|
||||
namespace widget {
|
||||
|
||||
struct left_aligned : container {
|
||||
|
||||
inline left_aligned(float _x, float _y, float gap, widget ** _children, int _length)
|
||||
: container(_x, _y, 0, 0, _children, _length)
|
||||
{
|
||||
float xi = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
children[i]->_x = xi;
|
||||
children[i]->_y = 0;
|
||||
xi += children[i]->width + gap;
|
||||
if (children[i]->height > height)
|
||||
height = children[i]->height;
|
||||
}
|
||||
width = xi;
|
||||
}
|
||||
};
|
||||
}
|
23
src/widget/top_aligned.hpp
Normal file
23
src/widget/top_aligned.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "widget/container.hpp"
|
||||
|
||||
namespace widget {
|
||||
|
||||
struct top_aligned : container {
|
||||
|
||||
inline top_aligned(float _x, float _y, float gap, widget ** _children, int _length)
|
||||
: container(_x, _y, 0, 0, _children, _length)
|
||||
{
|
||||
float yi = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
children[i]->_x = 0;
|
||||
children[i]->_y = yi;
|
||||
yi += children[i]->height + gap;
|
||||
if (children[i]->width > width)
|
||||
width = children[i]->width;
|
||||
}
|
||||
height = yi;
|
||||
}
|
||||
};
|
||||
}
|
50
src/widget/widget.hpp
Normal file
50
src/widget/widget.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "widget/bounding_box.hpp"
|
||||
#include "ta_multiwriter.hpp"
|
||||
|
||||
#include "printf/printf.h"
|
||||
|
||||
namespace widget {
|
||||
|
||||
enum class click_type {
|
||||
press,
|
||||
down,
|
||||
release,
|
||||
};
|
||||
|
||||
struct widget : bounding_box {
|
||||
protected:
|
||||
click_type click_state;
|
||||
|
||||
public:
|
||||
inline widget(float _x, float _y, float _width, float _height)
|
||||
: bounding_box(_x, _y, _width, _height), click_state(click_type::release)
|
||||
{ }
|
||||
|
||||
inline virtual void draw(ta_multiwriter& multi)
|
||||
{
|
||||
if (click_state == click_type::press)
|
||||
click_state = click_type::down;
|
||||
else if (click_state == click_type::down)
|
||||
click_state = click_type::release;
|
||||
}
|
||||
|
||||
inline virtual void freeze(float _dx, float _dy)
|
||||
{
|
||||
dx = _dx;
|
||||
dy = _dy;
|
||||
}
|
||||
|
||||
inline virtual widget * pick(float _x, float _y)
|
||||
{
|
||||
if (inside(_x, _y))
|
||||
return this;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline virtual void click()
|
||||
{
|
||||
click_state = click_type::press;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user