# Changeset View

Changeset View

# Standalone View

Standalone View

# src/lib/elementary/efl_ui_relative_layout.c

- This file was added.

1 | #include "efl_ui_relative_layout_private.h" | ||||
---|---|---|---|---|---|

2 | | ||||

3 | #define MY_CLASS EFL_UI_RELATIVE_LAYOUT_CLASS | ||||

4 | #define MY_CLASS_NAME "Efl.Ui.Relative_Layout" | ||||

5 | | ||||

6 | #define LEFT 0 | ||||

7 | #define RIGHT 1 | ||||

8 | #define TOP 2 | ||||

9 | #define BOTTOM 3 | ||||

10 | | ||||

11 | #define START (axis ? TOP : LEFT) | ||||

12 | #define END (axis ? BOTTOM : RIGHT) | ||||

13 | | ||||

14 | static void _child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis); | ||||

15 | | ||||

16 | static int | ||||

17 | _chain_sort_cb(const void *l1, const void *l2) | ||||

18 | { | ||||

19 | Efl_Ui_Relative_Layout_Calc *calc1, *calc2; | ||||

20 | | ||||

21 | calc1 = EINA_INLIST_CONTAINER_GET(l1, Efl_Ui_Relative_Layout_Calc); | ||||

22 | calc2 = EINA_INLIST_CONTAINER_GET(l2, Efl_Ui_Relative_Layout_Calc); | ||||

23 | | ||||

24 | return calc2->comp_factor <= calc1->comp_factor ? -1 : 1; | ||||

25 | } | ||||

26 | | ||||

27 | static Efl_Ui_Relative_Layout_Child * | ||||

28 | _efl_ui_relative_layout_register(Efl_Ui_Relative_Layout_Data *pd, Eo *child) | ||||

29 | { | ||||

30 | Efl_Ui_Relative_Layout_Child *rc; | ||||

31 | | ||||

32 | rc = calloc(1, sizeof(Efl_Ui_Relative_Layout_Child)); | ||||

33 | if (!rc) return NULL; | ||||

34 | | ||||

35 | rc->obj = child; | ||||

36 | rc->layout = pd->obj; | ||||

37 | rc->rel[LEFT].to = rc->layout; | ||||

38 | rc->rel[LEFT].relative = 0.0; | ||||

39 | rc->rel[RIGHT].to = rc->layout; | ||||

40 | rc->rel[RIGHT].relative = 1.0; | ||||

41 | rc->rel[TOP].to = rc->layout; | ||||

42 | rc->rel[TOP].relative = 0.0; | ||||

43 | rc->rel[BOTTOM].to = rc->layout; | ||||

44 | rc->rel[BOTTOM].relative = 1.0; | ||||

45 | | ||||

46 | if (pd->obj == child) | ||||

47 | { | ||||

48 | rc->calc.state[0] = RELATIVE_CALC_DONE; | ||||

49 | rc->calc.state[1] = RELATIVE_CALC_DONE; | ||||

50 | rc->calc.chain_state[0] = RELATIVE_CALC_DONE; | ||||

51 | rc->calc.chain_state[1] = RELATIVE_CALC_DONE; | ||||

52 | } | ||||

53 | else | ||||

54 | { | ||||

55 | efl_ui_widget_sub_object_add(pd->obj, child); | ||||

56 | efl_canvas_group_member_add(pd->obj, child); | ||||

57 | efl_canvas_group_change(pd->obj); | ||||

58 | } | ||||

59 | | ||||

60 | eina_hash_add(pd->children, &child, rc); | ||||

61 | | ||||

62 | return rc; | ||||

63 | } | ||||

64 | | ||||

65 | static Efl_Ui_Relative_Layout_Child * | ||||

66 | _relative_child_get(Efl_Ui_Relative_Layout_Data *pd, Eo *child) | ||||

67 | { | ||||

68 | Efl_Ui_Relative_Layout_Child *rc; | ||||

69 | | ||||

70 | rc = eina_hash_find(pd->children, &child); | ||||

71 | if (!rc) | ||||

72 | rc = _efl_ui_relative_layout_register(pd, child); | ||||

73 | | ||||

74 | return rc; | ||||

75 | } | ||||

76 | | ||||

77 | static Efl_Ui_Relative_Layout_Child * | ||||

78 | _relative_child_find(const Eina_Hash *children, Eo *target) | ||||

79 | { | ||||

80 | Efl_Ui_Relative_Layout_Child *child; | ||||

81 | | ||||

82 | child = eina_hash_find(children, &target); | ||||

83 | if (!child) | ||||

84 | ERR("target(%p(%s)) is not registered", target, efl_class_name_get(target)); | ||||

85 | | ||||

86 | return child; | ||||

87 | } | ||||

88 | | ||||

89 | static void | ||||

90 | _child_aspect_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis) | ||||

91 | { | ||||

92 | Efl_Ui_Relative_Layout_Calc *calc = &child->calc; | ||||

93 | int temph; | ||||

94 | | ||||

95 | if ((calc->aspect[0] <= 0) || (calc->aspect[1] <= 0)) | ||||

96 | { | ||||

97 | ERR("Invalid aspect parameter for obj(%p), aspect(%d, %d) ", | ||||

98 | child->obj, calc->aspect[0], calc->aspect[1]); | ||||

99 | return; | ||||

100 | } | ||||

101 | | ||||

102 | switch (calc->aspect_type) | ||||

103 | { | ||||

104 | case EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL: | ||||

105 | if (axis) _child_calc(child, !axis); | ||||

106 | calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0]; | ||||

107 | break; | ||||

108 | case EFL_GFX_SIZE_HINT_ASPECT_VERTICAL: | ||||

109 | if (!axis) _child_calc(child, !axis); | ||||

110 | calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1]; | ||||

111 | break; | ||||

112 | case EFL_GFX_SIZE_HINT_ASPECT_BOTH: | ||||

113 | if (calc->state[!axis] != RELATIVE_CALC_ON) | ||||

114 | _child_calc(child, !axis); | ||||

115 | temph = calc->want[axis].length * calc->aspect[!axis] / calc->aspect[axis]; | ||||

116 | if (temph > calc->want[!axis].length) | ||||

117 | { | ||||

118 | temph = calc->want[!axis].length; | ||||

119 | calc->want[axis].length = temph * calc->aspect[axis] / calc->aspect[!axis]; | ||||

120 | } | ||||

121 | else | ||||

122 | calc->want[!axis].length = temph; | ||||

123 | break; | ||||

124 | default: | ||||

125 | if (calc->state[!axis] != RELATIVE_CALC_ON) | ||||

126 | _child_calc(child, !axis); | ||||

127 | temph = calc->want[axis].length * calc->aspect[!axis] / calc->aspect[axis]; | ||||

128 | if (temph < calc->want[!axis].length) | ||||

129 | { | ||||

130 | temph = calc->want[!axis].length; | ||||

131 | calc->want[axis].length = temph * calc->aspect[axis] / calc->aspect[!axis]; | ||||

132 | } | ||||

133 | else | ||||

134 | calc->want[!axis].length = temph; | ||||

135 | } | ||||

136 | | ||||

137 | //calculate max size | ||||

138 | if (calc->want[0].length > calc->max[0]) | ||||

139 | { | ||||

140 | calc->want[0].length = calc->max[0]; | ||||

141 | calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0]; | ||||

142 | } | ||||

143 | if (calc->want[1].length > calc->max[1]) | ||||

144 | { | ||||

145 | calc->want[1].length = calc->max[1]; | ||||

146 | calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1]; | ||||

147 | } | ||||

148 | //calculate min size | ||||

149 | if (calc->want[0].length < calc->min[0]) | ||||

150 | { | ||||

151 | calc->want[0].length = calc->min[0]; | ||||

152 | calc->want[1].length = calc->want[0].length * calc->aspect[1] / calc->aspect[0]; | ||||

153 | } | ||||

154 | if (calc->want[1].length < calc->min[1]) | ||||

155 | { | ||||

156 | calc->want[1].length = calc->min[1]; | ||||

157 | calc->want[0].length = calc->want[1].length * calc->aspect[0] / calc->aspect[1]; | ||||

158 | } | ||||

159 | | ||||

160 | //calculate align | ||||

161 | calc->want[!axis].position = | ||||

162 | calc->space[!axis].position + | ||||

163 | (calc->space[!axis].length - calc->want[!axis].length) * calc->align[!axis]; | ||||

164 | } | ||||

165 | | ||||

166 | static Eina_Bool | ||||

167 | _child_chain_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis) | ||||

168 | { | ||||

169 | Efl_Ui_Relative_Layout_Child *head, *tail, *o; | ||||

170 | Efl_Gfx_Size_Hint_Aspect aspect_type; | ||||

171 | int space, min_sum = 0; | ||||

172 | double weight_sum = 0, cur_pos; | ||||

173 | Eina_Inlist *chain = NULL; | ||||

174 | | ||||

175 | if (child->calc.chain_state[axis] == RELATIVE_CALC_DONE) | ||||

176 | return EINA_TRUE; | ||||

177 | | ||||

178 | if ((child != child->calc.to[START]->calc.to[END]) && | ||||

179 | (child != child->calc.to[END]->calc.to[START])) | ||||

180 | return EINA_FALSE; | ||||

181 | | ||||

182 | // find head | ||||

183 | head = child; | ||||

184 | while (head == head->calc.to[START]->calc.to[END]) | ||||

185 | head = head->calc.to[START]; | ||||

186 | | ||||

187 | //calculate weight_sum | ||||

188 | aspect_type = !axis ? EFL_GFX_SIZE_HINT_ASPECT_VERTICAL : EFL_GFX_SIZE_HINT_ASPECT_HORIZONTAL; | ||||

189 | o = head; | ||||

190 | do | ||||

191 | { | ||||

192 | if ((o->calc.aspect[0] > 0) && (o->calc.aspect[1] > 0) && | ||||

193 | (o->calc.aspect_type == aspect_type)) | ||||

194 | { | ||||

195 | _child_calc(o, !axis); | ||||

196 | if (o->calc.want[axis].length > o->calc.min[axis]) | ||||

197 | o->calc.min[axis] = o->calc.want[axis].length; | ||||

198 | } | ||||

199 | else if ((o->calc.aspect[0] <= 0) ^ (o->calc.aspect[1] <= 0)) | ||||

200 | { | ||||

201 | ERR("Invalid aspect parameter for obj(%p), aspect(%d, %d) ", | ||||

202 | o->obj, o->calc.aspect[0], o->calc.aspect[1]); | ||||

203 | } | ||||

204 | | ||||

205 | o->calc.space[axis].length = o->calc.min[axis] + | ||||

206 | o->calc.margin[START] + o->calc.margin[END]; | ||||

207 | min_sum += o->calc.space[axis].length; | ||||

208 | weight_sum += o->calc.weight[axis]; | ||||

209 | | ||||

210 | tail = o; | ||||

211 | o = o->calc.to[END]; | ||||

212 | } | ||||

213 | while (o->calc.to[START] == tail); | ||||

214 | | ||||

215 | _child_calc(head->calc.to[START], axis); | ||||

216 | _child_calc(tail->calc.to[END], axis); | ||||

217 | | ||||

218 | cur_pos = head->calc.to[START]->calc.want[axis].position + | ||||

219 | (head->calc.to[START]->calc.want[axis].length * head->rel[START].relative); | ||||

220 | space = tail->calc.to[END]->calc.want[axis].position + | ||||

221 | (tail->calc.to[END]->calc.want[axis].length * tail->rel[END].relative) - cur_pos; | ||||

222 | | ||||

223 | if ((space <= min_sum) || EINA_DBL_EQ(weight_sum, 0.0)) | ||||

224 | cur_pos += (space - min_sum) * head->calc.align[axis]; | ||||

225 | else | ||||

226 | { | ||||

227 | Efl_Ui_Relative_Layout_Calc *calc; | ||||

228 | double weight_len, orig_space = space, orig_weight = weight_sum; | ||||

229 | Eina_Inlist *itr; | ||||

230 | | ||||

231 | // Calculate compare factor | ||||

232 | for (o = head; o != tail->calc.to[END]; o = o->calc.to[END]) | ||||

233 | { | ||||

234 | double denom; | ||||

235 | | ||||

236 | calc = &o->calc; | ||||

237 | denom = (calc->weight[axis] * orig_space) - (orig_weight * calc->min[axis]); | ||||

238 | if (denom > 0) | ||||

239 | { | ||||

240 | calc->comp_factor = (calc->weight[axis] * orig_space) / denom; | ||||

241 | chain = eina_inlist_append(chain, EINA_INLIST_GET(calc)); | ||||

242 | } | ||||

243 | else | ||||

244 | { | ||||

245 | space -= calc->space[axis].length; | ||||

246 | weight_sum -= calc->weight[axis]; | ||||

247 | } | ||||

248 | } | ||||

249 | | ||||

250 | chain = eina_inlist_sort(chain, _chain_sort_cb); | ||||

251 | | ||||

252 | for (itr = chain; itr; itr = itr->next) | ||||

253 | { | ||||

254 | calc = EINA_INLIST_CONTAINER_GET(itr, Efl_Ui_Relative_Layout_Calc); | ||||

255 | weight_len = (space * calc->weight[axis]) / weight_sum; | ||||

256 | | ||||

257 | if (calc->space[axis].length < weight_len) | ||||

258 | calc->space[axis].length = weight_len; | ||||

259 | else | ||||

260 | { | ||||

261 | weight_sum -= calc->weight[axis]; | ||||

262 | space -= calc->space[axis].length; | ||||

263 | } | ||||

264 | } | ||||

265 | } | ||||

266 | | ||||

267 | for (o = head; o != tail->calc.to[END]; o = o->calc.to[END]) | ||||

268 | { | ||||

269 | o->calc.space[axis].position = cur_pos + o->calc.margin[START] + 0.5; | ||||

270 | cur_pos += o->calc.space[axis].length; | ||||

271 | o->calc.space[axis].length -= o->calc.margin[START] + o->calc.margin[END]; | ||||

272 | o->calc.chain_state[axis] = RELATIVE_CALC_DONE; | ||||

273 | } | ||||

274 | | ||||

275 | return EINA_TRUE; | ||||

276 | } | ||||

277 | | ||||

278 | static void | ||||

279 | _child_calc(Efl_Ui_Relative_Layout_Child *child, Eina_Bool axis) | ||||

280 | { | ||||

281 | Efl_Ui_Relative_Layout_Calc *calc = &child->calc; | ||||

282 | | ||||

283 | if (calc->state[axis] == RELATIVE_CALC_DONE) | ||||

284 | return; | ||||

285 | | ||||

286 | if (calc->state[axis] == RELATIVE_CALC_ON) | ||||

287 | { | ||||

288 | ERR("%c-axis circular dependency when calculating part \"%s\"(%p).", | ||||

289 | axis ? 'Y' : 'X', efl_class_name_get(child->obj), child->obj); | ||||

290 | return; | ||||

291 | } | ||||

292 | | ||||

293 | calc->state[axis] = RELATIVE_CALC_ON; | ||||

294 | | ||||

295 | if (!_child_chain_calc(child, axis)) | ||||

296 | { | ||||

297 | _child_calc(calc->to[START], axis); | ||||

298 | _child_calc(calc->to[END], axis); | ||||

299 | | ||||

300 | calc->space[axis].position = calc->to[START]->calc.want[axis].position | ||||

301 | + (calc->to[START]->calc.want[axis].length * child->rel[START].relative) | ||||

302 | + calc->margin[START]; | ||||

303 | calc->space[axis].length = calc->to[END]->calc.want[axis].position | ||||

304 | + (calc->to[END]->calc.want[axis].length * child->rel[END].relative) | ||||

305 | - calc->margin[END] - calc->space[axis].position; | ||||

306 | } | ||||

307 | | ||||

308 | if (calc->fill[axis] && (calc->weight[axis] > 0)) | ||||

309 | calc->want[axis].length = calc->space[axis].length; | ||||

310 | | ||||

311 | if (!calc->aspect[0] && !calc->aspect[1]) | ||||

312 | { | ||||

313 | if (calc->want[axis].length > calc->max[axis]) | ||||

314 | calc->want[axis].length = calc->max[axis]; | ||||

315 | | ||||

316 | if (calc->want[axis].length < calc->min[axis]) | ||||

317 | calc->want[axis].length = calc->min[axis]; | ||||

318 | } | ||||

319 | else | ||||

320 | { | ||||

321 | _child_aspect_calc(child, axis); | ||||

322 | } | ||||

323 | | ||||

324 | //calculate align | ||||

325 | calc->want[axis].position = | ||||

326 | calc->space[axis].position + | ||||

327 | (calc->space[axis].length - calc->want[axis].length) * calc->align[axis]; | ||||

328 | | ||||

329 | child->calc.state[axis] = RELATIVE_CALC_DONE; | ||||

330 | } | ||||

331 | | ||||

332 | static void | ||||

333 | _hash_free_cb(void *data) | ||||

334 | { | ||||

335 | Efl_Ui_Relative_Layout_Child *child = data; | ||||

336 | | ||||

337 | free(child); | ||||

338 | } | ||||

339 | | ||||

340 | static Eina_Bool | ||||

341 | _hash_free_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, | ||||

342 | void *data, void *fdata EINA_UNUSED) | ||||

343 | { | ||||

344 | Efl_Ui_Relative_Layout_Child *child = data; | ||||

345 | | ||||

346 | _elm_widget_sub_object_redirect_to_top(child->layout, child->obj); | ||||

347 | _hash_free_cb(child); | ||||

348 | | ||||

349 | return EINA_TRUE; | ||||

350 | } | ||||

351 | | ||||

352 | static Eina_Bool | ||||

353 | _hash_child_calc_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, | ||||

354 | void *data, void *fdata EINA_UNUSED) | ||||

355 | { | ||||

356 | Efl_Ui_Relative_Layout_Child *child = data; | ||||

357 | Eina_Rect want; | ||||

358 | | ||||

359 | if (child->obj == child->layout) | ||||

360 | return EINA_TRUE; | ||||

361 | | ||||

362 | _child_calc(child, 0); | ||||

363 | _child_calc(child, 1); | ||||

364 | | ||||

365 | want.x = child->calc.want[0].position; | ||||

366 | want.w = child->calc.want[0].length; | ||||

367 | want.y = child->calc.want[1].position; | ||||

368 | want.h = child->calc.want[1].length; | ||||

369 | | ||||

370 | efl_gfx_entity_geometry_set(child->obj, want); | ||||

371 | return EINA_TRUE; | ||||

372 | } | ||||

373 | | ||||

374 | | ||||

375 | static Eina_Bool | ||||

376 | _hash_child_init_foreach_cb(const Eina_Hash *hash, const void *key EINA_UNUSED, | ||||

377 | void *data, void *fdata EINA_UNUSED) | ||||

378 | { | ||||

379 | Eina_Size2D max, min, aspect; | ||||

380 | Efl_Ui_Relative_Layout_Child *child = data; | ||||

381 | Efl_Ui_Relative_Layout_Calc *calc = &(child->calc); | ||||

382 | | ||||

383 | calc->to[LEFT] = _relative_child_find(hash, child->rel[LEFT].to); | ||||

384 | if (!calc->to[LEFT]) calc->to[LEFT] = eina_hash_find(hash, &child->layout); | ||||

385 | calc->to[RIGHT] = _relative_child_find(hash, child->rel[RIGHT].to); | ||||

386 | if (!calc->to[RIGHT]) calc->to[RIGHT] = eina_hash_find(hash, &child->layout); | ||||

387 | calc->to[TOP] = _relative_child_find(hash, child->rel[TOP].to); | ||||

388 | if (!calc->to[TOP]) calc->to[TOP] = eina_hash_find(hash, &child->layout); | ||||

389 | calc->to[BOTTOM] = _relative_child_find(hash, child->rel[BOTTOM].to); | ||||

390 | if (!calc->to[BOTTOM]) calc->to[BOTTOM] = eina_hash_find(hash, &child->layout); | ||||

391 | | ||||

392 | if (child->obj == child->layout) | ||||

393 | { | ||||

394 | Eina_Rect want = efl_gfx_entity_geometry_get(child->obj); | ||||

395 | calc->want[0].position = want.x; | ||||

396 | calc->want[0].length = want.w; | ||||

397 | calc->want[1].position = want.y; | ||||

398 | calc->want[1].length = want.h; | ||||

399 | calc->state[0] = RELATIVE_CALC_DONE; | ||||

400 | calc->state[1] = RELATIVE_CALC_DONE; | ||||

401 | calc->chain_state[0] = RELATIVE_CALC_DONE; | ||||

402 | calc->chain_state[1] = RELATIVE_CALC_DONE; | ||||

403 | return EINA_TRUE; | ||||

404 | } | ||||

405 | | ||||

406 | calc->state[0] = RELATIVE_CALC_NONE; | ||||

407 | calc->state[1] = RELATIVE_CALC_NONE; | ||||

408 | calc->chain_state[0] = RELATIVE_CALC_NONE; | ||||

409 | calc->chain_state[1] = RELATIVE_CALC_NONE; | ||||

410 | | ||||

411 | efl_gfx_size_hint_weight_get(child->obj, &calc->weight[0], &calc->weight[1]); | ||||

412 | efl_gfx_size_hint_align_get(child->obj, &calc->align[0], &calc->align[1]); | ||||

413 | efl_gfx_size_hint_fill_get(child->obj, &calc->fill[0], &calc->fill[1]); | ||||

414 | efl_gfx_size_hint_aspect_get(child->obj, &calc->aspect_type, &aspect); | ||||

415 | calc->aspect[0] = aspect.w; | ||||

416 | calc->aspect[1] = aspect.h; | ||||

417 | efl_gfx_size_hint_margin_get(child->obj, &calc->margin[LEFT], &calc->margin[RIGHT], | ||||

418 | &calc->margin[TOP], &calc->margin[BOTTOM]); | ||||

419 | max = efl_gfx_size_hint_max_get(child->obj); | ||||

420 | min = efl_gfx_size_hint_combined_min_get(child->obj); | ||||

421 | calc->max[0] = max.w; | ||||

422 | calc->max[1] = max.h; | ||||

423 | calc->min[0] = min.w; | ||||

424 | calc->min[1] = min.h; | ||||

425 | | ||||

426 | calc->want[0].position = 0; | ||||

427 | calc->want[0].length = 0; | ||||

428 | calc->want[1].position = 0; | ||||

429 | calc->want[1].length = 0; | ||||

430 | calc->space[0].position = 0; | ||||

431 | calc->space[0].length = 0; | ||||

432 | calc->space[1].position = 0; | ||||

433 | calc->space[1].length = 0; | ||||

434 | | ||||

435 | if (calc->weight[0] < 0) calc->weight[0] = 0; | ||||

436 | if (calc->weight[1] < 0) calc->weight[1] = 0; | ||||

437 | | ||||

438 | if (calc->align[0] < 0) calc->align[0] = 0; | ||||

439 | if (calc->align[1] < 0) calc->align[1] = 0; | ||||

440 | if (calc->align[0] > 1) calc->align[0] = 1; | ||||

441 | if (calc->align[1] > 1) calc->align[1] = 1; | ||||

442 | | ||||

443 | if (calc->max[0] < 0) calc->max[0] = INT_MAX; | ||||

444 | if (calc->max[1] < 0) calc->max[1] = INT_MAX; | ||||

445 | if (calc->aspect[0] < 0) calc->aspect[0] = 0; | ||||

446 | if (calc->aspect[1] < 0) calc->aspect[1] = 0; | ||||

447 | | ||||

448 | return EINA_TRUE; | ||||

449 | } | ||||

450 | | ||||

451 | static void | ||||

452 | _on_size_hints_changed(void *data EINA_UNUSED, Evas *e EINA_UNUSED, | ||||

453 | Evas_Object *obj, void *event_info EINA_UNUSED) | ||||

454 | { | ||||

455 | efl_pack_layout_request(obj); | ||||

456 | } | ||||

457 | | ||||

458 | EOLIAN static void | ||||

459 | _efl_ui_relative_layout_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) | ||||

460 | { | ||||

461 | eina_hash_foreach(pd->children, _hash_child_init_foreach_cb, NULL); | ||||

462 | eina_hash_foreach(pd->children, _hash_child_calc_foreach_cb, NULL); | ||||

463 | | ||||

464 | efl_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); | ||||

465 | } | ||||

Jaehyun_Cho: EFL_PACK_EVENT_LAYOUT_UPDATED event is provided by Efl.Pack interface.
Since Efl.Ui. | |||||

466 | | ||||

467 | EOLIAN static void | ||||

468 | _efl_ui_relative_layout_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED) | ||||

469 | { | ||||

470 | efl_canvas_group_need_recalculate_set(obj, EINA_TRUE); | ||||

471 | } | ||||

472 | | ||||

473 | EOLIAN static void | ||||

474 | _efl_ui_relative_layout_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED) | ||||

475 | { | ||||

476 | efl_pack_layout_update(obj); | ||||

477 | } | ||||

478 | | ||||

479 | EOLIAN static void | ||||

480 | _efl_ui_relative_layout_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED, Eina_Size2D sz) | ||||

481 | { | ||||

482 | efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz); | ||||

483 | efl_canvas_group_change(obj); | ||||

484 | } | ||||

485 | | ||||

486 | EOLIAN static void | ||||

487 | _efl_ui_relative_layout_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED, Eina_Position2D pos) | ||||

488 | { | ||||

489 | efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos); | ||||

490 | efl_canvas_group_change(obj); | ||||

491 | } | ||||

492 | | ||||

493 | EOLIAN static void | ||||

494 | _efl_ui_relative_layout_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Relative_Layout_Data *pd EINA_UNUSED) | ||||

495 | { | ||||

496 | evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, NULL); | ||||

497 | efl_canvas_group_add(efl_super(obj, MY_CLASS)); | ||||

498 | elm_widget_sub_object_parent_add(obj); | ||||

499 | | ||||

500 | elm_widget_highlight_ignore_set(obj, EINA_TRUE); | ||||

501 | } | ||||

502 | | ||||

503 | EOLIAN static Eo * | ||||

504 | _efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) | ||||

505 | { | ||||

506 | obj = efl_constructor(efl_super(obj, MY_CLASS)); | ||||

507 | efl_canvas_object_type_set(obj, MY_CLASS_NAME); | ||||

508 | efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_SKIPPED); | ||||

509 | efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER); | ||||

510 | | ||||

511 | pd->obj = obj; | ||||

512 | pd->children = eina_hash_pointer_new(_hash_free_cb); | ||||

513 | _efl_ui_relative_layout_register(pd, obj); | ||||

514 | | ||||

Not Done ReplyIt seems that child does nothing if the child is relative layout itself. Is there any reason why relative layout itself becomes a child? Jaehyun_Cho: It seems that child does nothing if the child is relative layout itself.
Is there any reason… | |||||

Not Done ReplyA child can have a relationship with parent(relative layout). in this case, if relative layout itself becomes a child, layout calculation function can be more simple. YOhoho: A child can have a relationship with parent(relative layout). in this case, if relative layout… | |||||

515 | return obj; | ||||

516 | } | ||||

517 | | ||||

518 | EOLIAN static void | ||||

519 | _efl_ui_relative_layout_efl_object_destructor(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) | ||||

520 | { | ||||

521 | eina_hash_free(pd->children); | ||||

522 | efl_destructor(efl_super(obj, MY_CLASS)); | ||||

523 | } | ||||

524 | | ||||

525 | EOLIAN static void | ||||

526 | _efl_ui_relative_layout_unregister(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Efl_Object *child) | ||||

527 | { | ||||

528 | _elm_widget_sub_object_redirect_to_top(obj, child); | ||||

529 | if (!eina_hash_del_by_key(pd->children, &child)) | ||||

530 | ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); | ||||

531 | } | ||||

532 | | ||||

533 | EOLIAN static void | ||||

534 | _efl_ui_relative_layout_unregister_all(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd) | ||||

535 | { | ||||

536 | eina_hash_foreach(pd->children, _hash_free_foreach_cb, NULL); | ||||

537 | } | ||||

538 | | ||||

539 | EOLIAN static Eina_Iterator * | ||||

540 | _efl_ui_relative_layout_children_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd) | ||||

541 | { | ||||

542 | return eina_hash_iterator_data_new(pd->children); | ||||

543 | } | ||||

544 | | ||||

545 | EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(left, LEFT); | ||||

546 | EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(right, RIGHT); | ||||

547 | EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(top, TOP); | ||||

548 | EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(bottom, BOTTOM); | ||||

549 | | ||||

550 | /* Internal EO APIs and hidden overrides */ | ||||

551 | | ||||

552 | #define EFL_UI_RELATIVE_LAYOUT_EXTRA_OPS \ | ||||

553 | EFL_CANVAS_GROUP_ADD_OPS(efl_ui_relative_layout) | ||||

554 | | ||||

555 | #include "efl_ui_relative_layout.eo.c" |

EFL_PACK_EVENT_LAYOUT_UPDATED event is provided by Efl.Pack interface.

Since Efl.Ui.Relative_Layout does not implement Efl.Pack, it seems that this is not correct.