Compare commits

...

4 commits

Author SHA1 Message Date
24d6e756ee refactor naming 2021-02-24 20:37:27 +01:00
e0181cc3e8 add integer debugging 2018-12-04 13:20:42 +01:00
a759cabb5b Merge branch 'master' into jedi/dev 2018-12-04 13:13:49 +01:00
6091a40278 add inverted text 2018-12-01 20:26:05 +01:00
32 changed files with 635 additions and 590 deletions

View file

@ -1,7 +1,7 @@
TARGET = main
SRC = hal.cpp main.cpp example.cpp buttons.cpp
SRC += gfx/screen.cpp gfx/canvas.cpp gfx/font.cpp gfx/layout.cpp gfx/buffer.cpp
SRC += gfx/Screen.cpp gfx/Canvas.cpp gfx/Font.cpp gfx/Layout.cpp gfx/Buffer.cpp
SRC += fonts/basic_5x4.cpp

View file

@ -2,27 +2,30 @@
// Created by jedi on 11/6/18.
//
#ifndef MGL_DMXMENU_INPUT_H
#define MGL_DMXMENU_INPUT_H
#pragma once
namespace micromenu {
enum direction {
I_LEFT = 0,
I_RIGHT,
I_UP,
I_DOWN
};
class buttons {
private:
static void onPush(direction id, bool state);
public:
bool raw[4] = {false, false, false, false};
bool last[4] = {false, false, false, false};
void poll();
};
#define I_LEFT 0
#define I_RIGHT 1
#define I_UP 2
#define I_DOWN 3
extern buttons input;
class buttons {
private:
void onPush(int id, bool state);
public:
bool raw[4]={false,false, false, false};
bool last[4]={false,false, false, false};
void poll();
};
extern buttons input;
#endif //MGL_DMXMENU_INPUT_H
}

View file

@ -2,33 +2,38 @@
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#include "gfx/canvas.h"
#include "gfx/Canvas.h"
#include "node.h"
class menu : public node {
public:
template<typename ... Args>
menu(Args ... ns) : node(ns...) {
}
using canvas = micromenu::Canvas;
using node = micromenu::node;
using value = micromenu::value;
void render(canvas &c);
class menu : public node {
public:
template<typename ... Args>
explicit menu(Args ... ns) : node(ns...) {
}
void render(canvas &c) override;
};
class fooValue : public value {
public:
fooValue(const char* str, int val) : value(str, val, 32, 48) {
}
public:
fooValue(const char *str, int val) : value(str, val, 32, 48) {
}
void render(canvas &c);
void render(canvas &c) override;
};
class blubValue : public value{
public:
template<typename ... Args>
blubValue(Args ... ns) : value(ns..., 64, 96) {
}
void render(canvas& c);
class blubValue : public value {
public:
template<typename ... Args>
explicit blubValue(Args ... ns) : value(ns..., 64, 96) {
}
void render(canvas &c) override;
};
#endif

View file

@ -2,11 +2,11 @@
// Created by jedi on 11/2/18.
//
#ifndef MGL_DMXMENU_BASIC_5X4_H
#define MGL_DMXMENU_BASIC_5X4_H
#pragma once
#include "gfx/font.h"
#include "gfx/Font.h"
extern font basic_5x4;
namespace micromenu {
extern Font basic_5x4;
}
#endif //MGL_DMXMENU_BASIC_5X4_H

54
inc/gfx/Buffer.h Normal file
View file

@ -0,0 +1,54 @@
//
// Created by jedi on 11/2/18.
//
#include <cstdlib>
#include <cstdint>
namespace micromenu {
enum bufferBlocks {
_1bit = 1, _2bit = 2, _4bit = 4, _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32
};
template<bufferBlocks N>
class Buffer {
private:
int *ptr_;
int size_;
constexpr static const int block_ = 8 * sizeof(int);
public:
Buffer(int size) : size_(size) {
ptr_ = (int *) malloc(size * N / 8);
}
int get(int i) {
if(i >= size_) return 0;
return ptr_[i * N / block_] & ((1 << N) - 1) << (i * N % block_);
}
int getBlock(int i) {
if(i >= size_) return 0;
return ptr_[i * N / block_];
}
void set(int i, int v) {
if(i < size_) {
ptr_[i * N / block_] &= ~(((1 << N) - 1) << (i * N % block_));
ptr_[i * N / block_] |= (((1 << N) - 1) & v) << (i * N % block_);
}
}
~Buffer() {
free(ptr_);
}
};
template<>
int Buffer<_32bit>::get(int i);
template<>
void Buffer<_32bit>::set(int i, int v);
}

42
inc/gfx/Canvas.h Normal file
View file

@ -0,0 +1,42 @@
//
// Created by jedi on 11/1/18.
//
#pragma once
#include "hal/hal.h"
#include "gfx/Font.h"
#include "fonts/basic_5x4.h"
#include "gfx/Buffer.h"
namespace micromenu {
class Screen;
class Canvas {
private:
const int width_;
const int height_;
Buffer<_1bit> buffer_;
void draw_onto_(Screen &);
public:
Canvas(int w, int h);
void clear();
void draw(int x, int y, bool inv = false);
void print(int x, int y, const char *str, bool inv = false, Font & = basic_5x4);
void print(int x, int y, char *str, bool inv = false, Font & = basic_5x4);
int getWidth();
int getHeight();
friend Screen;
};
}

27
inc/gfx/Font.h Normal file
View file

@ -0,0 +1,27 @@
//
// Created by jedi on 11/1/18.
//
#pragma once
namespace micromenu {
class Canvas;
class Font {
public:
typedef const bool raw_font[32][20];
private:
raw_font &raw_data_;
public:
explicit Font(raw_font &) noexcept;
void print(int x, int y, char c, Canvas &, bool inv = false);
void print(int x, int y, char *str, Canvas &, bool inv = false);
void print(int x, int y, const char *str, Canvas &, bool inv = false);
};
}

49
inc/gfx/Layout.h Normal file
View file

@ -0,0 +1,49 @@
//
// Created by jedi on 11/5/18.
//
#pragma once
#include "gfx/Canvas.h"
#include "gfx/Screen.h"
namespace micromenu {
class Layout {
class Slot {
private:
int pos_ = 0;
int size_ = 0;
Canvas *canvas_ = nullptr;
public:
node *content = nullptr;
friend Layout;
};
private:
const int maxwidth_;
const int maxheight_;
int allocated_ = 0;
Screen &screen_;
int allocate_(node *, int);
int expand_(int);
int pack_(int);
public:
static const int maxslots = 10;
Slot slots[maxslots];
node *cursor = nullptr;
explicit Layout(Screen &s) noexcept: maxwidth_(s.getWidth()), maxheight_(s.getHeight()), screen_(s) {
}
int apply(node *);
void render();
};
}

38
inc/gfx/Screen.h Normal file
View file

@ -0,0 +1,38 @@
//
// Created by jedi on 11/1/18.
//
#pragma once
#include "hal/hal.h"
#include "gfx/Canvas.h"
namespace micromenu {
class Screen {
private:
const int width_;
const int height_;
public:
explicit Screen(int w, int h) noexcept;
void draw(int x, int y);
void draw(int x, int y, Canvas &c);
void print(int x, int y, const char *str, Font & = basic_5x4);
void print(int x, int y, char *str, Font & = basic_5x4);
[[nodiscard]] int getWidth() const{
return width_;
}
[[nodiscard]] int getHeight() const{
return height_;
}
};
}

View file

@ -1,50 +0,0 @@
//
// Created by jedi on 11/2/18.
//
#ifndef MGL_DMXMENU_BUFFER_1_H
#define MGL_DMXMENU_BUFFER_1_H
#include <stdlib.h>
#include <stdint.h>
enum bufferBlocks{
_1bit = 1, _2bit = 2, _4bit = 4, _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32
};
template <bufferBlocks N>
class buffer {
private:
int *ptr_;
int size_;
constexpr static const int block_ = 8 * sizeof(int);
public:
buffer(int size) : size_(size) {
ptr_ = (int *) malloc(size * N / 8);
}
int get(int i) {
if (i >= size_) return 0;
return ptr_[i*N/block_] & ((1<<N)-1) << (i*N%block_);
}
void set(int i, int v) {
if (i < size_) {
ptr_[i*N/block_] &= ~(((1<<N)-1) << (i*N%block_));
ptr_[i*N/block_] |= (((1<<N)-1)&v) << (i*N%block_);
}
}
~buffer() {
free(ptr_);
}
};
template <>
int buffer<_32bit>::get(int i);
template <>
void buffer<_32bit>::set(int i, int v);
#endif //MGL_DMXMENU_BUFFER_1_H

View file

@ -1,42 +0,0 @@
//
// Created by jedi on 11/1/18.
//
#ifndef MGL_DMXMENU_CANVAS_H
#define MGL_DMXMENU_CANVAS_H
#include "hal/hal.h"
#include "gfx/font.h"
#include "fonts/basic_5x4.h"
#include "gfx/buffer.h"
class screen;
class canvas {
private:
const int width_;
const int height_;
buffer<_1bit> buffer_;
void draw_onto_(screen &);
public:
canvas(int w, int h);
void clear();
void draw(int x, int y);
void print(int x, int y, const char *str, font & = basic_5x4);
void print(int x, int y, char *str, font & = basic_5x4);
int getWidth();
int getHeight();
friend screen;
};
#endif //MGL_DMXMENU_CANVAS_H

View file

@ -1,22 +0,0 @@
//
// Created by jedi on 11/1/18.
//
#ifndef MGL_DMXMENU_FONT_H
#define MGL_DMXMENU_FONT_H
class canvas;
class font {
public:
typedef const bool raw_font[32][20];
private:
raw_font& raw_data_;
public:
font(raw_font&);
void print(int x, int y, char c, canvas&);
void print(int x, int y, char* str, canvas&);
void print(int x, int y, const char* str, canvas&);
};
#endif //MGL_DMXMENU_FONT_H

View file

@ -1,51 +0,0 @@
//
// Created by jedi on 11/5/18.
//
#ifndef MGL_DMXMENU_LAYOUT_H
#define MGL_DMXMENU_LAYOUT_H
#include "gfx/canvas.h"
#include "gfx/screen.h"
class layout {
class Slot {
private:
int pos_ = 0;
int size_ = 0;
canvas *canvas_ = nullptr;
public:
node *content = nullptr;
friend layout;
};
private:
const int maxwidth_;
const int maxheight_;
int allocated_;
screen& screen_;
int allocate_(node *, int);
int expand_(int);
int pack_(int);
public:
static const int maxslots = 10;
Slot slots[maxslots];
node *cursor;
layout(screen& s) : maxwidth_(s.getWidth()), maxheight_(s.getHeight()), screen_(s) {
}
int apply(node *);
void render();
};
#endif //MGL_DMXMENU_LAYOUT_H

View file

@ -1,34 +0,0 @@
//
// Created by jedi on 11/1/18.
//
#ifndef MGL_DMXMENU_SCREEN_H
#define MGL_DMXMENU_SCREEN_H
#include "hal/hal.h"
#include "gfx/canvas.h"
class screen {
private:
const int width_;
const int height_;
public:
screen(int w, int h);
void draw(int x, int y);
void draw(int x, int y, canvas &c);
void print(int x, int y, const char *str, font & = basic_5x4);
void print(int x, int y, char *str, font & = basic_5x4);
int getWidth();
int getHeight();
};
#endif //MGL_DMXMENU_SCREEN_H

View file

@ -3,11 +3,12 @@
#define _HAL_H_
void debug(int);
void debug(const char* str);
void hal_init_screen(int w, int h);
void hal_poll_input(bool *ptr);
void hal_draw(int x, int y);
void hal_clear();
void hal_draw(int x, int y, int b);
void hal_render();
void render();

View file

@ -2,82 +2,84 @@
// Created by jedi on 11/5/18.
//
#ifndef MGL_DMXMENU_NODE_H
#define MGL_DMXMENU_NODE_H
#pragma once
#include "gfx/canvas.h"
#include "gfx/Canvas.h"
class node {
private:
node *parent_ = nullptr;
node *child_ = nullptr;
node *cursor_ = nullptr;
node *next_ = nullptr;
namespace micromenu {
void addNodes(bool b) {
}
class node {
private:
node *parent_ = nullptr;
node *child_ = nullptr;
node *cursor_ = nullptr;
node *next_ = nullptr;
template<class ...Us>
void addNodes(bool b, node *n, Us ... ns) {
next_ = n;
next_->parent_ = parent_;
next_->addNodes(!b, ns...);
}
void addNodes(bool b) {
}
public:
const char *title_ = 0;
const int minsize;
const int maxsize;
template<class ...Us>
void addNodes(bool b, node *n, Us ... ns) {
next_ = n;
next_->parent_ = parent_;
next_->addNodes(!b, ns...);
}
virtual void render(canvas &c) = 0;
public:
const char *title_ = 0;
const int minsize;
const int maxsize;
explicit node(int min = 24, int max = 48) : next_(nullptr), child_(nullptr), parent_(nullptr), minsize(min),
maxsize(max) {
}
virtual void render(Canvas &c) = 0;
explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max), next_(nullptr),
child_(nullptr),
parent_(nullptr) {
}
explicit node(int min = 24, int max = 48) : next_(nullptr), child_(nullptr), parent_(nullptr), minsize(min),
maxsize(max) {
}
template<typename ... Args>
node(const char *t, node *n, Args ... ns) : title_(t), minsize(24), maxsize(48) {
child_ = n;
cursor_ = n;
n->parent_ = this;
child_->addNodes(true, ns...);
}
explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max),
next_(nullptr),
child_(nullptr),
parent_(nullptr) {
}
node *getChild() {
return child_;
}
template<typename ... Args>
node(const char *t, node *n, Args ... ns) : title_(t), minsize(24), maxsize(48) {
child_ = n;
cursor_ = n;
n->parent_ = this;
child_->addNodes(true, ns...);
}
node *getNext() {
return next_;
}
node *getChild() {
return child_;
}
node *getCursor() {
return cursor_;
}
node *getNext() {
return next_;
}
node *getParent() {
return parent_;
}
node *getCursor() {
return cursor_;
}
void setCursor(node *c) {
cursor_ = c;
}
};
node *getParent() {
return parent_;
}
void setCursor(node *c) {
cursor_ = c;
}
};
class value: public node {
public:
const char *header;
int state;
class value : public node {
public:
const char *header;
int state;
value(const char *t, int val, int min = 64, int max = 96) : node(t, min, max), header(t), state(val) {
}
};
value(const char *t, int val, int min = 64, int max = 96) : node(t, min, max), header(t), state(val) {
}
};
#endif //MGL_DMXMENU_NODE_H
}

View file

@ -8,7 +8,8 @@ OBJ = $(SRC_PATH:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
REMOVEDIR = rm -rf
CFLAGS += -std=gnu99
CXXFLAGS += -std=c++17
CXXFLAGS += -std=gnu++20
LDFLAGS =
CFLAGS += -I$(INCDIR) -DLINUX
@ -24,7 +25,7 @@ all: $(OBJDIR)/$(TARGET)
.PRECIOUS: $(OBJ)
$(OBJDIR)/$(TARGET): $(OBJ) | $(OBJDIR)
@echo link $^
@$(CXX) $(LDFLAGS) -o $@ $^
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
@echo compile $<

View file

@ -5,16 +5,18 @@
#include "hal/hal.h"
#include "buttons.h"
namespace micromenu {
buttons input;
buttons input;
void buttons::poll() {
hal_poll_input(raw);
void buttons::poll() {
hal_poll_input(raw);
for(int i = 0; i < 4; i++){
if(raw[i]!=last[i]){
onPush(i, raw[i]);
last[i]=raw[i];
for (int i = 0; i < 4; i++) {
if(raw[i] != last[i]) {
onPush(static_cast<direction>(i), raw[i]);
last[i] = raw[i];
}
}
}
}

View file

@ -1,13 +1,15 @@
#include <cstring>
#include "buttons.h"
#include "example.h"
#include "node.h"
#include "gfx/canvas.h"
#include "gfx/Canvas.h"
char peng[] = {' ', ' ', ' ', ' ', ' ', 0};
int j = 0;
void fooValue::render(canvas& c){
for(int i = 0; i<c.getHeight(); i++)
@ -15,10 +17,10 @@ void fooValue::render(canvas& c){
c.print(10 , 10, title_);
peng[0] = input.raw[0] ? 'L' : ' ';
peng[1] = input.raw[1] ? 'R' : ' ';
peng[2] = input.raw[2] ? 'U' : ' ';
peng[3] = input.raw[3] ? 'D' : ' ';
peng[0] = micromenu::input.raw[0] ? 'L' : ' ';
peng[1] = micromenu::input.raw[1] ? 'R' : ' ';
peng[2] = micromenu::input.raw[2] ? 'U' : ' ';
peng[3] = micromenu::input.raw[3] ? 'D' : ' ';
j++;
j %= 10;
peng[4] = 'A' + j;
@ -32,15 +34,25 @@ void blubValue::render(canvas& c){
c.print(3 , 15, title_);
}
void menu::render(canvas& c){
void menu::render(canvas& c) {
for(int i = 0; i<c.getHeight();i++)
c.draw(0,i);
for (int i = 0; i < c.getHeight(); i++)
c.draw(0, i);
int r = 0;
node* ptr = getChild();
while(ptr){
c.print(3,6*r+2, ptr->title_);
node *ptr = getChild();
while (ptr) {
if (ptr == getCursor()) {
int len = strlen(ptr->title_);
for(int i = 0; i < 6*len; i++){
for(int j = 0; j < 7; j++) {
c.draw(2+i, 1+7*r+j);
}
}
c.print(3, 7 * r + 2, ptr->title_, true);
} else {
c.print(3, 7 * r + 2, ptr->title_);
}
ptr = ptr->getNext();
r++;
}

View file

@ -4,7 +4,9 @@
#include "fonts/basic_5x4.h"
const bool basic_5x4_raw[32][20] = {
namespace micromenu {
const bool basic_5x4_raw[32][20] = {
//0
{0,0,0,0,
0,0,0,0,
@ -167,6 +169,8 @@ const bool basic_5x4_raw[32][20] = {
0,1,1,0,
1,0,0,0,
1,1,1,1},
};
};
font basic_5x4(basic_5x4_raw);
Font basic_5x4(basic_5x4_raw);
}

View file

@ -2,16 +2,16 @@
// Created by jedi on 11/2/18.
//
#include "gfx/buffer.h"
#include "gfx/Buffer.h"
template <>
int buffer<_32bit>::get(int i){
int Buffer<_32bit>::get(int i){
if (i >= size_) return 0;
return ptr_[i];
}
template <>
void buffer<_32bit>::set(int i, int v) {
void Buffer<_32bit>::set(int i, int v) {
if (i < size_)
ptr_[i] = v;
}

34
src/gfx/Font.cpp Normal file
View file

@ -0,0 +1,34 @@
//
// Created by jedi on 11/1/18.
//
#include "gfx/Font.h"
#include "gfx/Canvas.h"
namespace micromenu {
Font::Font(raw_font &raw) noexcept : raw_data_(raw) {
}
void Font::print(int x, int y, char l, Canvas &c, bool inv) {
int j = (l - ' ') % 32;
for (int x_ = 0; x_ < 4; x_++)
for (int y_ = 0; y_ < 5; y_++)
if(raw_data_[j][x_ + 4 * y_])
c.draw(x + x_, y + y_, inv);
}
void Font::print(int x, int y, char *str, Canvas &c, bool inv) {
for (int i = 0; str[i]; i++) {
print(x + i * 5, y, str[i], c, inv);
}
}
void Font::print(int x, int y, const char *str, Canvas &c, bool inv) {
for (int i = 0; str[i]; i++) {
print(x + i * 5, y, str[i], c, inv);
}
}
}

71
src/gfx/Layout.cpp Normal file
View file

@ -0,0 +1,71 @@
//
// Created by jedi on 11/5/18.
//
#include "node.h"
#include "gfx/Layout.h"
namespace micromenu {
void Layout::render() {
for (int j = 0; j < allocated_; j++) {
node *node_ptr;
node_ptr = slots[j].content;
if(node_ptr) {
slots[j].canvas_->clear();
node_ptr->render(*slots[j].canvas_);
screen_.draw(slots[j].pos_, 0, *slots[j].canvas_);
}
}
}
int Layout::apply(node *node) {
int rootslot = allocate_(node, maxslots);
int minsize = pack_(rootslot + 1);
expand_(minsize);
if(cursor == nullptr)
cursor = slots[rootslot].content->getCursor();
return 0;
}
int Layout::pack_(int usedslots) {
int minsum = 0;
int i;
for (i = 0; i < usedslots; i++) {
if(!slots[i].content) break;
if(minsum + slots[i].content->minsize > maxwidth_) break;
minsum += slots[i].content->minsize;
}
allocated_ = i;
return minsum;
}
int Layout::expand_(int packedsize) {
int diff = maxwidth_ - packedsize;
int pos = 0;
for (int i = allocated_ - 1; i >= 0; i--) {
slots[i].pos_ = pos;
int size = slots[i].content->minsize + (diff * slots[i].content->minsize) / packedsize;
if(size > slots[i].content->maxsize)
size = slots[i].content->maxsize;
slots[i].size_ = size;
delete slots[i].canvas_;
slots[i].canvas_ = new Canvas(size, maxheight_);
pos += size;
}
return 0;
}
int Layout::allocate_(node *current, int depth) {
if(node *next = current->getCursor()) {
int i = allocate_(next, depth) + 1;
slots[i].content = current;
return i;
} else {
slots[0].content = current;
return 0;
}
}
}

29
src/gfx/Screen.cpp Normal file
View file

@ -0,0 +1,29 @@
//
// Created by jedi on 11/1/18.
//
#include "gfx/Screen.h"
namespace micromenu {
Screen::Screen(int w, int h) noexcept: width_(w), height_(h) {
hal_init_screen(w, h);
}
void Screen::draw(int x, int y, Canvas &c) {
for (int x_ = 0; x_ < c.getWidth(); x_++)
for (int y_ = 0; y_ < c.getHeight(); y_ += 8 * sizeof(int))
hal_draw(x + x_, y + y_, c.buffer_.getBlock(x_ * c.getHeight() + y_));
}
void Screen::print(int x, int y, const char *str, Font &f) {
//f.print(x, y, str);
}
void Screen::print(int x, int y, char *str, Font &f) {
//f.print(x, y, str);
}
}

View file

@ -2,35 +2,39 @@
// Created by jedi on 11/1/18.
//
#include "gfx/canvas.h"
#include "gfx/Canvas.h"
canvas::canvas(int w, int h) : width_(w), height_(h), buffer_(w*h) {
clear();
}
namespace micromenu {
void canvas::clear() {
for (int x = 0; x < width_; x++)
for (int y = 0; y < height_; y++)
buffer_.set(x * height_ + y, false);
}
Canvas::Canvas(int w, int h) : width_(w), height_(h), buffer_(w * h) {
clear();
}
void canvas::draw(int x, int y) {
if (y < height_ && x < width_)
buffer_.set(x * height_ + y, true);
}
void Canvas::clear() {
for (int x = 0; x < width_; x++)
for (int y = 0; y < height_; y++)
buffer_.set(x * height_ + y, false);
}
void canvas::print(int x, int y, const char *str, font& f) {
f.print(x, y, str, *this);
}
void Canvas::draw(int x, int y, bool inv) {
if(y < height_ && x < width_)
buffer_.set(x * height_ + y, !inv);
}
void canvas::print(int x, int y, char *str, font& f) {
f.print(x, y, str, *this);
}
void Canvas::print(int x, int y, const char *str, bool inv, Font &f) {
f.print(x, y, str, *this, inv);
}
int canvas::getWidth(){
return width_;
}
void Canvas::print(int x, int y, char *str, bool inv, Font &f) {
f.print(x, y, str, *this, inv);
}
int Canvas::getWidth() {
return width_;
}
int Canvas::getHeight() {
return height_;
}
int canvas::getHeight(){
return height_;
}

View file

@ -1,31 +0,0 @@
//
// Created by jedi on 11/1/18.
//
#include "gfx/font.h"
#include "gfx/canvas.h"
font::font(raw_font& raw ):raw_data_(raw){
}
void font::print(int x, int y, char l, canvas& c) {
int j = (l - ' ') % 32;
for (int x_ = 0; x_ < 4; x_++)
for (int y_ = 0; y_ < 5; y_++)
if (raw_data_[j][x_ + 4 * y_])
c.draw(x + x_, y + y_);
}
void font::print(int x, int y, char* str, canvas& c) {
for (int i = 0; str[i]; i++) {
print(x + i * 5,y,str[i],c);
}
}
void font::print(int x, int y, const char* str, canvas& c) {
for (int i = 0; str[i]; i++) {
print(x + i * 5,y,str[i],c);
}
}

View file

@ -1,66 +0,0 @@
//
// Created by jedi on 11/5/18.
//
#include "node.h"
#include "gfx/layout.h"
void layout::render() {
for (int j = 0; j < allocated_; j++) {
node *node_ptr;
if (node_ptr = slots[j].content) {
slots[j].canvas_->clear();
node_ptr->render(*slots[j].canvas_);
screen_.draw(slots[j].pos_, 0, *slots[j].canvas_);
}
}
}
int layout::apply(node* node) {
int rootslot = allocate_(node, maxslots);
int minsize = pack_(rootslot + 1);
expand_(minsize);
if (cursor == nullptr)
cursor = slots[rootslot].content->getCursor();
return 0;
}
int layout::pack_(int usedslots) {
int minsum = 0;
int i;
for (i = 0; i < usedslots; i++) {
if (!slots[i].content) break;
if (minsum + slots[i].content->minsize > maxwidth_) break;
minsum += slots[i].content->minsize;
}
allocated_ = i;
return minsum;
}
int layout::expand_(int packedsize) {
int diff = maxwidth_ - packedsize;
int pos = 0;
for (int i = allocated_ - 1; i >= 0; i--) {
slots[i].pos_ = pos;
int size = slots[i].content->minsize + (diff * slots[i].content->minsize) / packedsize;
if (size > slots[i].content->maxsize)
size = slots[i].content->maxsize;
slots[i].size_ = size;
if(slots[i].canvas_)
delete slots[i].canvas_;
slots[i].canvas_ = new canvas(size, maxheight_);
pos += size;
}
return 0;
}
int layout::allocate_(node* current, int depth) {
if (node* next = current->getCursor()) {
int i = allocate_(next, depth) + 1;
slots[i].content = current;
return i;
} else {
slots[0].content = current;
return 0;
}
}

View file

@ -1,36 +0,0 @@
//
// Created by jedi on 11/1/18.
//
#include "gfx/screen.h"
screen::screen(int w, int h) : width_(w), height_(h) {
hal_init_screen(w,h);
}
void screen::draw(int x, int y) {
hal_draw(x, y);
}
void screen::draw(int x, int y, canvas &c) {
for (int x_ = 0; x_ < width_; x_++)
for (int y_ = 0; y_ < height_; y_++)
if (c.buffer_.get(x_ * height_ + y_))
hal_draw(x + x_, y + y_);
}
void screen::print(int x, int y, const char *str, font& f) {
//f.print(x, y, str);
}
void screen::print(int x, int y, char *str, font& f) {
//f.print(x, y, str);
}
int screen::getWidth(){
return width_;
}
int screen::getHeight(){
return height_;
}

View file

@ -8,3 +8,18 @@
#ifdef AVR
#include "hal/avr.cpp"
#endif
void debug(int n){
const char hex[]="0123456789ABCDEF";
char buf[]="0x00000000\n";
buf[2]=hex[(n>>28)&0xF];
buf[3]=hex[(n>>24)&0xF];
buf[4]=hex[(n>>20)&0xF];
buf[5]=hex[(n>>16)&0xF];
buf[6]=hex[(n>>12)&0xF];
buf[7]=hex[(n>>8)&0xF];
buf[8]=hex[(n>>4)&0xF];
buf[9]=hex[(n>>0)&0xF];
debug(buf);
}

View file

@ -3,24 +3,25 @@
//
#include "ssd1306.h"
#include "nano_gfx.h"
#include "buttons.h"
#include <stdlib.h>
#include <stdint.h>
#include <hal/hal.h>
uint8_t canvasData[128 * (32 / 8)];
NanoCanvas canvas(128, 32, canvasData);
void hal_init_screen(int w, int h) {
ssd1306_128x32_i2c_init();
ssd1306_fillScreen( 0x00 );
DDRD = 0;
PORTD |= (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5);
}
void hal_draw(int x, int y){
canvas.putPixel(x, y);
void hal_draw(int x, int y, int b){
ssd1306_putPixels(x, y, b&0xFF);
ssd1306_putPixels(x, y+8, b>>8);
}
void hal_clear(){
}
@ -36,9 +37,7 @@ void hal_poll_input(bool *ptr) {
void hal_render() {
while (true) {
ssd1306_fillScreen( 0x00 );
render();
canvas.blt(0, 0);
}
}

View file

@ -35,8 +35,20 @@ void hal_init_screen(int width, int height){
}
}
void hal_draw(int x, int y){
SDL_RenderDrawPoint(renderer, x, y);
void hal_draw(int x, int y, int b) {
for (int i = 0; i < 8 *sizeof(int);i++)
if (b & (1 << i)) {
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
SDL_RenderDrawPoint(renderer, x, y + i);
}else{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderDrawPoint(renderer, x, y + i);
}
}
void hal_clear(){
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
}
@ -46,10 +58,6 @@ void hal_render() {
while (!quit) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
render();
SDL_RenderPresent(renderer);
}
@ -68,16 +76,16 @@ void hal_poll_input(bool *ptr) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_LEFT:
ptr[I_LEFT] = true;
ptr[micromenu::I_LEFT] = true;
break;
case SDLK_RIGHT:
ptr[I_RIGHT] = true;
ptr[micromenu::I_RIGHT] = true;
break;
case SDLK_UP:
ptr[I_UP] = true;
ptr[micromenu::I_UP] = true;
break;
case SDLK_DOWN:
ptr[I_DOWN] = true;
ptr[micromenu::I_DOWN] = true;
break;
case 'q':
case 0x1b: //ESC
@ -89,16 +97,16 @@ void hal_poll_input(bool *ptr) {
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_LEFT:
ptr[I_LEFT] = false;
ptr[micromenu::I_LEFT] = false;
break;
case SDLK_RIGHT:
ptr[I_RIGHT] = false;
ptr[micromenu::I_RIGHT] = false;
break;
case SDLK_UP:
ptr[I_UP] = false;
ptr[micromenu::I_UP] = false;
break;
case SDLK_DOWN:
ptr[I_DOWN] = false;
ptr[micromenu::I_DOWN] = false;
break;
}
break;

View file

@ -1,110 +1,87 @@
#include "hal/hal.h"
#include "node.h"
#include "gfx/layout.h"
#include "gfx/Layout.h"
#include "example.h"
#include "gfx/screen.h"
#include "gfx/canvas.h"
#include "gfx/Screen.h"
#include "gfx/Canvas.h"
#include "buttons.h"
#ifdef LINUX
#include <SDL2/SDL.h>
#include <stdio.h>
#include <iostream>
extern SDL_Window* window;
extern SDL_Window *window;
extern SDL_Event event;
extern SDL_Renderer *renderer;
#endif
screen s(128,32);
layout l(s);
menu* root;
micromenu::Screen screen(128, 32);
micromenu::Layout layout(screen);
menu *root;
//using micromenu::menu;
int main() {
root = new menu("",
new menu("foo",
new menu("baz",
new fooValue("I", 5),
new fooValue("II", 5),
new fooValue("III", 5),
new fooValue("IIII", 5)
root = new menu("",
new menu("baz",
new menu("x",
new fooValue("x x", 5),
new blubValue("xxx", 5)
),
new menu("peng",
new fooValue("o", 5),
new fooValue("oo", 5),
new fooValue("o o", 5)
),
new menu("x",
new fooValue("x x", 5),
new fooValue("xxx", 5)
),
new menu("y",
new fooValue("y y", 5),
new fooValue("yyy", 5)
)
),
new menu("a",
new blubValue("a a", 5),
new blubValue("aa", 5),
new blubValue("aaa", 5)
),
new menu("b",
new blubValue("b b", 5),
new blubValue("bb", 5),
new blubValue("bbb", 5)
),
new menu("c",
new blubValue("c c", 5),
new blubValue("cc", 5),
new blubValue("ccc", 5)
)
);
new fooValue("I", 5),
new fooValue("II", 5),
new blubValue("III", 5),
new blubValue("IIII", 5)
),
new menu("peng",
new fooValue("o", 5),
new fooValue("oo", 5),
new fooValue("o o", 5)
)
);
hal_render();
return 0;
hal_render();
return 0;
}
void render(){
l.apply(root);
input.poll();
l.render();
void render() {
layout.apply(root);
micromenu::input.poll();
layout.render();
}
void buttons::onPush(int id, bool state) {
if (state) {
node *c;
node *p;
switch (id) {
case I_DOWN:
c = l.cursor;
p = c->getParent();
if ((c = c->getNext()) || p && (c = p->getChild())) {
p->setCursor(c);
l.cursor = c;
}
break;
case I_UP:
break;
case I_RIGHT:
c = l.cursor;
if (c = c->getCursor()) {
l.cursor = c;
}
break;
case I_LEFT:
c = l.cursor;
if (c = c->getParent()) {
l.cursor = c;
}
break;
}
}
void micromenu::buttons::onPush(direction dir, bool state) {
if(state) {
node *c;
if(dir == I_DOWN) {
c = layout.cursor;
node *parent = c->getParent();
if((c = c->getNext()) || parent && (c = parent->getChild())) {
parent->setCursor(c);
layout.cursor = c;
}
} else if(dir == I_UP) {
// TODO implement
} else if(dir == I_RIGHT) {
c = layout.cursor;
c = c->getCursor();
if(c) {
layout.cursor = c;
}
} else if(dir == I_LEFT) {
c = layout.cursor;
c = c->getParent();
if(c) {
layout.cursor = c;
}
}
}
}