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 TARGET = main
SRC = hal.cpp main.cpp example.cpp buttons.cpp 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 SRC += fonts/basic_5x4.cpp

View file

@ -2,27 +2,30 @@
// Created by jedi on 11/6/18. // Created by jedi on 11/6/18.
// //
#ifndef MGL_DMXMENU_INPUT_H #pragma once
#define MGL_DMXMENU_INPUT_H
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();
};
extern buttons input;
#define I_LEFT 0
#define I_RIGHT 1
#define I_UP 2
#define I_DOWN 3
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_ #ifndef _EXAMPLE_H_
#define _EXAMPLE_H_ #define _EXAMPLE_H_
#include "gfx/canvas.h" #include "gfx/Canvas.h"
#include "node.h" #include "node.h"
class menu : public node { using canvas = micromenu::Canvas;
public: using node = micromenu::node;
template<typename ... Args> using value = micromenu::value;
menu(Args ... ns) : node(ns...) {
}
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 { class fooValue : public value {
public: public:
fooValue(const char* str, int val) : value(str, val, 32, 48) { fooValue(const char *str, int val) : value(str, val, 32, 48) {
} }
void render(canvas &c); void render(canvas &c) override;
}; };
class blubValue : public value{ class blubValue : public value {
public: public:
template<typename ... Args> template<typename ... Args>
blubValue(Args ... ns) : value(ns..., 64, 96) { explicit blubValue(Args ... ns) : value(ns..., 64, 96) {
} }
void render(canvas& c);
void render(canvas &c) override;
}; };
#endif #endif

View file

@ -2,11 +2,11 @@
// Created by jedi on 11/2/18. // Created by jedi on 11/2/18.
// //
#ifndef MGL_DMXMENU_BASIC_5X4_H #pragma once
#define MGL_DMXMENU_BASIC_5X4_H
#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_ #define _HAL_H_
void debug(int);
void debug(const char* str); void debug(const char* str);
void hal_init_screen(int w, int h); void hal_init_screen(int w, int h);
void hal_poll_input(bool *ptr); 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 hal_render();
void render(); void render();

View file

@ -2,82 +2,84 @@
// Created by jedi on 11/5/18. // Created by jedi on 11/5/18.
// //
#ifndef MGL_DMXMENU_NODE_H #pragma once
#define MGL_DMXMENU_NODE_H
#include "gfx/canvas.h" #include "gfx/Canvas.h"
class node { namespace micromenu {
private:
node *parent_ = nullptr;
node *child_ = nullptr;
node *cursor_ = nullptr;
node *next_ = nullptr;
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) {
void addNodes(bool b, node *n, Us ... ns) { }
next_ = n;
next_->parent_ = parent_;
next_->addNodes(!b, ns...);
}
public: template<class ...Us>
const char *title_ = 0; void addNodes(bool b, node *n, Us ... ns) {
const int minsize; next_ = n;
const int maxsize; 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), virtual void render(Canvas &c) = 0;
maxsize(max) {
}
explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max), next_(nullptr), explicit node(int min = 24, int max = 48) : next_(nullptr), child_(nullptr), parent_(nullptr), minsize(min),
child_(nullptr), maxsize(max) {
parent_(nullptr) { }
}
template<typename ... Args> explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max),
node(const char *t, node *n, Args ... ns) : title_(t), minsize(24), maxsize(48) { next_(nullptr),
child_ = n; child_(nullptr),
cursor_ = n; parent_(nullptr) {
n->parent_ = this; }
child_->addNodes(true, ns...);
}
node *getChild() { template<typename ... Args>
return child_; 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() { node *getChild() {
return next_; return child_;
} }
node *getCursor() { node *getNext() {
return cursor_; return next_;
} }
node *getParent() { node *getCursor() {
return parent_; return cursor_;
} }
void setCursor(node *c) { node *getParent() {
cursor_ = c; return parent_;
} }
};
void setCursor(node *c) {
cursor_ = c;
}
};
class value: public node { class value : public node {
public: public:
const char *header; const char *header;
int state; 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 REMOVEDIR = rm -rf
CFLAGS += -std=gnu99 CFLAGS += -std=gnu99
CXXFLAGS += -std=c++17 CXXFLAGS += -std=gnu++20
LDFLAGS =
CFLAGS += -I$(INCDIR) -DLINUX CFLAGS += -I$(INCDIR) -DLINUX
@ -24,7 +25,7 @@ all: $(OBJDIR)/$(TARGET)
.PRECIOUS: $(OBJ) .PRECIOUS: $(OBJ)
$(OBJDIR)/$(TARGET): $(OBJ) | $(OBJDIR) $(OBJDIR)/$(TARGET): $(OBJ) | $(OBJDIR)
@echo link $^ @echo link $^
@$(CXX) $(LDFLAGS) -o $@ $^ $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
@echo compile $< @echo compile $<

View file

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

View file

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

View file

@ -4,7 +4,9 @@
#include "fonts/basic_5x4.h" #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,0,
0,0,0,0, 0,0,0,0,
@ -167,6 +169,8 @@ const bool basic_5x4_raw[32][20] = {
0,1,1,0, 0,1,1,0,
1,0,0,0, 1,0,0,0,
1,1,1,1}, 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. // Created by jedi on 11/2/18.
// //
#include "gfx/buffer.h" #include "gfx/Buffer.h"
template <> template <>
int buffer<_32bit>::get(int i){ int Buffer<_32bit>::get(int i){
if (i >= size_) return 0; if (i >= size_) return 0;
return ptr_[i]; return ptr_[i];
} }
template <> template <>
void buffer<_32bit>::set(int i, int v) { void Buffer<_32bit>::set(int i, int v) {
if (i < size_) if (i < size_)
ptr_[i] = v; 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. // 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) { namespace micromenu {
clear();
}
void canvas::clear() { Canvas::Canvas(int w, int h) : width_(w), height_(h), buffer_(w * h) {
for (int x = 0; x < width_; x++) clear();
for (int y = 0; y < height_; y++) }
buffer_.set(x * height_ + y, false);
}
void canvas::draw(int x, int y) { void Canvas::clear() {
if (y < height_ && x < width_) for (int x = 0; x < width_; x++)
buffer_.set(x * height_ + y, true); 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) { void Canvas::draw(int x, int y, bool inv) {
f.print(x, y, str, *this); if(y < height_ && x < width_)
} buffer_.set(x * height_ + y, !inv);
}
void canvas::print(int x, int y, char *str, font& f) { void Canvas::print(int x, int y, const char *str, bool inv, Font &f) {
f.print(x, y, str, *this); f.print(x, y, str, *this, inv);
} }
int canvas::getWidth(){ void Canvas::print(int x, int y, char *str, bool inv, Font &f) {
return width_; 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 #ifdef AVR
#include "hal/avr.cpp" #include "hal/avr.cpp"
#endif #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 "ssd1306.h"
#include "nano_gfx.h"
#include "buttons.h" #include "buttons.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <hal/hal.h> #include <hal/hal.h>
uint8_t canvasData[128 * (32 / 8)];
NanoCanvas canvas(128, 32, canvasData);
void hal_init_screen(int w, int h) { void hal_init_screen(int w, int h) {
ssd1306_128x32_i2c_init(); ssd1306_128x32_i2c_init();
ssd1306_fillScreen( 0x00 );
DDRD = 0; DDRD = 0;
PORTD |= (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5); PORTD |= (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5);
} }
void hal_draw(int x, int y){ void hal_draw(int x, int y, int b){
canvas.putPixel(x, y); 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() { void hal_render() {
while (true) { while (true) {
ssd1306_fillScreen( 0x00 );
render(); 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){ void hal_draw(int x, int y, int b) {
SDL_RenderDrawPoint(renderer, x, y); 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) { while (!quit) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
render(); render();
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
@ -68,16 +76,16 @@ void hal_poll_input(bool *ptr) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_LEFT: case SDLK_LEFT:
ptr[I_LEFT] = true; ptr[micromenu::I_LEFT] = true;
break; break;
case SDLK_RIGHT: case SDLK_RIGHT:
ptr[I_RIGHT] = true; ptr[micromenu::I_RIGHT] = true;
break; break;
case SDLK_UP: case SDLK_UP:
ptr[I_UP] = true; ptr[micromenu::I_UP] = true;
break; break;
case SDLK_DOWN: case SDLK_DOWN:
ptr[I_DOWN] = true; ptr[micromenu::I_DOWN] = true;
break; break;
case 'q': case 'q':
case 0x1b: //ESC case 0x1b: //ESC
@ -89,16 +97,16 @@ void hal_poll_input(bool *ptr) {
case SDL_KEYUP: case SDL_KEYUP:
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_LEFT: case SDLK_LEFT:
ptr[I_LEFT] = false; ptr[micromenu::I_LEFT] = false;
break; break;
case SDLK_RIGHT: case SDLK_RIGHT:
ptr[I_RIGHT] = false; ptr[micromenu::I_RIGHT] = false;
break; break;
case SDLK_UP: case SDLK_UP:
ptr[I_UP] = false; ptr[micromenu::I_UP] = false;
break; break;
case SDLK_DOWN: case SDLK_DOWN:
ptr[I_DOWN] = false; ptr[micromenu::I_DOWN] = false;
break; break;
} }
break; break;

View file

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