@@ -753,7 +753,7 @@ void MCControl::layer_changeeffectiverect(const MCRectangle& p_old_effective_rec
753753
754754// //////////////////////////////////////////////////////////////////////////////
755755
756- void MCCard::layer_added (MCControl *p_control, MCObjptr *p_previous, MCObjptr *p_next)
756+ void MCCard::layer_added (MCControl *p_control, MCControl *p_previous, MCControl *p_next)
757757{
758758 MCTileCacheRef t_tilecache;
759759 t_tilecache = getstack () -> view_gettilecache ();
@@ -781,18 +781,22 @@ void MCCard::layer_added(MCControl *p_control, MCObjptr *p_previous, MCObjptr *p
781781 if (p_previous == nil || p_next == nil)
782782 return ;
783783
784+ // skip previous container layers
785+ while (p_previous != nil && p_previous->layer_iscontainer ())
786+ p_previous = MCControlPreviousByLayer (p_previous);
787+
784788 // If the previous (layer below) objptr has no id, then there is nothing to do
785789 // also. This will only occur if only new layers have been added above,
786790 // or if no rendering has been done yet.
787791 uint32_t t_before_layer_id;
788- t_before_layer_id = p_previous -> getref () -> layer_getid ();
792+ t_before_layer_id = p_previous -> layer_getid ();
789793 if (t_before_layer_id == 0 )
790794 return ;
791795
792796 // MW-2013-06-21: [[ Bug 10974 ]] If the previous layer is a sprite then this layer
793797 // will change the lower limit of the scenery layers above, thus there is
794798 // nothing to do.
795- if (p_previous -> getref () -> layer_issprite ())
799+ if (p_previous -> layer_issprite ())
796800 return ;
797801
798802 // Now insert the scenery.
@@ -806,11 +810,12 @@ void MCCard::layer_added(MCControl *p_control, MCObjptr *p_previous, MCObjptr *p
806810 // the layer to be treated 'as one' with that layer until a redraw is done.
807811 // This means that any subsequent updates to the rect of the new layer will
808812 // appropriately flush the tiles in the cache.
809- p_control -> layer_setid (t_before_layer_id);
813+ if (!p_control->layer_iscontainer ())
814+ p_control -> layer_setid (t_before_layer_id);
810815 }
811816}
812817
813- void MCCard::layer_removed (MCControl *p_control, MCObjptr *p_previous, MCObjptr *p_next)
818+ void MCCard::layer_removed (MCControl *p_control, MCControl *p_previous, MCControl *p_next)
814819{
815820 MCTileCacheRef t_tilecache;
816821 t_tilecache = getstack () -> view_gettilecache ();
@@ -852,6 +857,13 @@ void MCCard::layer_removed(MCControl *p_control, MCObjptr *p_previous, MCObjptr
852857 // don't try and reuse a dead scenery layer.
853858 p_control -> layer_resetattrs ();
854859
860+ // skip previous container layers
861+ while (p_previous != nil && p_previous->layer_iscontainer ())
862+ p_previous = MCControlPreviousByLayer (p_previous);
863+
864+ // skip next container layers
865+ while (p_next != nil && p_next->layer_iscontainer ())
866+ p_next = MCControlNextByLayer (p_next);
855867 // If there is no previous or next control we have no tweaks to ids
856868 // to perform.
857869 if (p_previous == nil || p_next == nil)
@@ -862,7 +874,7 @@ void MCCard::layer_removed(MCControl *p_control, MCObjptr *p_previous, MCObjptr
862874 // layer has a different id than us, make sure all previous layers
863875 // with the same id match it.
864876 uint32_t t_before_layer_id;
865- t_before_layer_id = p_previous -> getref () -> layer_getid ();
877+ t_before_layer_id = p_previous -> layer_getid ();
866878
867879 // The layer below us has the same id so there's nothing to do, we are
868880 // removing a 'new' layer before its been redrawn.
@@ -872,20 +884,19 @@ void MCCard::layer_removed(MCControl *p_control, MCObjptr *p_previous, MCObjptr
872884 // MW-2013-06-21: [[ Bug 10974 ]] If the layer below is a sprite, then removing
873885 // this layer will increase the lower limit of the scenery stack above
874886 // thus there is nothing to do.
875- if (p_previous -> getref () -> layer_issprite ())
887+ if (p_previous -> layer_issprite ())
876888 return ;
877889
878890 // The layer below us has a different id, so this is an existing layer
879891 // and thus we must ensure all layers above us now use the id of the
880892 // layer below.
881- MCObjptr *t_objptr;
882- t_objptr = p_next;
883- while (t_objptr != p_previous &&
884- !t_objptr->getref ()->layer_issprite () &&
885- t_objptr -> getref () -> layer_getid () == p_control -> layer_getid ())
893+ while (p_next != nil &&
894+ !p_next->layer_issprite () &&
895+ p_next->layer_getid () == p_control->layer_getid ())
886896 {
887- t_objptr -> getref () -> layer_setid (t_before_layer_id);
888- t_objptr = t_objptr -> next ();
897+ if (!p_next->layer_iscontainer ())
898+ p_next->layer_setid (t_before_layer_id);
899+ p_next = MCControlNextByLayer (p_next);
889900 }
890901 }
891902}
@@ -1471,3 +1482,94 @@ void MCRedrawDoUpdateScreen(void)
14711482
14721483// //////////////////////////////////////////////////////////////////////////////
14731484
1485+ MCControl *MCControlTopChildByLayer (MCControl *p_control)
1486+ {
1487+ if (p_control->gettype () == CT_GROUP)
1488+ {
1489+ MCControl *t_controls = static_cast <MCGroup*>(p_control)->getcontrols ();
1490+
1491+ if (t_controls != nil)
1492+ return MCControlTopChildByLayer (t_controls->prev ());
1493+ }
1494+
1495+ return p_control;
1496+ }
1497+
1498+ MCControl *MCControlPreviousByLayer (MCControl *p_control)
1499+ {
1500+ MCObject *t_parent = nil;
1501+ t_parent = p_control->getparent ();
1502+
1503+ if (t_parent == nil || t_parent->gettype () == CT_STACK)
1504+ return nil;
1505+
1506+ if (t_parent->gettype () == CT_GROUP)
1507+ {
1508+ MCControl *t_controls = static_cast <MCGroup*>(t_parent)->getcontrols ();
1509+
1510+ if (t_controls == p_control)
1511+ return static_cast <MCControl*>(t_parent);
1512+ else
1513+ return MCControlTopChildByLayer (p_control->prev ());
1514+ }
1515+ else if (t_parent->gettype () == CT_CARD)
1516+ {
1517+ MCObjptr *t_object = static_cast <MCCard*>(t_parent)->getobjptrforcontrol (p_control);
1518+ if (t_object == nil)
1519+ return nil; // object not on card
1520+
1521+ // check if first object on card
1522+ if (t_object == static_cast <MCCard*>(t_parent)->getobjptrs ())
1523+ return nil;
1524+
1525+ return MCControlTopChildByLayer (static_cast <MCControl*>(t_object->prev ()->getref ()));
1526+ }
1527+ else
1528+ {
1529+ // control not in group or on card
1530+ return nil;
1531+ }
1532+ }
1533+
1534+ MCControl *MCControlNextByLayer (MCControl *p_control)
1535+ {
1536+ if (p_control->gettype () == CT_GROUP)
1537+ {
1538+ MCControl *t_controls = static_cast <MCGroup*>(p_control)->getcontrols ();
1539+ if (t_controls != nil)
1540+ return t_controls;
1541+ }
1542+
1543+ MCControl *t_child = p_control;
1544+ MCObject *t_parent = t_child->getparent ();
1545+
1546+ while (true )
1547+ {
1548+ if (t_parent == nil || t_parent->gettype () == CT_STACK)
1549+ return nil;
1550+
1551+ if (t_parent->gettype () == CT_GROUP)
1552+ {
1553+ MCControl *t_controls = static_cast <MCGroup*>(t_parent)->getcontrols ();
1554+ if (t_controls->prev () != t_child)
1555+ return t_child->next ();
1556+ }
1557+ else if (t_parent->gettype () == CT_CARD)
1558+ {
1559+ MCObjptr *t_obj = static_cast <MCCard*>(t_parent)->getobjptrforcontrol (t_child);
1560+ if (t_obj == nil)
1561+ return nil; // object no longer on card
1562+
1563+ MCObjptr *t_next = t_obj->next ();
1564+ // check for wrap-around
1565+ if (t_next == static_cast <MCCard*>(t_parent)->getobjptrs ())
1566+ return nil;
1567+ else
1568+ return static_cast <MCControl*>(t_next->getref ());
1569+ }
1570+
1571+ t_child = static_cast <MCControl*>(t_parent);
1572+ t_parent = t_child->getparent ();
1573+ }
1574+ }
1575+
0 commit comments