added frontend

This commit is contained in:
Steffen Vogel 2012-11-15 22:04:02 +01:00
parent 6446c9b24d
commit 6a2edcde49
9 changed files with 337 additions and 0 deletions

24
frontend/Makefile Executable file
View file

@ -0,0 +1,24 @@
# adding cairo.pc
export PKG_CONFIG_PATH:=/usr/lib/x86_64-linux-gnu/pkgconfig/
# programs
CC = gcc
PC=pkg-config
RM=rm
TARGET=frontend
OBJS=Plot.o XWindow.o cairotest.o
CFLAGS = -Wall `$(PC) --cflags cairomm-xlib-1.0`
LIBS = -lm `$(PC) --libs cairomm-xlib-1.0`
INC = -I/usr/include/cairomm-1.0/
all: $(OBJS)
$(CC) $(OBJS) $(LIBS) -o $(TARGET)
%.o: %.cpp
$(CC) $(CFLAGS) $(INC) -c -o $@ $<
clean:
$(RM) frontend
$(RM) $(OBJS)

108
frontend/Plot.cpp Normal file
View file

@ -0,0 +1,108 @@
#include <math.h>
#include <float.h>
#include <iostream>
#include "Plot.h"
PlotSeries::PlotSeries(PlotSeries::Style style, Color color)
: color(color), style(style)
{ }
void PlotSeries::draw(RefPtr<Context> ctx) {
ctx->set_source_rgb(color.red, color.green, color.blue); /* set series color */
/* determine maxima and minima for autoscale */
double min = DBL_MAX, max = DBL_MIN;
for (std::list<double>::iterator it = begin(); it != end(); it++) {
if (*it > max) max = *it;
if (*it < min) min = *it;
}
/* stroke */
int width = 800;//dynamic_cast<RefPtr<XlibSurface>>(ctx->get_target())->get_width();
int height = 400;//dynamic_cast<RefPtr<XlibSurface>>(ctx->get_target())->get_height();
ctx->move_to(Plot::PADDING, (height/2) + (height-2*Plot::PADDING) * (front()/max));
int i = 0;
for (std::list<double>::iterator it = begin(); it != end(); it++) {
i++;
ctx->line_to(i * 2 + Plot::PADDING, (height/2) + (height-2*Plot::PADDING) * (*it/max*0.5));
}
ctx->stroke();
}
Plot::Plot(int width, int height)
: width(width), height(height)
{
window = XWindow::create("Frontend", 1, 1, width, height);
surface = XlibSurface::create(window->getDisplay(), window->getWindow(), window->getVisual(), width, height);
}
void Plot::draw() {
RefPtr<Context> ctx = Context::create(surface);
ctx->set_antialias(ANTIALIAS_SUBPIXEL);
/* background */
ctx->set_source_rgb(0, 0, 0); /* black */
ctx->paint();
ctx->set_source_rgb(0, 0.7, 0.1); /* axis & tick color */
drawAxes(ctx);
drawTicks(ctx);
for (std::list<PlotSeries *>::iterator it = series.begin(); it != series.end(); it++) {
(*it)->draw(ctx);
}
}
void Plot::drawAxes(RefPtr<Context> ctx) {
ctx->set_line_width(1.8);
/* x-axis */
ctx->move_to(PADDING, height-PADDING);
ctx->line_to(width-PADDING, height-PADDING);
ctx->stroke();
/* y-axis */
ctx->move_to(PADDING, height-PADDING);
ctx->line_to(PADDING, PADDING);
ctx->stroke();
/* arrows (arcs) */
ctx->move_to(width-PADDING-2, height-PADDING-4);
ctx->line_to(width-PADDING+5, height-PADDING);
ctx->line_to(width-PADDING-2, height-PADDING+4);
ctx->stroke();
ctx->move_to(PADDING-4, PADDING+2);
ctx->line_to(PADDING, PADDING-5);
ctx->line_to(PADDING+4, PADDING+2);
ctx->stroke();
}
void Plot::drawTicks(RefPtr<Context> ctx) {
int ticks = 20;
int intv_x = (width-2*PADDING)/ticks;
int intv_y = (height-2*PADDING)/ticks;
ctx->set_line_width(1);
for (int i = 0; i < ticks; i++) {
/* x-axis */
ctx->move_to(PADDING + i*intv_x, height-PADDING-3);
ctx->line_to(PADDING + i*intv_x, height-PADDING+3);
ctx->stroke();
/* y-axis */
ctx->move_to(PADDING-3, PADDING + (i+1)*intv_y);
ctx->line_to(PADDING+3, PADDING + (i+1)*intv_y);
ctx->stroke();
}
}
Plot::~Plot() {
}

50
frontend/Plot.h Normal file
View file

@ -0,0 +1,50 @@
#ifndef _PLOT_H_
#define _PLOT_H_
#include <list>
#include <cairomm/cairomm.h>
#include <cairomm/xlib_surface.h>
#include "XWindow.h"
using namespace Cairo;
struct Color {
double red, green, blue, alpha;
};
class PlotSeries : public std::list<double> {
public:
Color color;
enum Style { STYLE_LINE, STYLE_SPLINE, STYLE_SCATTER } style;
PlotSeries(enum Style style, Color color);
void draw(RefPtr<Context> ctx);
};
class Plot {
friend class PlotSeries;
public:
Plot(int width = 400, int height = 300);
virtual ~Plot();
void draw();
std::list<PlotSeries *> series;
protected:
RefPtr<XWindow> window;
RefPtr<Surface> surface;
int width, height;
void drawAxes(RefPtr<Context> ctx);
void drawTicks(RefPtr<Context> ctx);
static const int PADDING = 20;
};
#endif /* _PLOT_H_ */

BIN
frontend/Plot.o Normal file

Binary file not shown.

60
frontend/XWindow.cpp Normal file
View file

@ -0,0 +1,60 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "XWindow.h"
Display * XWindow::display = NULL;
int XWindow::windows = 0;
int XWindow::screen = 0;
XException::XException(const char *reason) {
fprintf(stderr, "%s\n", reason);
exit(EXIT_FAILURE);
}
XWindow::XWindow(const char *title, int x, int y, int width, int height, unsigned long background) {
Window rootWindow;
screen = XDefaultScreen(display);
rootWindow = XRootWindow(display, screen);
window = XCreateSimpleWindow(display, rootWindow, x, y, width, height, 0, 0, background);
XStoreName(display, window, title);
XSelectInput(display, window, ExposureMask | ButtonPressMask);
XMapWindow(display, window);
}
XWindow::~XWindow() {
windows--;
if (windows == 0) {
disconnect();
}
}
Display * XWindow::getDisplay() {
if (display == NULL) {
throw new XException("There exists no connection to an XServer!");
}
return display;
}
void XWindow::connect(std::string display_name) {
display = XOpenDisplay(display_name.c_str());
if (display == NULL) {
throw XException("Cannot open display!");
}
}
void XWindow::disconnect() {
XCloseDisplay(display);
}
Cairo::RefPtr<XWindow> XWindow::create(const char *title, int x, int y, int width, int height, unsigned long background) {
XWindow *win = new XWindow(title, x, y, width, height, background);
return Cairo::RefPtr<XWindow>(win);
}

49
frontend/XWindow.h Normal file
View file

@ -0,0 +1,49 @@
#ifndef _XWINDOW_H_
#define _XWINDOW_H_
#include <cairomm/refptr.h>
#include <X11/Xlib.h>
#include <string>
class XException {
public:
XException(const char * reason);
};
class XWindow {
public:
XWindow(
const char *title,
int x = 1, int y = 1,
int width = 800, int height = 600,
unsigned long background = 0
);
virtual ~XWindow();
Window getWindow() { return window; };
Visual * getVisual() { return XDefaultVisual(display, screen); };
static Display * getDisplay();
static void connect(std::string display);
static void disconnect();
static Cairo::RefPtr<XWindow> create(
const char *title,
int x = 1, int y = 1,
int width = 800, int height = 600,
unsigned long background = 0
);
protected:
Window window;
static Display *display;
static int screen;
static int windows; /* reference counter to open windows */
};
#endif /* _XWINDOW_H_ */

BIN
frontend/XWindow.o Normal file

Binary file not shown.

46
frontend/cairotest.cpp Normal file
View file

@ -0,0 +1,46 @@
#include "XWindow.h"
#include "Plot.h"
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
using namespace Cairo;
int main(int argc, char *argv[]) {
XWindow::connect(":0"); // TODO parse from argv
XEvent e;
Color blue = { 0, 0, 1 };
Color red = { 1, 0, 0 };
Plot testPlot(800, 400);
Plot testPlot2(800, 400);
PlotSeries *demo1 = new PlotSeries(PlotSeries::STYLE_LINE, blue);
PlotSeries *demo2 = new PlotSeries(PlotSeries::STYLE_LINE, red);
testPlot.series.push_back(demo1);
testPlot2.series.push_back(demo2);
double phi = 0;
double last = 0;
while (1) {
phi += 1e-1;
last += -10 + rand()%21;
demo2->push_back(last);
if (demo2->size() > 400) demo2->pop_front();
demo1->clear();
for (int i = 0; i < 300; i++) {
demo1->push_back(0.7*sin(i*phi/1e3)*sin(i * (M_PI/30.0) + phi));
}
usleep(0.2*1e5);
testPlot.draw();
testPlot2.draw();
}
}

BIN
frontend/cairotest.o Normal file

Binary file not shown.