Skip to content

Commit 6300ef6

Browse files
committed
[[ Engine ]] Add 'layerClipRect' property to controls
This patch adds a new property 'layerClipRect' to all controls. The property defines a clipping rectangle in card co-ordinates which is applied both when the control is rendered normally, and also to the accelerated rendering layer-clip when accelerated rendering is turned on.
1 parent 20d42c0 commit 6300ef6

8 files changed

Lines changed: 123 additions & 1 deletion

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Name: layerClipRect
2+
3+
Type: property
4+
5+
Syntax: set the layerClipRect of <control> to <rectangle>
6+
7+
Summary:
8+
Specifies the visible area of a control
9+
10+
Introduced: 9.5
11+
12+
OS: mac, windows, linux, ios, android
13+
14+
Platforms: desktop, server, mobile
15+
16+
Example:
17+
// restrict visible region of image to a square in the top-left of the card
18+
set the layerClipRect of image "myImage" to 0,0,50,50
19+
20+
Example:
21+
// Hide 10 pixels from the border of image "myImage"
22+
local tRect
23+
put the rect of image "myImage" into tRect
24+
add 10 to item 1 of tRect
25+
add 10 to item 2 of tRect
26+
subtract 10 from item 3 of tRect
27+
subtract 10 from item 4 of tRect
28+
set the layerClipRect of image "myImage" to tRect
29+
30+
Parameters:
31+
<rectangle>:
32+
A rectangle in card coordinates.
33+
34+
Description:
35+
Use the <layerClipRect> property to clip an object's display to a rectangle.
36+
The clipping rectangle only changes what part of the object is rendered,
37+
it has no effect on interaction; in particular, mouse events will still
38+
occur as they would without it being set.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# New layerClipRect control property
2+
3+
A new property 'layerClipRect' has been added to all controls.
4+
5+
Use the layerClipRect property to clip an object's display to a rectangle.
6+
The clipping rectangle only changes what part of the object is rendered,
7+
it has no effect on interaction; in particular, mouse events will still
8+
occur as they would without it being set.

engine/src/control.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ MCPropertyInfo MCControl::kProperties[] =
6464
DEFINE_RW_OBJ_CUSTOM_PROPERTY(P_MARGINS, InterfaceMargins, MCControl, Margins)
6565
DEFINE_RW_OBJ_PROPERTY(P_TOOL_TIP, String, MCControl, ToolTip)
6666
DEFINE_RW_OBJ_PROPERTY(P_UNICODE_TOOL_TIP, BinaryString, MCControl, UnicodeToolTip)
67+
DEFINE_RW_OBJ_PROPERTY(P_LAYER_CLIP_RECT, OptionalRectangle, MCControl, LayerClipRect)
6768
DEFINE_RW_OBJ_NON_EFFECTIVE_ENUM_PROPERTY(P_LAYER_MODE, InterfaceLayerMode, MCControl, LayerMode)
6869
DEFINE_RO_OBJ_EFFECTIVE_ENUM_PROPERTY(P_LAYER_MODE, InterfaceLayerMode, MCControl, LayerMode)
6970

@@ -100,6 +101,8 @@ MCControl::MCControl()
100101
layer_resetattrs();
101102
// MW-2011-09-21: [[ Layers ]] The layer starts off as static.
102103
m_layer_mode_hint = kMCLayerModeHintStatic;
104+
m_layer_has_clip_rect = false;
105+
m_layer_clip_rect = kMCEmptyRectangle;
103106
}
104107

105108
MCControl::MCControl(const MCControl &cref) : MCObject(cref)
@@ -122,6 +125,8 @@ MCControl::MCControl(const MCControl &cref) : MCObject(cref)
122125
layer_resetattrs();
123126
// MW-2011-09-21: [[ Layers ]] The layer takes its layer hint from the source.
124127
m_layer_mode_hint = cref . m_layer_mode_hint;
128+
m_layer_has_clip_rect = cref.m_layer_has_clip_rect;
129+
m_layer_clip_rect = cref.m_layer_clip_rect;
125130
}
126131

127132
MCControl::~MCControl()
@@ -817,6 +822,13 @@ void MCControl::redraw(MCDC *dc, const MCRectangle &dirty)
817822

818823
dc -> setopacity(255);
819824
dc -> setfunction(GXcopy);
825+
826+
/* Apply the layerClipRect property, if set. */
827+
if (m_layer_has_clip_rect)
828+
{
829+
trect = MCU_intersect_rect(trect, m_layer_clip_rect);
830+
}
831+
820832
dc->cliprect(trect);
821833

822834
// MW-2011-09-06: [[ Redraw ] Make sure we draw the control normally (not

engine/src/exec-interface-control.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,50 @@ void MCControl::GetEffectiveLayerMode(MCExecContext& ctxt, intenum_t& r_mode)
337337
r_mode = (intenum_t)layer_geteffectivemode();
338338
}
339339

340+
void MCControl::GetLayerClipRect(MCExecContext& ctxt, MCRectangle*& r_layer_clip_rect)
341+
{
342+
if (m_layer_has_clip_rect)
343+
{
344+
*r_layer_clip_rect = m_layer_clip_rect;
345+
}
346+
else
347+
{
348+
r_layer_clip_rect = nullptr;
349+
}
350+
}
351+
352+
void MCControl::SetLayerClipRect(MCExecContext& ctxt, MCRectangle* p_layer_clip_rect)
353+
{
354+
bool t_old_has_layer_clip_rect = m_layer_has_clip_rect;
355+
MCRectangle t_old_layer_clip_rect = m_layer_clip_rect;
356+
357+
bool t_redraw = false;
358+
if (p_layer_clip_rect != nullptr)
359+
{
360+
m_layer_clip_rect = *p_layer_clip_rect;
361+
m_layer_has_clip_rect = true;
362+
363+
if (!t_old_has_layer_clip_rect ||
364+
MCU_equal_rect(m_layer_clip_rect, t_old_layer_clip_rect))
365+
{
366+
t_redraw = true;
367+
}
368+
}
369+
else
370+
{
371+
m_layer_has_clip_rect = false;
372+
if (t_old_has_layer_clip_rect)
373+
{
374+
t_redraw = true;
375+
}
376+
}
377+
378+
if (t_redraw)
379+
{
380+
Redraw();
381+
}
382+
}
383+
340384
void MCControl::SetMargins(MCExecContext& ctxt, const MCInterfaceMargins& p_margins)
341385
{
342386
if (p_margins . type == kMCInterfaceMarginsTypeSingle)

engine/src/lextable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ const LT factor_table[] =
11141114
{"labelwidth", TT_PROPERTY, P_LABEL_WIDTH},
11151115
{"last", TT_CHUNK, CT_LAST},
11161116
{"layer", TT_PROPERTY, P_LAYER},
1117+
{"layercliprect", TT_PROPERTY, P_LAYER_CLIP_RECT},
11171118
// MW-2011-08-25: [[ TileCache ]] The layerMode property token.
11181119
{"layermode", TT_PROPERTY, P_LAYER_MODE},
11191120
{"layers", TT_CLASS, CT_LAYER},

engine/src/mccontrol.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class MCControl : public MCObject, public MCMixinObjectHandle<MCControl>
6565

6666
// MW-2011-08-24: [[ Layers ]] The layer id of the control.
6767
uint32_t m_layer_id;
68+
MCRectangle m_layer_clip_rect;
6869

6970
// MW-2011-09-21: [[ Layers ]] Whether something about the control has
7071
// changed requiring a recompute the layer attributes.
@@ -90,6 +91,8 @@ class MCControl : public MCObject, public MCMixinObjectHandle<MCControl>
9091
// MW-2011-09-21: [[ Layers ]] Whether the layer is a sprite or scenery
9192
// layer.
9293
bool m_layer_is_sprite : 1;
94+
95+
bool m_layer_has_clip_rect : 1;
9396

9497
static int2 defaultmargin;
9598
static int2 xoffset;
@@ -263,6 +266,12 @@ class MCControl : public MCObject, public MCMixinObjectHandle<MCControl>
263266
// MW-2011-09-21: [[ Layers ]] Returns whether the layer is opaque or not.
264267
bool layer_isopaque(void) { return m_layer_is_opaque; }
265268

269+
bool layer_has_clip_rect(void) { return m_layer_has_clip_rect; }
270+
271+
// Note: The returned value only has meaning if layer_has_clip_rect() returns
272+
// true.
273+
MCRectangle layer_get_clip_rect(void) { return m_layer_clip_rect; }
274+
266275
// MW-2011-09-21: [[ Layers ]] Make sure the layerMode attr's are accurate.
267276
MCLayerModeHint layer_computeattrs(bool commit);
268277
// MW-2011-09-21: [[ Layers ]] Reset the attributes to defaults.
@@ -359,8 +368,10 @@ class MCControl : public MCObject, public MCMixinObjectHandle<MCControl>
359368
void SetToolTip(MCExecContext& ctxt, MCStringRef p_tooltip);
360369
void GetUnicodeToolTip(MCExecContext& ctxt, MCDataRef& r_tooltip);
361370
void SetUnicodeToolTip(MCExecContext& ctxt, MCDataRef p_tooltip);
371+
void GetLayerClipRect(MCExecContext& ctxt, MCRectangle*& r_layer_clip_rect);
372+
void SetLayerClipRect(MCExecContext& ctxt, MCRectangle* p_layer_clip_rect);
362373
void GetLayerMode(MCExecContext& ctxt, intenum_t& r_mode);
363-
void SetLayerMode(MCExecContext& ctxt, intenum_t p_mode);
374+
void SetLayerMode(MCExecContext& ctxt, intenum_t p_mode);
364375
void GetEffectiveLayerMode(MCExecContext& ctxt, intenum_t& r_mode);
365376
virtual void SetMargins(MCExecContext& ctxt, const MCInterfaceMargins& p_margins);
366377
void GetMargins(MCExecContext& ctxt, MCInterfaceMargins& r_margins);

engine/src/parsedef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,8 @@ enum Properties {
17551755

17561756
P_REV_LIBRARY_MAPPING,
17571757

1758+
P_LAYER_CLIP_RECT,
1759+
17581760
__P_LAST,
17591761
};
17601762

engine/src/redraw.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,12 @@ void MCCard::render_control(MCTileCacheRef p_tiler, MCControl *p_control, const
11231123
// IM-2013-10-14: [[ FullscreenMode ]] Constrain each layer to the visible area
11241124
t_layer_clip = MCU_intersect_rect(t_layer_clip, p_visible_rect);
11251125

1126+
/* If the layer has a layerClipRect, then apply it here. */
1127+
if (p_control->layer_has_clip_rect())
1128+
{
1129+
t_layer_clip = MCU_intersect_rect(t_layer_clip, p_control->layer_get_clip_rect());
1130+
}
1131+
11261132
// IM-2013-08-21: [[ ResIndependence ]] Use device coords for tilecache operation
11271133
// IM-2013-09-30: [[ FullscreenMode ]] Use stack transform to get device coords
11281134
t_layer . region = MCRectangle32GetTransformedBounds(t_layer_region, p_transform);

0 commit comments

Comments
 (0)