lnvis

nanovg lightning network visualizer
git clone git://jb55.com/lnvis
Log | Files | Refs | README | LICENSE

commit 229c858b4a349e5f3740f95fa04d78d7e6795b7b
parent 0572d3de479222937a981f0a3275a3fa3cd58bea
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 15 Aug 2018 01:34:54 -0700

dual channel stuff

Diffstat:
Mjson.c | 2+-
Mln.c | 3+++
Mln.h | 3+++
Mmain.c | 13+++++++++++++
Mrender.c | 85++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mupdate.c | 4++++
6 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/json.c b/json.c @@ -303,6 +303,7 @@ int parse_clightning_channels(FILE *fd, int *nchans, struct channel **pchannels) char *buffer; void *res; struct channel *chan = NULL, *channels; + struct short_channel_id last_chan; int chancap = 4096; jsmntok_t *toks; jsmntok_t *tok; @@ -346,7 +347,6 @@ int parse_clightning_channels(FILE *fd, int *nchans, struct channel **pchannels) chan = &channels[*nchans]; - // TODO: lookup node id, assign nodes switch (state) { case PARSING_CHAN_SOURCE: strncpy(chan->source, tokstr, min(PUBKEY_SIZE, toklen)); diff --git a/ln.c b/ln.c @@ -132,6 +132,9 @@ void filter_network(const char *nodeid, struct node *filter_node, struct ln *ln) for (i = 0; i < ln->channel_count; i++) { chan = &ln->channels[i]; + if (i % 2 == 0) + chan->filtered = 1; + if (chan->nodes[0]->filtered) chan->nodes[1]->mark_filtered = 1; diff --git a/ln.h b/ln.h @@ -98,6 +98,7 @@ struct channel { u64 satoshis; // app specific stuff + int filtered; int draw_last; }; @@ -106,12 +107,14 @@ enum display_flags { DISP_GRID = 1UL << 1, DISP_ALIASES = 1UL << 2, DISP_STROKE_NODES = 1UL << 3, + DISP_BEZIER = 1UL << 4, }; struct ln { NVGcontext *vg; int clicked; + int right_clicked; int mdown; double mx, my; int window_width; diff --git a/main.c b/main.c @@ -42,7 +42,9 @@ static void key(GLFWwindow *window, int key, int scancode, int action, int mods) static struct ln ln; static double mx, my; static int mdown = 0; +static int rmdown = 0; static int mclicked = 0; +static int rmclicked = 0; static const union color dark_color = { .rgba = { 0x28 / 255.0, 0x2c / 255.0, 0x34 / 255.0, 1.0f } @@ -68,9 +70,12 @@ void mouse_click(GLFWwindow *win, int button, int action, int mods) (void)mods; mclicked = action == 1 && button == 0; + rmclicked = action == 1 && button == 1; if (button == 0) mdown = action; + if (button == 1) + rmdown = action; } @@ -91,6 +96,9 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod case GLFW_KEY_G: ln.display_flags ^= DISP_GRID; break; + case GLFW_KEY_B: + ln.display_flags ^= DISP_BEZIER; + break; case GLFW_KEY_T: if (ln.display_flags & DISP_DARK) memcpy(&ln.clear_color, &light_color, sizeof(ln.clear_color)); @@ -276,6 +284,8 @@ int main() while (!glfwWindowShouldClose(window)) { if (ln.clicked) ln.clicked = 0; + if (ln.right_clicked) + ln.right_clicked = 0; double t, dt; int winWidth, winHeight; int fbWidth, fbHeight; @@ -289,6 +299,9 @@ int main() ln.clicked = mclicked; mclicked = 0; + ln.right_clicked = rmclicked; + rmclicked = 0; + ln.mx = mx; ln.my = my; ln.mdown = mdown; diff --git a/render.c b/render.c @@ -5,9 +5,36 @@ #include <assert.h> #include <math.h> #include "nanovg/nanovg.h" +#include <stdlib.h> + + +#define Pr .299 +#define Pg .587 +#define Pb .114 + +static inline double rand_0to1() { + return (double) rand() / RAND_MAX; +} + + +void saturate(union color *c, double change) +{ + double P=sqrt( + (c->r)*(c->r)*Pr+ + (c->g)*(c->g)*Pg+ + (c->b)*(c->b)*Pb ) ; + + c->r = P+((c->r)-P)*change; + c->g = P+((c->g)-P)*change; + c->b = P+((c->b)-P)*change; +} + void draw_channel(NVGcontext *vg, struct ln *ln, struct channel *channel) { + if (channel->filtered == 1) + return; + const struct node *n1 = channel->nodes[0]; const struct node *n2 = channel->nodes[1]; @@ -35,11 +62,17 @@ void draw_channel(NVGcontext *vg, struct ln *ln, struct channel *channel) else c = n2t.nvg_color; - if (channel->nodes[0] == ln->last_drag_target || - channel->nodes[1] == ln->last_drag_target) + if ((channel->nodes[0] == ln->last_drag_target || + channel->nodes[1] == ln->last_drag_target)) c.a = 1.0; - else - c.a = 0.4; + else { + if (ln->drag_target) { + saturate((union color*)&c, 0.01); + c.a = 0.1; + } + else + c.a = 0.4; + } /* NVGpaint linear_grad = */ @@ -51,8 +84,50 @@ void draw_channel(NVGcontext *vg, struct ln *ln, struct channel *channel) /* nvgStrokePaint(vg, linear_grad); */ nvgStrokeColor(vg, c); nvgBeginPath(vg); + +#define TAU (2.0*NVG_PI) + + + nvgMoveTo(vg, n1->x, n1->y); - nvgLineTo(vg, n2->x, n2->y); + + if (ln->display_flags & DISP_BEZIER) { + srand(channel->short_channel_id.blocknum ^ + channel->short_channel_id.outnum ^ + channel->short_channel_id.txnum); + float ang1 = TAU*rand_0to1(); + float ang2 = TAU*rand_0to1(); + + float dx = n2->x - n1->x; + float dy = n2->y - n1->y; + + float len = sqrt(dx*dx + dy*dy); + + /* float nx = dx/len; */ + /* float ny = dy/len; */ + + const float dist = 1.0/3.0; + + float ax1 = cos(ang1) * len * dist; + float ay1 = sin(ang1) * len * dist; + + float ax2 = cos(ang2) * len * dist; + float ay2 = sin(ang2) * len * dist; + + nvgBezierTo(vg, n1->x + ax1, + n1->y + ay1, + n2->x - ax2, + n2->y - ay2, + n2->x, n2->y); + } + else { + nvgLineTo(vg, n2->x, n2->y); + } + /* nvgMoveTo(vg, n2->x, n2->y); */ + /* nvgArc(vg, n1->x, n1->y, TAU*4.0, TAU/8.0, 100.0, NVG_CCW); */ + /* nvgClosePath(vg); */ + /* nvgArcTo(vg, n1->x, n1->y, n2->x, n2->y, 100.0); */ + /* nvgLineTo(vg, n2->x, n2->y); */ nvgStroke(vg); nvgRestore(vg); } diff --git a/update.c b/update.c @@ -159,6 +159,10 @@ void update(struct ln *ln, double dt) struct node *hit = hit_node(ln); ln->drag_target = hit; ln->last_drag_target = hit; + } + + if (ln->right_clicked) { + struct node *hit = hit_node(ln); if (hit != NULL) filter_network(NULL, hit, ln); }