@@ -182,69 +182,116 @@ void RectToInvalidArea(const LCUI_Rect *rect, LCUI_Rect *area)
182
182
LCUIMetrics_ComputeRectActual (area , & rectf );
183
183
}
184
184
185
- LCUI_BOOL Widget_InvalidateArea (LCUI_Widget widget , LCUI_RectF * in_rect ,
185
+ LCUI_BOOL Widget_InvalidateArea (LCUI_Widget w , LCUI_RectF * in_rect ,
186
186
int box_type )
187
187
{
188
- int mode ;
189
188
LCUI_RectF rect ;
190
- LCUI_Rect * actual_rect ;
191
- LCUI_Widget w = widget ;
192
- LCUI_Widget root = LCUIWidget_GetRoot ();
193
- LCUI_RectGroup group ;
194
189
195
190
if (!w ) {
196
- w = root ;
191
+ w = LCUIWidget_GetRoot ();
192
+ }
193
+ if (!w -> computed_style .visible ||
194
+ w -> invalid_area_type > LCUI_INVALID_AREA_TYPE_CUSTOM ) {
195
+ return FALSE;
197
196
}
198
- mode = LCUIDisplay_GetMode ();
199
197
Widget_AdjustArea (w , in_rect , & rect , box_type );
200
198
rect .x += w -> box .canvas .x ;
201
199
rect .y += w -> box .canvas .y ;
202
- while (w && w -> parent ) {
203
- LCUIRectF_ValidateArea (& rect , w -> parent -> box .padding .width ,
204
- w -> parent -> box .padding .height );
205
- if (rect .width <= 0 || rect .height <= 0 ) {
206
- return FALSE;
207
- }
208
- if (mode != LCUI_DMODE_SEAMLESS && w -> parent == root ) {
209
- break ;
210
- }
211
- w = w -> parent ;
212
- rect .x += w -> box .padding .x ;
213
- rect .y += w -> box .padding .y ;
200
+ if (w -> invalid_area_type == LCUI_INVALID_AREA_TYPE_CUSTOM ) {
201
+ LCUIRectF_MergeRect (& w -> invalid_area , & rect , & w -> invalid_area );
202
+ } else {
203
+ w -> invalid_area = rect ;
214
204
}
215
- LCUIRectF_ValidateArea (& rect , MAX_VISIBLE_WIDTH , MAX_VISIBLE_HEIGHT );
216
- if (rect .width <= 0 || rect .height <= 0 ) {
217
- return FALSE;
205
+ w -> invalid_area_type = LCUI_INVALID_AREA_TYPE_CUSTOM ;
206
+ while (w -> parent ) {
207
+ w -> parent -> has_child_invalid_area = TRUE;
208
+ w = w -> parent ;
218
209
}
219
- actual_rect = malloc (sizeof (LCUI_Rect ));
220
- RectFToInvalidArea (& rect , actual_rect );
221
- if (mode != LCUI_DMODE_SEAMLESS ) {
222
- LinkedList_Append (& self .rects , actual_rect );
223
- return TRUE;
210
+ return TRUE;
211
+ }
212
+
213
+ #define AddInvalidArea () \
214
+ do { \
215
+ rect.x += x; \
216
+ rect.y += y; \
217
+ LCUIRectF_GetOverlayRect(&rect, &visible_area, &rect); \
218
+ if (rect.width > 0 && rect.height > 0) { \
219
+ actual_rect = malloc(sizeof(LCUI_Rect)); \
220
+ RectFToInvalidArea(&rect, actual_rect); \
221
+ LinkedList_Append(rects, actual_rect); \
222
+ } \
223
+ } while (0)
224
+
225
+ static void Widget_CollectInvalidArea (LCUI_Widget w , LinkedList * rects , float x ,
226
+ float y , LCUI_RectF visible_area )
227
+ {
228
+ LCUI_RectF rect ;
229
+ LCUI_Rect * actual_rect ;
230
+ LinkedListNode * node ;
231
+
232
+ if (w -> parent && w -> parent -> invalid_area_type >=
233
+ LCUI_INVALID_AREA_TYPE_PADDING_BOX ) {
234
+ w -> invalid_area_type = LCUI_INVALID_AREA_TYPE_CANVAS_BOX ;
235
+ } else if (w -> invalid_area_type >= LCUI_INVALID_AREA_TYPE_PADDING_BOX ) {
236
+ switch (w -> invalid_area_type ) {
237
+ case LCUI_INVALID_AREA_TYPE_PADDING_BOX :
238
+ rect = w -> box .padding ;
239
+ break ;
240
+ case LCUI_INVALID_AREA_TYPE_BORDER_BOX :
241
+ rect = w -> box .border ;
242
+ break ;
243
+ default :
244
+ rect = w -> box .canvas ;
245
+ break ;
246
+ }
247
+ if (!LCUIRectF_IsCoverRect (& rect , & w -> invalid_area )) {
248
+ AddInvalidArea ();
249
+ rect = w -> invalid_area ;
250
+ AddInvalidArea ();
251
+ } else {
252
+ LCUIRectF_MergeRect (& rect , & rect , & w -> invalid_area );
253
+ AddInvalidArea ();
254
+ }
255
+ } else if (w -> invalid_area_type == LCUI_INVALID_AREA_TYPE_CUSTOM ) {
256
+ rect = w -> invalid_area ;
257
+ AddInvalidArea ();
224
258
}
225
- group = RBTree_CustomGetData (& self .groups , w );
226
- if (!group ) {
227
- group = NEW (LCUI_RectGroupRec , 1 );
228
- group -> widget = w ;
229
- LinkedList_Init (& group -> rects );
230
- RBTree_CustomInsert (& self .groups , w , group );
259
+ if (w -> has_child_invalid_area ) {
260
+ visible_area .x -= x ;
261
+ visible_area .y -= y ;
262
+ LCUIRectF_GetOverlayRect (& visible_area , & w -> box .padding ,
263
+ & visible_area );
264
+ visible_area .x += x ;
265
+ visible_area .y += y ;
266
+ for (LinkedList_Each (node , & w -> children_show )) {
267
+ Widget_CollectInvalidArea (
268
+ node -> data , rects , x + w -> box .padding .x ,
269
+ y + w -> box .padding .y , visible_area );
270
+ }
231
271
}
232
- return LinkedList_Append (& group -> rects , actual_rect ) == 0 ;
272
+ w -> invalid_area_type = LCUI_INVALID_AREA_TYPE_NONE ;
273
+ w -> has_child_invalid_area = FALSE;
233
274
}
234
275
235
276
size_t Widget_GetInvalidArea (LCUI_Widget w , LinkedList * rects )
236
277
{
237
- LCUI_RectGroup group ;
278
+ LCUI_Rect * rect ;
279
+ LinkedListNode * node ;
238
280
239
- if (!w || w == LCUIWidget_GetRoot ()) {
240
- LinkedList_Concat (rects , & self .rects );
241
- return (size_t )rects -> length ;
242
- }
243
- group = RBTree_CustomGetData (& self .groups , w );
244
- if (group ) {
245
- LinkedList_Concat (rects , & group -> rects );
281
+ float scale = LCUIMetrics_GetScale ();
282
+ int x = iround (w -> box .padding .x * scale );
283
+ int y = iround (w -> box .padding .y * scale );
284
+
285
+ Widget_CollectInvalidArea (w , rects , 0 , 0 , w -> box .padding );
286
+ DEBUG_MSG ("rects: %lu\n" , rects -> length );
287
+ for (LinkedList_Each (node , rects )) {
288
+ rect = node -> data ;
289
+ rect -> x -= x ;
290
+ rect -> y -= y ;
291
+ _DEBUG_MSG ("(%d, %d, %d, %d)\n" , rect -> x , rect -> y , rect -> width ,
292
+ rect -> height );
246
293
}
247
- return ( size_t ) rects -> length ;
294
+ return rects -> length ;
248
295
}
249
296
250
297
static int OnCompareGroup (void * data , const void * keydata )
0 commit comments