118 |
118 |
119 static void uic_context_unbind_vars(UiContext *ctx) { |
119 static void uic_context_unbind_vars(UiContext *ctx) { |
120 CxMapIterator mi = cxMapIterator(ctx->vars); |
120 CxMapIterator mi = cxMapIterator(ctx->vars); |
121 cx_foreach(CxMapEntry*, entry, mi) { |
121 cx_foreach(CxMapEntry*, entry, mi) { |
122 UiVar *var = entry->value; |
122 UiVar *var = entry->value; |
123 if(var->from && var->from_ctx && var->from_ctx != ctx) { |
123 // var->from && var->from_ctx && var->from_ctx != ctx |
|
124 if(var->from) { |
124 uic_save_var2(var); |
125 uic_save_var2(var); |
125 uic_copy_binding(var, var->from, FALSE); |
126 uic_copy_binding(var, var->from, FALSE); |
126 cxMapPut(var->from_ctx->vars_unbound, *entry->key, var->from); |
127 cxMapPut(var->from->from_ctx->vars_unbound, *entry->key, var->from); |
127 var->from_ctx = ctx; |
128 var->from = NULL; |
128 } |
129 } |
129 } |
130 } |
130 |
131 |
131 if(ctx->documents) { |
132 if(ctx->documents) { |
132 CxIterator i = cxListIterator(ctx->documents); |
133 CxIterator i = cxListIterator(ctx->documents); |
284 fprintf(stderr, "UI Error: var has incompatible type.\n"); |
287 fprintf(stderr, "UI Error: var has incompatible type.\n"); |
285 return; |
288 return; |
286 } |
289 } |
287 |
290 |
288 void *fromvalue = from->value; |
291 void *fromvalue = from->value; |
|
292 void *tovalue = to->value; |
289 // update var |
293 // update var |
290 if(copytodoc) { |
294 if(copytodoc) { |
291 to->from = from; |
295 to->from = from; // from which UiVar are the bindings copied |
292 to->from_ctx = from->from_ctx; |
296 from->original_value = fromvalue; // save original value otherwise it would be lost |
|
297 // widgets store a reference to the UiVar with their value |
|
298 // the UiVar object must be updated to contain the current value object |
|
299 from->value = tovalue; |
|
300 } else { |
|
301 if(to->original_value) { |
|
302 to->value = to->original_value; |
|
303 tovalue = to->value; |
|
304 } |
293 } |
305 } |
294 |
306 |
295 ui_setop_enable(TRUE); |
307 ui_setop_enable(TRUE); |
296 |
308 |
297 // copy binding |
309 // copy binding |
299 switch(from->type) { |
311 switch(from->type) { |
300 default: fprintf(stderr, "uic_copy_binding: wtf!\n"); break; |
312 default: fprintf(stderr, "uic_copy_binding: wtf!\n"); break; |
301 case UI_VAR_SPECIAL: break; |
313 case UI_VAR_SPECIAL: break; |
302 case UI_VAR_INTEGER: { |
314 case UI_VAR_INTEGER: { |
303 UiInteger *f = fromvalue; |
315 UiInteger *f = fromvalue; |
304 UiInteger *t = to->value; |
316 UiInteger *t = tovalue; |
305 if(!f->obj) break; |
317 if(!f->obj) break; |
306 uic_int_copy(f, t); |
318 uic_int_copy(f, t); |
307 t->set(t, t->value); |
319 t->set(t, t->value); |
308 break; |
320 break; |
309 } |
321 } |
310 case UI_VAR_DOUBLE: { |
322 case UI_VAR_DOUBLE: { |
311 UiDouble *f = fromvalue; |
323 UiDouble *f = fromvalue; |
312 UiDouble *t = to->value; |
324 UiDouble *t = tovalue; |
313 if(!f->obj) break; |
325 if(!f->obj) break; |
314 uic_double_copy(f, t); |
326 uic_double_copy(f, t); |
315 t->set(t, t->value); |
327 t->set(t, t->value); |
316 break; |
328 break; |
317 } |
329 } |
318 case UI_VAR_STRING: { |
330 case UI_VAR_STRING: { |
319 UiString *f = fromvalue; |
331 UiString *f = fromvalue; |
320 UiString *t = to->value; |
332 UiString *t = tovalue; |
321 if(!f->obj) break; |
333 if(!f->obj) break; |
322 uic_string_copy(f, t); |
334 uic_string_copy(f, t); |
323 char *tvalue = t->value.ptr ? t->value.ptr : ""; |
335 char *tvalue = t->value.ptr ? t->value.ptr : ""; |
|
336 char *fvalue = f->value.ptr ? f->value.ptr : ""; |
324 t->set(t, tvalue); |
337 t->set(t, tvalue); |
325 break; |
338 break; |
326 } |
339 } |
327 case UI_VAR_TEXT: { |
340 case UI_VAR_TEXT: { |
328 UiText *f = fromvalue; |
341 UiText *f = fromvalue; |
329 UiText *t = to->value; |
342 UiText *t = tovalue; |
330 if(!f->obj) break; |
343 if(!f->obj) break; |
331 uic_text_copy(f, t); |
344 uic_text_copy(f, t); |
332 t->restore(t); |
345 t->restore(t); |
333 break; |
346 break; |
334 } |
347 } |
335 case UI_VAR_LIST: { |
348 case UI_VAR_LIST: { |
336 // TODO: not sure how correct this is |
349 UiList *f = fromvalue; |
337 |
350 UiList *t = tovalue; |
338 UiList *f = from->value; |
351 uic_list_copy(f, t); |
339 UiList *t = to->value; |
352 ui_list_update(t); |
340 if (f->obj) { |
|
341 t->obj = f->obj; |
|
342 t->update = f->update; |
|
343 t->getselection = f->getselection; |
|
344 t->setselection = f->setselection; |
|
345 } |
|
346 |
|
347 UiVar tmp = *from; |
|
348 *from = *to; |
|
349 *to = tmp; |
|
350 |
|
351 UiList* t2 = to->value; |
|
352 if(t->update) { |
|
353 t->update(t, -1); |
|
354 } |
|
355 ui_notify(t2->observers, NULL); // TODO: why not t? |
|
356 |
|
357 break; |
353 break; |
358 } |
354 } |
359 case UI_VAR_RANGE: { |
355 case UI_VAR_RANGE: { |
360 UiRange *f = fromvalue; |
356 UiRange *f = fromvalue; |
361 UiRange *t = to->value; |
357 UiRange *t = tovalue; |
362 if(!f->obj) break; |
358 if(!f->obj) break; |
363 uic_range_copy(f, t); |
359 uic_range_copy(f, t); |
364 t->setextent(t, t->extent); |
360 t->setextent(t, t->extent); |
365 t->setrange(t, t->min, t->max); |
361 t->setrange(t, t->min, t->max); |
366 t->set(t, t->value); |
362 t->set(t, t->value); |
367 break; |
363 break; |
368 } |
364 } |
369 case UI_VAR_GENERIC: { |
365 case UI_VAR_GENERIC: { |
370 UiGeneric *f = fromvalue; |
366 UiGeneric *f = fromvalue; |
371 UiGeneric *t = to->value; |
367 UiGeneric *t = tovalue; |
372 if(!f->obj) break; |
368 if(!f->obj) break; |
373 uic_generic_copy(f, t); |
369 uic_generic_copy(f, t); |
374 t->set(t, t->value, t->type); |
370 t->set(t, t->value, t->type); |
375 break; |
371 break; |
376 } |
372 } |