static int a3d_layer_fade(a3d_widget_t* widget, float fade, float dt) { assert(widget); LOGD("debug"); int a; int animate = 0; a3d_layer_t* self = (a3d_layer_t*) widget; a3d_listitem_t* iter = a3d_list_head(self->list); a3d_widget_t* head = (a3d_widget_t*) a3d_list_peekhead(self->list); while(iter) { widget = (a3d_widget_t*) a3d_list_peekitem(iter); if((self->mode == A3D_LAYER_MODE_LAYERED) || (widget == head)) { a = a3d_widget_fade(widget, fade, dt); iter = a3d_list_next(iter); } else { // remove widget if fade-to-zero is complete a = a3d_widget_fade(widget, 0.0f, dt); if(a == 0) { a3d_list_remove(self->list, &iter); } else { iter = a3d_list_next(iter); } } animate |= a; } return animate; }
static void a3d_listbox_layoutHorizontalStretch(a3d_listbox_t* self, int dragx, int dragy) { assert(self); LOGD("debug dragx=%i, dragy=%i", dragx, dragy); // initialize the layout float x = 0.0f; float y = 0.0f; float t = self->widget.rect_draw.t; float l = self->widget.rect_draw.l; float w = self->widget.rect_draw.w; float h = self->widget.rect_draw.h; float cnt = (float) a3d_list_size(self->list); float dw = w/cnt; a3d_rect4f_t rect_clip; a3d_rect4f_t rect_draw; a3d_listitem_t* iter = a3d_list_head(self->list); while(iter) { a3d_widget_t* child = (a3d_widget_t*) a3d_list_peekitem(iter); rect_draw.t = t; rect_draw.l = l; rect_draw.w = dw; rect_draw.h = h; l += dw; a3d_widget_anchorPt(&rect_draw, child->anchor, &x, &y); a3d_rect4f_intersect(&rect_draw, &self->widget.rect_clip, &rect_clip); a3d_widget_layoutXYClip(child, x, y, &rect_clip, dragx, dragy); iter = a3d_list_next(iter); } }
int naip_cache_prefetch(int zoom, int x, int y) { double lat0; double lon0; double lat1; double lon1; terrain_sample2coord(x, y, zoom, 0, 0, &lat0, &lon0); terrain_sample2coord(x, y, zoom, TERRAIN_SAMPLES_TILE - 1, TERRAIN_SAMPLES_TILE - 1, &lat1, &lon1); // search the list int count = 0; a3d_listitem_t* item = a3d_list_head(glist); while(item) { // if found insert in LRU naip_node_t* node = (naip_node_t*) a3d_list_peekitem(item); if((node->t < lat1) || (node->b > lat0) || (node->l > lon1) || (node->r < lon0)) { // not found } else { naip_cache(node); ++count; } item = a3d_list_next(item); } return count; }
const a3d_list_t* a3d_multimap_find(const a3d_multimap_t* self, a3d_multimapIter_t* iter, const char* key) { assert(self); assert(iter); assert(key); iter->hiter = &iter->hiterator; a3d_list_t* list; list = (a3d_list_t*) a3d_hashmap_find(self->hash, iter->hiter, key); if(list == NULL) { return NULL; } iter->item = a3d_list_head(list); return list; }
a3d_multimapIter_t* a3d_multimap_next(a3d_multimapIter_t* iter) { assert(iter); iter->item = a3d_list_next(iter->item); if(iter->item) { return iter; } iter->hiter = a3d_hashmap_next(iter->hiter); if(iter->hiter == NULL) { return NULL; } a3d_list_t* list = (a3d_list_t*) a3d_hashmap_val(iter->hiter); iter->item = a3d_list_head(list); return iter; }
static void a3d_layer_size(a3d_widget_t* widget, float* w, float* h) { assert(widget); assert(w); assert(h); LOGD("debug"); a3d_layer_t* self = (a3d_layer_t*) widget; a3d_listitem_t* iter = a3d_list_head(self->list); float wmax = 0.0f; float hmax = 0.0f; float tmp_w = 0.0f; float tmp_h = 0.0f; while(iter) { tmp_w = *w; tmp_h = *h; widget = (a3d_widget_t*) a3d_list_peekitem(iter); a3d_widget_layoutSize(widget, &tmp_w, &tmp_h); if(tmp_w > wmax) { wmax = tmp_w; } if(tmp_h > hmax) { hmax = tmp_h; } iter = a3d_list_next(iter); } *w = wmax; *h = hmax; }
static int a3d_listbox_click(a3d_widget_t* widget, int state, float x, float y) { assert(widget); LOGD("debug state=%i, x=%f, y=%f", state, x, y); a3d_listbox_t* self = (a3d_listbox_t*) widget; a3d_listitem_t* iter = a3d_list_head(self->list); while(iter) { widget = (a3d_widget_t*) a3d_list_peekitem(iter); if(a3d_widget_click(widget, state, x, y)) { return 1; } iter = a3d_list_next(iter); } // listboxes are always clicked return 1; }
static void a3d_listbox_layoutVerticalShrink(a3d_listbox_t* self, int dragx, int dragy) { assert(self); LOGD("debug dragx=%i, dragy=%i", dragx, dragy); // initialize the layout float x = 0.0f; float y = 0.0f; float t = self->widget.rect_draw.t; float l = self->widget.rect_draw.l; float w = self->widget.rect_draw.w; a3d_rect4f_t rect_clip; a3d_rect4f_t rect_draw; a3d_listitem_t* iter = a3d_list_head(self->list); while(iter) { a3d_widget_t* child = (a3d_widget_t*) a3d_list_peekitem(iter); float h = child->rect_border.h; rect_draw.t = t; rect_draw.l = l; rect_draw.w = w; rect_draw.h = h; t += h; a3d_widget_anchorPt(&rect_draw, child->anchor, &x, &y); a3d_rect4f_intersect(&rect_draw, &self->widget.rect_clip, &rect_clip); a3d_widget_layoutXYClip(child, x, y, &rect_clip, dragx, dragy); iter = a3d_list_next(iter); } }
static void a3d_listbox_size(a3d_widget_t* widget, float* w, float* h) { assert(widget); assert(w); assert(h); LOGD("debug"); a3d_listbox_t* self = (a3d_listbox_t*) widget; a3d_listitem_t* iter = a3d_list_head(self->list); float cnt = (float) a3d_list_size(self->list); float dw = *w/cnt; float dh = *h/cnt; if(self->orientation == A3D_LISTBOX_ORIENTATION_VERTICAL) { dw = *w; } else { dh = *h; } float wmax = 0.0f; float hmax = 0.0f; float wsum = 0.0f; float hsum = 0.0f; float tmp_w = 0.0f; float tmp_h = 0.0f; while(iter) { tmp_w = dw; tmp_h = dh; widget = (a3d_widget_t*) a3d_list_peekitem(iter); a3d_widget_layoutSize(widget, &tmp_w, &tmp_h); if(tmp_w > wmax) { wmax = tmp_w; } wsum += tmp_w; if(tmp_h > hmax) { hmax = tmp_h; } hsum += tmp_h; iter = a3d_list_next(iter); } if(self->orientation == A3D_LISTBOX_ORIENTATION_HORIZONTAL) { *w = wsum; *h = hmax; } else { *w = wmax; *h = hsum; } }
void a3d_workq_purge(a3d_workq_t* self) { assert(self); LOGD("debug"); pthread_mutex_lock(&self->mutex); // purge the pending queue a3d_listitem_t* iter = a3d_list_head(self->queue_pending); while(iter) { a3d_workqnode_t* node; node = (a3d_workqnode_t*) a3d_list_peekitem(iter); if(node->purge_id != self->purge_id) { a3d_list_remove(self->queue_pending, &iter); (*self->purge_fn)(self->owner, node->task, node->status); a3d_workqnode_delete(&node); } else { iter = a3d_list_next(iter); } } // purge the active queue (non-blocking) iter = a3d_list_head(self->queue_active); while(iter) { a3d_workqnode_t* node; node = (a3d_workqnode_t*) a3d_list_peekitem(iter); if(node->purge_id != self->purge_id) { node->purge_id = A3D_WORKQ_PURGE; } iter = a3d_list_next(iter); } // purge the complete queue iter = a3d_list_head(self->queue_complete); while(iter) { a3d_workqnode_t* node; node = (a3d_workqnode_t*) a3d_list_peekitem(iter); if((node->purge_id != self->purge_id) || (node->purge_id == A3D_WORKQ_PURGE)) { a3d_list_remove(self->queue_complete, &iter); (*self->purge_fn)(self->owner, node->task, node->status); a3d_workqnode_delete(&node); } else { iter = a3d_list_next(iter); } } // swap the purge id if(self->purge_id != A3D_WORKQ_PURGE) { self->purge_id = 1 - self->purge_id; } pthread_mutex_unlock(&self->mutex); }
static void a3d_textbox_reflow(a3d_widget_t* widget, float w, float h) { assert(widget); LOGD("debug w=%f, h=%f", w, h); a3d_textbox_t* self = (a3d_textbox_t*) widget; // reflow text when changes occur if((self->dirty == 0) && (self->last_w == w) && (self->last_h == h)) { return; } self->dirty = 0; self->last_w = w; self->last_h = h; // determine maxi a3d_font_t* font = a3d_screen_font(widget->screen); float aspect = a3d_font_aspectRatio(font); float size = a3d_screen_layoutText(widget->screen, self->style_text); int maxi = (int) (w/(aspect*size)) - 1; // maxi does not include null character // but max_len does // limit to max_len if((maxi >= self->max_len) || (maxi == 0)) { maxi = self->max_len - 1; } // clear the text a3d_listbox_t* listbox = (a3d_listbox_t*) self; a3d_listitem_t* iter = a3d_list_head(listbox->list); while(iter) { a3d_text_t* text; text = (a3d_text_t*) a3d_list_remove(listbox->list, &iter); a3d_text_delete(&text); } // initialize parser char tok[256]; char dst[256]; int srci = 0; int toki = 0; int dsti = 0; int type = A3D_TOKEN_END; // reflow the string(s) iter = a3d_list_head(self->strings); while(iter) { const char* src = (const char*) a3d_list_peekitem(iter); srci = 0; type = getToken(src, tok, &srci, &toki); while(type != A3D_TOKEN_END) { if(type == A3D_TOKEN_BREAK) { if(dsti > 0) { a3d_textbox_printText(self, dst); a3d_textbox_printText(self, ""); } else { a3d_textbox_printText(self, ""); } dsti = 0; break; } if(dsti == 0) { strncpy(dst, tok, 256); dst[255] = '\0'; dsti = toki; } else { if(dsti + toki + 1 <= maxi) { strcat(dst, " "); strcat(dst, tok); dst[255] = '\0'; dsti += toki + 1; } else { a3d_textbox_printText(self, dst); strncpy(dst, tok, 256); dst[255] = '\0'; dsti = toki; } } type = getToken(src, tok, &srci, &toki); } iter = a3d_list_next(iter); } if(dsti > 0) { a3d_textbox_printText(self, dst); } }