Basic painting and invalidation systems work.
This commit is contained in:
parent
597b7c26e4
commit
ced7886a10
@ -6,6 +6,7 @@ namespace sharp
|
|||||||
{
|
{
|
||||||
enum window_flags : uint32_t
|
enum window_flags : uint32_t
|
||||||
{
|
{
|
||||||
WINDOW_ACTIVE = 1,
|
CONTINUOUS_PAINT = 0x01,
|
||||||
|
CONTINUOUS_TICK = 0x02,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ namespace sharp
|
|||||||
static const global_properties defaults;
|
static const global_properties defaults;
|
||||||
|
|
||||||
color background_color;
|
color background_color;
|
||||||
|
float refresh_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef SHARPSOFT_INTERNAL
|
#ifdef SHARPSOFT_INTERNAL
|
||||||
|
#include "basic_types.hpp"
|
||||||
#include "window_types.hpp"
|
#include "window_types.hpp"
|
||||||
|
|
||||||
|
#define HAS_WINDOW_FLAG(pwin, flag) ((pwin->flags & flag) > 0)
|
||||||
|
|
||||||
namespace sharp
|
namespace sharp
|
||||||
{
|
{
|
||||||
namespace internal
|
namespace internal
|
||||||
@ -11,6 +14,9 @@ namespace sharp
|
|||||||
|
|
||||||
void render_iter();
|
void render_iter();
|
||||||
void render_loop();
|
void render_loop();
|
||||||
|
|
||||||
|
void draw_global_rectangle(const color& color, const int_rect& rect);
|
||||||
|
void fill_global_rectangle(const color& color, const int_rect& rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "sharpsoft/basic_types.hpp"
|
#include "sharpsoft/basic_types.hpp"
|
||||||
@ -9,32 +10,47 @@ namespace sharp
|
|||||||
{
|
{
|
||||||
class window_base
|
class window_base
|
||||||
{
|
{
|
||||||
|
#ifdef SHARPSOFT_INTERNAL
|
||||||
|
public:
|
||||||
|
#else
|
||||||
private:
|
private:
|
||||||
|
#endif
|
||||||
uint16_t posX, posY;
|
uint16_t posX, posY;
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
std::string title;
|
std::string title;
|
||||||
window_flags flags;
|
window_flags flags;
|
||||||
|
bool active, visible;
|
||||||
|
|
||||||
|
bool header_validated;
|
||||||
|
bool content_validated;
|
||||||
|
|
||||||
|
void paint_header();
|
||||||
|
|
||||||
|
#ifndef SHARPSOFT_INTERNAL
|
||||||
protected:
|
protected:
|
||||||
|
#endif
|
||||||
window_base(const std::string& title, const int2& pos, const int2& size);
|
window_base(const std::string& title, const int2& pos, const int2& size);
|
||||||
|
|
||||||
#ifdef SHARPSOFT_INTERNAL
|
|
||||||
public:
|
|
||||||
#endif
|
|
||||||
virtual void paint() = 0;
|
virtual void paint() = 0;
|
||||||
|
virtual void tick() = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool get_flag(window_flags flag) const;
|
||||||
const int2 get_pos() const;
|
const int2 get_pos() const;
|
||||||
const int2 get_size() const;
|
const int2 get_size() const;
|
||||||
const int_rect get_window_rect() const;
|
const int_rect get_window_rect() const;
|
||||||
const std::string get_title() const;
|
const std::string get_title() const;
|
||||||
const bool is_active() const;
|
bool is_active() const;
|
||||||
|
bool is_visible() const;
|
||||||
|
|
||||||
|
void set_flag(window_flags flag, bool value);
|
||||||
void set_pos(const int2& new_pos);
|
void set_pos(const int2& new_pos);
|
||||||
void set_size(const int2& new_size);
|
void set_size(const int2& new_size);
|
||||||
void set_window_rect(const int_rect& new_rect);
|
void set_window_rect(const int_rect& new_rect);
|
||||||
void set_title(const std::string& new_title);
|
void set_title(const std::string& new_title);
|
||||||
|
|
||||||
|
void invalidate();
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
void hide();
|
void hide();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,13 +9,17 @@ class test_window : public sharp::window_base
|
|||||||
protected:
|
protected:
|
||||||
void paint() override
|
void paint() override
|
||||||
{
|
{
|
||||||
printf("Printed: %d\n", test_variable);
|
printf("Paint called.\n");
|
||||||
|
}
|
||||||
|
void tick() override
|
||||||
|
{
|
||||||
|
printf("Tick called.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
test_window() : window_base("Testing", sharp::int2(10, 10), sharp::int2(150, 100))
|
test_window() : window_base("Testing", sharp::int2(10, 10), sharp::int2(150, 100))
|
||||||
{
|
{
|
||||||
|
set_flag(sharp::CONTINUOUS_TICK, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_variable;
|
int test_variable;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#include "pros/rtos.hpp"
|
|
||||||
#define SHARPSOFT_INTERNAL
|
#define SHARPSOFT_INTERNAL
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "sharpsoft/enums.hpp"
|
||||||
#include "sharpsoft/global_misc.hpp"
|
#include "sharpsoft/global_misc.hpp"
|
||||||
#include "sharpsoft/internal.hpp"
|
#include "sharpsoft/internal.hpp"
|
||||||
#include "sharpsoft/interop.hpp"
|
#include "sharpsoft/interop.hpp"
|
||||||
@ -12,12 +12,14 @@ using std::vector;
|
|||||||
|
|
||||||
const global_properties global_properties::defaults =
|
const global_properties global_properties::defaults =
|
||||||
{
|
{
|
||||||
0x95d9ed
|
0x95d9ed,
|
||||||
|
20,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init = false;
|
bool init = false;
|
||||||
bool started = false;
|
bool started = false;
|
||||||
color back_col;
|
color back_col;
|
||||||
|
int render_wait_ms;
|
||||||
thread* render_thread = nullptr;
|
thread* render_thread = nullptr;
|
||||||
|
|
||||||
vector<window_base*> windows;
|
vector<window_base*> windows;
|
||||||
@ -31,6 +33,7 @@ void sharp::initialize(const global_properties& props)
|
|||||||
if (init) return;
|
if (init) return;
|
||||||
|
|
||||||
back_col = props.background_color;
|
back_col = props.background_color;
|
||||||
|
render_wait_ms = 1000 / props.refresh_rate;
|
||||||
|
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
@ -70,18 +73,41 @@ bool sharp::is_initialized()
|
|||||||
void sharp::internal::render_iter()
|
void sharp::internal::render_iter()
|
||||||
{
|
{
|
||||||
int window_count = windows.size();
|
int window_count = windows.size();
|
||||||
|
|
||||||
|
// The way windows are ordered in the vector represents
|
||||||
|
// the rendering order. More recent pushes (so further
|
||||||
|
// down the list) have a higher order.
|
||||||
for (int i = 0; i < window_count; i++)
|
for (int i = 0; i < window_count; i++)
|
||||||
{
|
{
|
||||||
window_base* win = windows.at(i);
|
window_base* win = windows.at(i);
|
||||||
|
// First handle special stuff.
|
||||||
|
|
||||||
|
// Now tick the window if applicable.
|
||||||
|
if (HAS_WINDOW_FLAG(win, CONTINUOUS_TICK)) win->tick();
|
||||||
|
|
||||||
|
// Apply any possible invalidations.
|
||||||
|
if (HAS_WINDOW_FLAG(win, CONTINUOUS_PAINT)) win->content_validated = false;
|
||||||
|
|
||||||
|
// Now render anything that is invalidated.
|
||||||
|
if (!win->content_validated)
|
||||||
|
{
|
||||||
win->paint();
|
win->paint();
|
||||||
|
win->content_validated = true;
|
||||||
|
}
|
||||||
|
if (!win->header_validated)
|
||||||
|
{
|
||||||
|
win->paint_header();
|
||||||
|
win->header_validated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void sharp::internal::render_loop()
|
void sharp::internal::render_loop()
|
||||||
{
|
{
|
||||||
|
thread::delay(50); // Wait a sec for the screen to be ready.
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
render_iter();
|
render_iter();
|
||||||
thread::delay(100); // TODO: should be something else.
|
thread::delay(render_wait_ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +118,7 @@ void sharp::internal::add_window(window_base* win_ptr, size_t size)
|
|||||||
|
|
||||||
window_base* copy = (window_base*)copy_raw;
|
window_base* copy = (window_base*)copy_raw;
|
||||||
windows.push_back(copy);
|
windows.push_back(copy);
|
||||||
|
copy->active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sharp::start()
|
void sharp::start()
|
||||||
|
|||||||
31
src/sharpsoft/rendering.cpp
Normal file
31
src/sharpsoft/rendering.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#define SHARPSOFT_INTERNAL
|
||||||
|
|
||||||
|
#include "sharpsoft/internal.hpp"
|
||||||
|
#include "sharpsoft/macros.hpp"
|
||||||
|
#include "sharpsoft/window_types.hpp"
|
||||||
|
|
||||||
|
#ifdef SH_PROS_ACTIVE
|
||||||
|
#include "pros/screen.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace sharp;
|
||||||
|
|
||||||
|
#ifdef SH_PROS_ACTIVE
|
||||||
|
void internal::draw_global_rectangle(const color& color, const int_rect& rect)
|
||||||
|
{
|
||||||
|
pros::screen::set_pen(color.get_value());
|
||||||
|
pros::screen::draw_rect(rect.left, rect.top, rect.left + rect.width - 1, rect.top + rect.height - 1);
|
||||||
|
}
|
||||||
|
void internal::fill_global_rectangle(const color& color, const int_rect& rect)
|
||||||
|
{
|
||||||
|
pros::screen::set_pen(color.get_value());
|
||||||
|
pros::screen::fill_rect(rect.left, rect.top, rect.left + rect.width - 1, rect.top + rect.height - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void window_base::paint_header()
|
||||||
|
{
|
||||||
|
// Draw outline.
|
||||||
|
const color outline_color = color(255, 255, 255);
|
||||||
|
internal::draw_global_rectangle(outline_color, int_rect(posX - 1, posY - 1, width + 1, height + 1));
|
||||||
|
}
|
||||||
@ -10,10 +10,19 @@ sharp::window_base::window_base(const string& title, const int2& pos, const int2
|
|||||||
posX = pos.x;
|
posX = pos.x;
|
||||||
posY = pos.y;
|
posY = pos.y;
|
||||||
width = size.x;
|
width = size.x;
|
||||||
width = size.y;
|
height = size.y;
|
||||||
flags = (window_flags)0;
|
flags = (window_flags)0;
|
||||||
|
active = false;
|
||||||
|
visible = true;
|
||||||
|
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sharp::window_base::get_flag(window_flags flag) const
|
||||||
|
{
|
||||||
|
return (flags & flag) > 0;
|
||||||
|
}
|
||||||
const int2 sharp::window_base::get_pos() const
|
const int2 sharp::window_base::get_pos() const
|
||||||
{
|
{
|
||||||
return int2(posX, posY);
|
return int2(posX, posY);
|
||||||
@ -30,45 +39,79 @@ const string sharp::window_base::get_title() const
|
|||||||
{
|
{
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
const bool sharp::window_base::is_active() const
|
bool sharp::window_base::is_active() const
|
||||||
{
|
{
|
||||||
return (flags & WINDOW_ACTIVE) > 0;
|
return active;
|
||||||
|
}
|
||||||
|
bool sharp::window_base::is_visible() const
|
||||||
|
{
|
||||||
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sharp::window_base::set_flag(window_flags flag, bool value)
|
||||||
|
{
|
||||||
|
switch (flag)
|
||||||
|
{
|
||||||
|
case CONTINUOUS_PAINT:
|
||||||
|
case CONTINUOUS_TICK:
|
||||||
|
break; // No invalidation.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) flags = (window_flags)(flags | flag);
|
||||||
|
else flags = (window_flags)(flags & ~flag);
|
||||||
|
}
|
||||||
void sharp::window_base::set_pos(const int2& new_pos)
|
void sharp::window_base::set_pos(const int2& new_pos)
|
||||||
{
|
{
|
||||||
// TODO: I'll have to re-render some parts.
|
// TODO: This will affect windows below it.
|
||||||
|
|
||||||
posX = new_pos.x;
|
posX = new_pos.x;
|
||||||
posY = new_pos.y;
|
posY = new_pos.y;
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
void sharp::window_base::set_size(const int2& new_pos)
|
void sharp::window_base::set_size(const int2& new_pos)
|
||||||
{
|
{
|
||||||
// TODO: I'll have to re-render some parts.
|
// TODO: This will affect windows below it.
|
||||||
|
|
||||||
width = new_pos.x;
|
width = new_pos.x;
|
||||||
height = new_pos.y;
|
height = new_pos.y;
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
void sharp::window_base::set_window_rect(const int_rect& new_rect)
|
void sharp::window_base::set_window_rect(const int_rect& new_rect)
|
||||||
{
|
{
|
||||||
// TODO: I'll have to re-render some parts.
|
// TODO: This will affect windows below it.
|
||||||
|
|
||||||
posX = new_rect.left;
|
posX = new_rect.left;
|
||||||
posY = new_rect.top;
|
posY = new_rect.top;
|
||||||
width = new_rect.width;
|
width = new_rect.width;
|
||||||
height = new_rect.height;
|
height = new_rect.height;
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
void sharp::window_base::set_title(const std::string& new_title)
|
void sharp::window_base::set_title(const std::string& new_title)
|
||||||
{
|
{
|
||||||
title = new_title;
|
title = new_title;
|
||||||
|
header_validated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sharp::window_base::invalidate()
|
||||||
|
{
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sharp::window_base::hide()
|
void sharp::window_base::hide()
|
||||||
{
|
{
|
||||||
// TODO: This will affect the renderer
|
// TODO: This will affect the renderer
|
||||||
|
|
||||||
flags = (window_flags)(flags & ~WINDOW_ACTIVE);
|
visible = false;
|
||||||
}
|
}
|
||||||
void sharp::window_base::show()
|
void sharp::window_base::show()
|
||||||
{
|
{
|
||||||
// TODO: This will affect the renderer
|
// TODO: This will affect the renderer
|
||||||
|
|
||||||
flags = (window_flags)(flags | WINDOW_ACTIVE);
|
visible = true;
|
||||||
|
header_validated = false;
|
||||||
|
content_validated = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user