static void render_focus_widget(glw_t *w, glw_cursor_t *gc, const Mtx *saved, glw_rctx_t *rc0, const glw_rctx_t *rc, int *zmax) { glw_root_t *gr = w->glw_root; if(!(gc->w.glw_flags & GLW_IN_FOCUS_PATH)) return; glw_t *f = gr->gr_current_focus; if(f->glw_matrix != NULL) { Mtx a_inv; glw_mtx_invert(&a_inv, saved); Mtx *b = f->glw_matrix; if(0) { glw_rect_t focus_rect; glw_project_matrix(&focus_rect, b, gr); printf("Current focus: %d,%d - %d,%d\n", focus_rect.x1, focus_rect.y1, focus_rect.x2, focus_rect.y2); } Mtx x; glw_mtx_mul(&x, &a_inv, b); if (!gc->gc_initialized) { gc->gc_mtx = x; gc->gc_initialized = 1; } else { for(int r = 0; r < 4; r++) { for(int c = 0; c < 4; c++) { glw_lp(&gc->gc_mtx.r[r][c], gr, x.r[r][c], 0.75); /* printf("%2.3f%c", gc->gc_mtx[i], (i+1) & 3 ? '\t' : '\n'); */ } } } glw_mtx_mul(&gc->gc_cursor_rctx.rc_mtx, saved, &gc->gc_mtx); } glw_rect_t cursor_rect; glw_project(&cursor_rect, &gc->gc_cursor_rctx, gr); gc->gc_cursor_rctx.rc_width = cursor_rect.x2 - cursor_rect.x1; gc->gc_cursor_rctx.rc_height = cursor_rect.y2 - cursor_rect.y1; if(gc->gc_cursor_rctx.rc_width <= 0) return; if(gc->gc_cursor_rctx.rc_height <= 0) return; gc->gc_cursor_rctx.rc_alpha = 1.0f; gc->gc_cursor_rctx.rc_sharpness = 1.0f; glw_layout0(w, &gc->gc_cursor_rctx); rc0->rc_zindex = MAX(*zmax, rc->rc_zindex); gc->gc_cursor_rctx.rc_zmax = rc0->rc_zmax; gc->gc_cursor_rctx.rc_zindex = rc0->rc_zindex; glw_render0(w, &gc->gc_cursor_rctx); }
static void glw_navigate_matrix_search(glw_t *w, navigate_matrix_aux_t *nma) { glw_t *c; TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link) glw_navigate_matrix_search(c, nma); if(w->glw_root->gr_current_focus == w) return; // Don't consider ourself if(w->glw_matrix == NULL) return; glw_rect_t rect; Mtx m; memcpy(m, w->glw_matrix, sizeof(float) * 16); glw_project_matrix(&rect, m, w->glw_root); // Default current/target cordinates are center of focus int tgt_x = (rect.x2 + rect.x1) / 2; int tgt_y = (rect.y2 + rect.y1) / 2; // .. but will be adjusted to edge based on how we're moving switch(nma->direction) { case 0: // Moving left tgt_x = rect.x2; if(tgt_x >= nma->cur_x) return; break; case 1: // Moving up tgt_y = rect.y2; if(tgt_y >= nma->cur_y) return; break; case 2: // Moving right tgt_x = rect.x1; if(tgt_x <= nma->cur_x) return; break; case 3: // Moving down tgt_y = rect.y1; if(tgt_y <= nma->cur_y) return; break; default: abort(); } const int dx = tgt_x - nma->cur_x; const int dy = tgt_y - nma->cur_y; int distance = sqrt(dx * dx + dy * dy); if(distance > nma->distance) return; nma->best = w; nma->distance = distance; }