diff --git a/docs/notes/bugfix-16568.md b/docs/notes/bugfix-16568.md new file mode 100644 index 00000000000..5242e9a758a --- /dev/null +++ b/docs/notes/bugfix-16568.md @@ -0,0 +1 @@ +# Browser widget visibility not updated correctly when in a group \ No newline at end of file diff --git a/engine/src/button.cpp b/engine/src/button.cpp index b67f824ef8c..4f098605f2b 100755 --- a/engine/src/button.cpp +++ b/engine/src/button.cpp @@ -1673,7 +1673,7 @@ uint2 MCButton::gettransient() const } -void MCButton::setrect(const MCRectangle &nrect) +void MCButton::applyrect(const MCRectangle &nrect) { rect = nrect; MCRectangle trect; diff --git a/engine/src/button.h b/engine/src/button.h index 93a0620bb04..594c25f35e4 100644 --- a/engine/src/button.h +++ b/engine/src/button.h @@ -190,7 +190,7 @@ class MCButton : public MCControl #endif virtual uint2 gettransient() const; - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEC virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); diff --git a/engine/src/eps.cpp b/engine/src/eps.cpp index b11de2300c3..a4887ad2c94 100644 --- a/engine/src/eps.cpp +++ b/engine/src/eps.cpp @@ -181,7 +181,7 @@ Boolean MCEPS::mup(uint2 which, bool p_release) return True; } -void MCEPS::setrect(const MCRectangle &nrect) +void MCEPS::applyrect(const MCRectangle &nrect) { if (rect.width != nrect.width || rect.height != nrect.height) { diff --git a/engine/src/eps.h b/engine/src/eps.h index 5ae5d285d59..08ca6846ad5 100644 --- a/engine/src/eps.h +++ b/engine/src/eps.h @@ -50,7 +50,7 @@ class MCEPS : public MCControl virtual const char *gettypestring(); virtual Boolean mdown(uint2 which); virtual Boolean mup(uint2 which, bool p_release); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEC virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); diff --git a/engine/src/exec-interface-group.cpp b/engine/src/exec-interface-group.cpp index 71bc6260284..0b12e33ba84 100644 --- a/engine/src/exec-interface-group.cpp +++ b/engine/src/exec-interface-group.cpp @@ -801,12 +801,21 @@ void MCGroup::GetClipsToRect(MCExecContext& ctxt, bool& r_clips_to_rect) r_clips_to_rect = m_clips_to_rect; } -void MCGroup::SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) +// PM-2015-07-02: [[ Bug 13262 ]] Make sure we attach/detach the player when +// showing/hiding a group that has a player +void MCGroup::SetVisible(MCExecContext &ctxt, uinteger_t part, bool setting) { - SetVisibility(ctxt, part, setting, true); -} - -void MCGroup::SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, false); + MCControl::SetVisible(ctxt, part, setting); +#ifdef PLATFORM_PLAYER + for(MCPlayer *t_player = MCplayers; t_player != nil; t_player = t_player -> getnextplayer()) + { + if (t_player -> getparent() == this) + { + if (setting) + t_player -> attachplayer(); + else + t_player -> detachplayer(); + } + } +#endif } diff --git a/engine/src/exec-interface-image.cpp b/engine/src/exec-interface-image.cpp index 0c0fa1bfd73..be8c709840a 100644 --- a/engine/src/exec-interface-image.cpp +++ b/engine/src/exec-interface-image.cpp @@ -739,10 +739,10 @@ void MCImage::SetInk(MCExecContext& ctxt, intenum_t ink) notifyneeds(false); } -void MCImage::SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible) +void MCImage::SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) { - Boolean wasvisible = isvisible(); - MCObject::SetVisibility(ctxt, part, setting, visible); + bool wasvisible = isvisible(); + MCObject::SetVisible(ctxt, part, setting); if (!(MCbufferimages || flags & F_I_ALWAYS_BUFFER) && !isvisible() && m_rep != nil) closeimage(); @@ -762,16 +762,6 @@ void MCImage::SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, } } -void MCImage::SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, true); -} - -void MCImage::SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, false); -} - // MERG-2015-02-11: [[ ImageMetadata ]] Refactored image metadata property void MCImage::GetMetadataProperty(MCExecContext& ctxt, MCNameRef p_prop, MCExecValue& r_value) { diff --git a/engine/src/exec-interface-object.cpp b/engine/src/exec-interface-object.cpp index b8bec3efc04..3e3e0bd9100 100644 --- a/engine/src/exec-interface-object.cpp +++ b/engine/src/exec-interface-object.cpp @@ -3151,17 +3151,11 @@ void MCObject::Set3D(MCExecContext& ctxt, bool setting) //////////////////////////////////////////////////////////////////////////////// -void MCObject::SetVisibility(MCExecContext& ctxt, uint32_t part, bool setting, bool visible) +void MCObject::SetVisible(MCExecContext& ctxt, uint32_t part, bool setting) { bool dirty; dirty = changeflag(setting, F_VISIBLE); - if (!visible) - { - flags ^= F_VISIBLE; - dirty = !dirty; - } - // MW-2011-10-17: [[ Bug 9813 ]] Record the current effective rect of the object. MCRectangle t_old_effective_rect; if (dirty && opened && gettype() >= CT_GROUP) @@ -3188,42 +3182,27 @@ void MCObject::SetVisibility(MCExecContext& ctxt, uint32_t part, bool setting, b void MCObject::GetVisible(MCExecContext& ctxt, uint32_t part, bool& r_setting) { - r_setting = getflag(F_VISIBLE); -} - -void MCObject::SetVisible(MCExecContext& ctxt, uint32_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, true); + r_setting = isvisible(false); } void MCObject::GetEffectiveVisible(MCExecContext& ctxt, uint32_t part, bool& r_setting) { - bool t_vis; - t_vis = getflag(F_VISIBLE); - - // if visible and effective and parent is a - // group then keep searching parent properties - if (t_vis && parent != NULL && parent->gettype() == CT_GROUP) - parent->GetEffectiveVisible(ctxt, part, t_vis); - - r_setting = t_vis; + r_setting = isvisible(true); } void MCObject::GetInvisible(MCExecContext& ctxt, uint32_t part, bool& r_setting) { - r_setting = (flags & F_VISIBLE) == False; + r_setting = !isvisible(false); } void MCObject::SetInvisible(MCExecContext& ctxt, uint32_t part, bool setting) { - SetVisibility(ctxt, part, setting, false); + SetVisible(ctxt, part, !setting); } void MCObject::GetEffectiveInvisible(MCExecContext& ctxt, uint32_t part, bool& r_setting) { - bool t_setting; - GetEffectiveVisible(ctxt, part, t_setting); - r_setting = !t_setting; + r_setting = !isvisible(true); } void MCObject::GetEnabled(MCExecContext& ctxt, uint32_t part, bool& r_setting) diff --git a/engine/src/exec-interface-player.cpp b/engine/src/exec-interface-player.cpp index 90739a5ca64..c31693929c7 100644 --- a/engine/src/exec-interface-player.cpp +++ b/engine/src/exec-interface-player.cpp @@ -697,10 +697,10 @@ void MCPlayer::SetBorderWidth(MCExecContext& ctxt, uinteger_t width) Redraw(); } -void MCPlayer::SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible) +void MCPlayer::SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) { uint4 oldflags = flags; - MCObject::SetVisibility(ctxt, part, setting, visible); + MCControl::SetVisible(ctxt, part, setting); // PM-2015-07-01: [[ Bug 15191 ]] Keep the LC 6.7 behaviour in non-platform player, to make the video layer to hide #ifndef FEATURE_PLATFORM_PLAYER @@ -713,16 +713,6 @@ void MCPlayer::SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, updatevisibility(); } -void MCPlayer::SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, true); -} - -void MCPlayer::SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting) -{ - SetVisibility(ctxt, part, setting, false); -} - void MCPlayer::SetTraversalOn(MCExecContext& ctxt, bool setting) { MCObject::SetTraversalOn(ctxt, setting); diff --git a/engine/src/field.cpp b/engine/src/field.cpp index 79a412f6c59..6e532a179fa 100644 --- a/engine/src/field.cpp +++ b/engine/src/field.cpp @@ -1399,7 +1399,7 @@ uint2 MCField::gettransient() const return 0; } -void MCField::setrect(const MCRectangle &nrect) +void MCField::applyrect(const MCRectangle &nrect) { // The contents only need to be laid out if the size changes. In particular, // it is the width that is important; the height does not affect layout. diff --git a/engine/src/field.h b/engine/src/field.h index 14b8768b3b4..def25ed0712 100644 --- a/engine/src/field.h +++ b/engine/src/field.h @@ -282,7 +282,7 @@ class MCField : public MCControl virtual void timer(MCNameRef mptr, MCParameter *params); virtual void select(); virtual uint2 gettransient() const; - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEc virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); diff --git a/engine/src/graphic.cpp b/engine/src/graphic.cpp index 590b1ff568c..5beff97d5fa 100644 --- a/engine/src/graphic.cpp +++ b/engine/src/graphic.cpp @@ -426,7 +426,7 @@ Boolean MCGraphic::doubleup(uint2 which) return MCControl::doubleup(which); } -void MCGraphic::setrect(const MCRectangle &nrect) +void MCGraphic::applyrect(const MCRectangle &nrect) { if (realpoints != NULL) { diff --git a/engine/src/graphic.h b/engine/src/graphic.h index 511b2e3f447..8dbae82b048 100644 --- a/engine/src/graphic.h +++ b/engine/src/graphic.h @@ -90,7 +90,7 @@ class MCGraphic : public MCControl virtual Boolean mup(uint2 which, bool p_release); virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); // MW-2011-11-23: [[ Array Chunk Props ]] Add 'effective' param to arrayprop access. #ifdef LEGACY_EXEC diff --git a/engine/src/group.cpp b/engine/src/group.cpp index 57ea0c27f4a..a139704fadb 100644 --- a/engine/src/group.cpp +++ b/engine/src/group.cpp @@ -264,6 +264,58 @@ bool MCGroup::visit_children(MCObjectVisitorOptions p_options, uint32_t p_part, return t_continue; } +void MCGroup::toolchanged(Tool p_new_tool) +{ + MCControl::toolchanged(p_new_tool); + if (controls != nil) + { + MCControl *t_ctrl; + t_ctrl = controls; + do + { + t_ctrl->toolchanged(p_new_tool); + t_ctrl = t_ctrl->next(); + } + while (t_ctrl != controls); + } +} + +MCRectangle MCGroup::getviewportgeometry() +{ + MCRectangle t_viewport; + t_viewport = getrect(); + + MCObject *t_parent; + t_parent = getparent(); + if (t_parent != nil && t_parent->gettype() == CT_GROUP) + t_viewport = MCU_intersect_rect(t_viewport, ((MCGroup*)t_parent)->getviewportgeometry()); + + return t_viewport; +} + +void MCGroup::geometrychanged(const MCRectangle &p_rect) +{ + MCControl::geometrychanged(p_rect); + viewportgeometrychanged(getviewportgeometry()); +} + +void MCGroup::viewportgeometrychanged(const MCRectangle &p_rect) +{ + MCRectangle t_viewport; + t_viewport = MCU_intersect_rect(p_rect, getrect()); + + if (controls != nil) + { + MCControl *t_control = controls; + do + { + t_control->viewportgeometrychanged(t_viewport); + t_control = t_control->next(); + } + while (t_control != controls); + } +} + void MCGroup::open() { MCControl::open(); @@ -796,7 +848,7 @@ Boolean MCGroup::doubleup(uint2 which) return False; } -void MCGroup::setrect(const MCRectangle &nrect) +void MCGroup::applyrect(const MCRectangle &nrect) { bool t_size_changed; t_size_changed = nrect . width != rect . width || nrect . height != rect . height; @@ -2747,6 +2799,10 @@ bool MCGroup::computeminrect(Boolean scrolling) else t_all = true; state = oldstate; + + // IM-2015-12-16: [[ NativeLayer ]] The group rect has changed, so send geometry change notification. + geometrychanged(getrect()); + return t_all; } else if ((flags & F_HSCROLLBAR || flags & F_VSCROLLBAR) @@ -3695,6 +3751,25 @@ void MCGroup::relayercontrol_insert(MCControl *p_control, MCControl *p_target) p_control -> layer_redrawall(); } +bool MCGroup::getNativeContainerLayer(MCNativeLayer *&r_layer) +{ + if (getNativeLayer() == nil) + { + void *t_view; + if (!MCNativeLayer::CreateNativeContainer(t_view)) + return false; + if (!SetNativeView(t_view)) + { + MCNativeLayer::ReleaseNativeView(t_view); + return false; + } + } + + r_layer = getNativeLayer(); + + return true; +} + void MCGroup::scheduledelete(bool p_is_child) { MCControl::scheduledelete(p_is_child); @@ -3710,22 +3785,3 @@ void MCGroup::scheduledelete(bool p_is_child) while(t_control != controls); } } - -// PM-2015-07-02: [[ Bug 13262 ]] Make sure we attach/detach the player when -// showing/hiding a group that has a player -void MCGroup::SetVisibility(MCExecContext &ctxt, uinteger_t part, bool flag, bool visible) -{ - MCControl::SetVisibility(ctxt, part, flag, visible); -#ifdef PLATFORM_PLAYER - for(MCPlayer *t_player = MCplayers; t_player != nil; t_player = t_player -> getnextplayer()) - { - if (t_player -> getparent() == this) - { - if (flag && visible || !flag && !visible) - t_player -> attachplayer(); - else - t_player -> detachplayer(); - } - } -#endif -} diff --git a/engine/src/group.h b/engine/src/group.h index c922ae0818a..6893ec0e269 100644 --- a/engine/src/group.h +++ b/engine/src/group.h @@ -81,7 +81,7 @@ class MCGroup : public MCControl virtual Boolean mup(uint2 which, bool p_release); virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEC virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); @@ -129,6 +129,16 @@ class MCGroup : public MCControl virtual void relayercontrol_remove(MCControl *control); virtual void relayercontrol_insert(MCControl *control, MCControl *target); + virtual void toolchanged(Tool p_new_tool); + + virtual void geometrychanged(const MCRectangle &p_rect); + + virtual void viewportgeometrychanged(const MCRectangle &p_rect); + + virtual MCRectangle getviewportgeometry(); + + bool getNativeContainerLayer(MCNativeLayer *&r_layer); + virtual void scheduledelete(bool p_is_child); MCControl *findchildwithid(Chunk_term type, uint4 p_id); @@ -302,9 +312,7 @@ class MCGroup : public MCControl void SetClipsToRect(MCExecContext& ctxt, bool p_clips_to_rect); void GetClipsToRect(MCExecContext& ctxt, bool &r_clips_to_rect); - void SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting); void SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting); - void SetVisibility(MCExecContext& ctxt, uinteger_t part, bool flag, bool visible); virtual void SetEnabled(MCExecContext& ctxt, uint32_t part, bool setting); virtual void SetDisabled(MCExecContext& ctxt, uint32_t part, bool setting); diff --git a/engine/src/image.cpp b/engine/src/image.cpp index 9a5fd88ba9f..f0b1fe8c1d2 100644 --- a/engine/src/image.cpp +++ b/engine/src/image.cpp @@ -603,7 +603,7 @@ void MCImage::timer(MCNameRef mptr, MCParameter *params) MCControl::timer(mptr, params); } -void MCImage::setrect(const MCRectangle &nrect) +void MCImage::applyrect(const MCRectangle &nrect) { MCRectangle orect = rect; rect = nrect; diff --git a/engine/src/image.h b/engine/src/image.h index 15ae567fd35..0dbdff947cf 100644 --- a/engine/src/image.h +++ b/engine/src/image.h @@ -406,7 +406,7 @@ class MCImage : public MCControl virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); virtual void timer(MCNameRef mptr, MCParameter *params); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEC virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); @@ -627,7 +627,6 @@ class MCImage : public MCControl void GetTransparencyData(MCExecContext &ctxt, bool p_flatten, MCDataRef &r_data); void SetTransparencyData(MCExecContext &ctxt, bool p_flatten, MCDataRef p_data); - void SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible); ////////// PROPERTY ACCESSORS @@ -682,7 +681,6 @@ class MCImage : public MCControl virtual void SetBlendLevel(MCExecContext& ctxt, uinteger_t level); virtual void SetInk(MCExecContext& ctxt, intenum_t ink); virtual void SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting); - virtual void SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting); }; extern bool MCU_israwimageformat(Export_format p_format); diff --git a/engine/src/java/com/runrev/android/Engine.java b/engine/src/java/com/runrev/android/Engine.java index f81b07deb10..9d1f7cff680 100644 --- a/engine/src/java/com/runrev/android/Engine.java +++ b/engine/src/java/com/runrev/android/Engine.java @@ -115,7 +115,7 @@ public class Engine extends View implements EngineApi private NativeControlModule m_native_control_module; private SoundModule m_sound_module; private NotificationModule m_notification_module; - private FrameLayout m_view_layout; + private RelativeLayout m_view_layout; private PowerManager.WakeLock m_wake_lock; @@ -941,7 +941,70 @@ public String getAssetFolderEntryList(String p_path) //////////////////////////////////////////////////////////////////////////////// + // Native layer view functionality + + Object getNativeLayerContainer() + { + if (m_view_layout == null) + { + FrameLayout t_main_view; + t_main_view = ((LiveCodeActivity)getContext()).s_main_layout; + + m_view_layout = new RelativeLayout(getContext()); + t_main_view.addView(m_view_layout, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); + t_main_view.bringChildToFront(m_view_layout); + } + + return m_view_layout; + } + + Object createNativeLayerContainer() + { + return new RelativeLayout(getContext()); + } + + // insert the view into the container, layered below p_view_above if not null. + void addNativeViewToContainer(Object p_view, Object p_view_above, Object p_container) + { + ViewGroup t_container; + t_container = (ViewGroup)p_container; + + int t_index; + if (p_view_above != null) + t_index = t_container.indexOfChild((View)p_view_above); + else + t_index = t_container.getChildCount(); + + t_container.addView((View)p_view, t_index, new RelativeLayout.LayoutParams(0, 0)); + } + + void removeNativeViewFromContainer(Object p_view) + { + // Remove view from its parent + View t_view; + t_view = (View)p_view; + + ViewGroup t_parent; + t_parent = (ViewGroup)t_view.getParent(); + if (t_parent != null) + t_parent.removeView(t_view); + } + + void setNativeViewRect(Object p_view, int left, int top, int width, int height) + { + RelativeLayout.LayoutParams t_layout = new RelativeLayout.LayoutParams(width, height); + t_layout.leftMargin = left; + t_layout.topMargin = top; + t_layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT); + t_layout.addRule(RelativeLayout.ALIGN_PARENT_TOP); + + View t_view = (View)p_view; + + t_view.setLayoutParams(t_layout); + } + // native control functionality + void addNativeControl(Object p_control) { m_native_control_module.addControl(p_control); @@ -952,53 +1015,6 @@ void removeNativeControl(Object p_control) m_native_control_module.removeControl(p_control); } - void removeNativeView(Object p_view) - { - View t_view = (View)p_view; - - if (m_view_layout != null) - m_view_layout.removeView(t_view); - } - - void placeNativeViewBelow(Object p_view, Object p_superior) - { - // Remove from any existing parent - removeNativeView(p_view); - - // The main view - FrameLayout t_main_view = ((LiveCodeActivity)getContext()).s_main_layout; - - // Create the layout for native layers if not already done - if (m_view_layout == null) - { - m_view_layout = new FrameLayout((LiveCodeActivity)getContext()); - t_main_view.addView(m_view_layout); - t_main_view.bringChildToFront(m_view_layout); - } - - View t_view = (View)p_view; - int t_index = m_view_layout.getChildCount(); - - if (p_superior != null) - { - View t_superior = (View)p_superior; - t_index = m_view_layout.indexOfChild(t_superior); - } - - m_view_layout.addView(t_view, t_index, new RelativeLayout.LayoutParams(0, 0)); - } - - void setNativeViewRect(Object p_view, int left, int top, int width, int height) - { - FrameLayout.LayoutParams t_layout = new FrameLayout.LayoutParams(width, height); - t_layout.leftMargin = left; - t_layout.topMargin = top; - - View t_view = (View)p_view; - - t_view.setLayoutParams(t_layout); - } - Object createNativeControl(String p_class_name) { return m_native_control_module.createControl(p_class_name); diff --git a/engine/src/native-layer-android.cpp b/engine/src/native-layer-android.cpp index 098b9411b76..b3883a33441 100644 --- a/engine/src/native-layer-android.cpp +++ b/engine/src/native-layer-android.cpp @@ -44,6 +44,8 @@ #include "globals.h" #include "context.h" +#include "group.h" + #include #include "mblandroidutil.h" @@ -53,101 +55,68 @@ #include "native-layer-android.h" -class MCNativeLayerAndroid::AndroidView -{ -public: - - // Constructor. The Java object being wrapped must be supplied. - AndroidView(jobject p_java_object); - - ~AndroidView(); - - void setRect(const MCRectangle& p_rect); - void placeViewBelow(AndroidView* p_other_view); - void removeFromMainView(); - - jobject getView(); - -private: - - // The Java object that is the view - jobject m_java_object; - - // Whether the object is currently in the view or not - bool m_in_view; -}; - //////////////////////////////////////////////////////////////////////////////// -MCNativeLayerAndroid::AndroidView::AndroidView(jobject p_java_object) : - m_java_object(MCJavaGetThreadEnv()->NewGlobalRef(p_java_object)), - m_in_view(false) +void MCAndroidViewSetRect(jobject p_view, const MCGRectangle &p_rect) { - ; -} + int16_t x, y, w, h; + x = (int16_t) roundf(p_rect . origin . x); + y = (int16_t) roundf(p_rect . origin . y); + w = (int16_t) roundf(p_rect . size . width); + h = (int16_t) roundf(p_rect . size . height); -MCNativeLayerAndroid::AndroidView::~AndroidView() -{ - MCJavaGetThreadEnv()->DeleteGlobalRef(m_java_object); + MCAndroidEngineRemoteCall("setNativeViewRect", "voiiii", nil, p_view, x, y, w, h); } -jobject MCNativeLayerAndroid::AndroidView::getView() +void MCAndroidViewSetRect(jobject p_view, const MCRectangle& p_rect) { - return m_java_object; + // MM-2013-11-26: [[ Bug 11485 ]] The rect of the control is passed in user space. Convert to device space when setting on view. + MCAndroidViewSetRect(p_view, MCNativeControlUserRectToDeviceRect(MCRectangleToMCGRectangle(p_rect))); } -void MCNativeLayerAndroid::AndroidView::setRect(const MCRectangle& p_rect) +void MCAndroidViewSetRect(jobject p_view, const MCRectangle &p_rect, const MCRectangle &p_parent_rect) { - int16_t i1, i2, i3, i4; - - // MM-2013-11-26: [[ Bug 11485 ]] The rect of the control is passed in user space. Convert to device space when setting on view. - // AL-2014-06-16: [[ Bug 12588 ]] Actually use the passed in rect parameter - MCGRectangle t_rect; - t_rect = MCNativeControlUserRectToDeviceRect(MCRectangleToMCGRectangle(p_rect)); - i1 = (int16_t) roundf(t_rect . origin . x); - i2 = (int16_t) roundf(t_rect . origin . y); - i3 = (int16_t) roundf(t_rect . size . width); - i4 = (int16_t) roundf(t_rect . size . height); - - MCAndroidEngineRemoteCall("setNativeViewRect", "voiiii", nil, m_java_object, i1, i2, i3, i4); + MCGRectangle t_rect = MCNativeControlUserRectToDeviceRect(MCRectangleToMCGRectangle(p_rect)); + MCGRectangle t_parent_rect = MCNativeControlUserRectToDeviceRect(MCRectangleToMCGRectangle(p_parent_rect)); + + t_rect.origin.x -= t_parent_rect.origin.x; + t_rect.origin.y -= t_parent_rect.origin.y; + + MCAndroidViewSetRect(p_view, t_rect); } -void MCNativeLayerAndroid::AndroidView::placeViewBelow(AndroidView* p_other_view) +void MCAndroidViewAddToContainer(jobject p_view, jobject p_view_above, jobject p_container) { - MCAndroidEngineRemoteCall("placeNativeViewBelow", "voo", nil, m_java_object, p_other_view ? p_other_view->m_java_object : NULL); - m_in_view = true; - MCAndroidObjectRemoteCall(m_java_object, "setVisibility", "vi", nil, 0); + MCAndroidEngineRemoteCall("addNativeViewToContainer", "vooo", nil, p_view, p_view_above, p_container); + MCAndroidObjectRemoteCall(p_view, "setVisibility", "vi", nil, 0); } -void MCNativeLayerAndroid::AndroidView::removeFromMainView() +void MCAndroidViewRemoveFromContainer(jobject p_view) { - if (m_in_view) - MCAndroidEngineRemoteCall("removeNativeView", "vo", nil, m_java_object); - m_in_view = false; + MCAndroidEngineRemoteCall("removeNativeViewFromContainer", "vo", nil, p_view); } //////////////////////////////////////////////////////////////////////////////// -MCNativeLayerAndroid::MCNativeLayerAndroid(MCWidgetRef p_widget, jobject p_view) : +MCNativeLayerAndroid::MCNativeLayerAndroid(MCObject *p_object, jobject p_view) : m_view(NULL) { - m_widget = p_widget; - m_view = new AndroidView(p_view); + m_object = p_object; + m_view = MCJavaGetThreadEnv()->NewGlobalRef(p_view); } MCNativeLayerAndroid::~MCNativeLayerAndroid() { - delete m_view; + if (m_view != nil) + MCJavaGetThreadEnv()->DeleteGlobalRef(m_view); } void MCNativeLayerAndroid::doAttach() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - if (m_view == nil) return; - OnVisibilityChanged(ShouldShowWidget(t_widget)); + doSetVisible(ShouldShowLayer()); } void MCNativeLayerAndroid::doDetach() @@ -156,7 +125,7 @@ void MCNativeLayerAndroid::doDetach() return; // Remove the view from the stack's content view - m_view->removeFromMainView(); + MCAndroidViewRemoveFromContainer(m_view); } // Rendering view to context not supported on Android. @@ -170,12 +139,22 @@ bool MCNativeLayerAndroid::doPaint(MCGContextRef p_context) return false; } +void MCNativeLayerAndroid::doSetViewportGeometry(const MCRectangle& p_rect) +{ +} + void MCNativeLayerAndroid::doSetGeometry(const MCRectangle &p_rect) { if (m_view == NULL) return; - - m_view->setRect(p_rect); + + if (m_object->getparent()->gettype() == CT_GROUP) + { + // Set rectangle relative to parent object + MCAndroidViewSetRect(m_view, p_rect, m_object->getparent()->getrect()); + } + else + MCAndroidViewSetRect(m_view, p_rect); } void MCNativeLayerAndroid::doSetVisible(bool p_visible) @@ -186,38 +165,65 @@ void MCNativeLayerAndroid::doSetVisible(bool p_visible) if (p_visible) { addToMainView(); - doSetGeometry(MCWidgetGetHost(m_widget)->getrect()); + doSetGeometry(m_object->getrect()); } else - m_view->removeFromMainView(); + MCAndroidViewRemoveFromContainer(m_view); } void MCNativeLayerAndroid::doRelayer() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - - if (m_view == NULL) - return; - // Find which native layer this should be inserted below - MCWidget* t_before; - t_before = findNextLayerAbove(t_widget); - + MCObject *t_before; + t_before = findNextLayerAbove(m_object); + + jobject t_parent_view; + t_parent_view = nil; + + if (!getParentView(t_parent_view)) + return; + // Insert the widget in the correct place (but only if the card is current) - if (isAttached() && t_widget->getstack()->getcard() == t_widget->getstack()->getcurcard()) + if (isAttached() && m_object->getstack()->getcard() == m_object->getstack()->getcurcard()) { + MCAndroidViewRemoveFromContainer(m_view); + + jobject t_before_view; + t_before_view = nil; + if (t_before != NULL) - { - MCNativeLayerAndroid* t_android_layer; - t_android_layer = reinterpret_cast(t_before->getNativeLayer()); - m_view->placeViewBelow(t_android_layer->m_view); - } - else - m_view->placeViewBelow(NULL); - m_view->setRect(t_widget->getrect()); + /* UNCHECKED */t_before->GetNativeView((void*&)t_before_view); + + MCAndroidViewAddToContainer(m_view, t_before_view, t_parent_view); + doSetGeometry(m_object->getrect()); } } +bool MCNativeLayerAndroid::getParentView(jobject &r_view) +{ + if (m_object->getparent()->gettype() == CT_GROUP) + { + MCNativeLayer *t_container; + t_container = nil; + + if (!((MCGroup*)m_object->getparent())->getNativeContainerLayer(t_container)) + return false; + + return t_container->GetNativeView((void*&)r_view); + } + else + { + jobject t_view; + t_view = nil; + MCAndroidEngineRemoteCall("getNativeLayerContainer", "o", &t_view); + if (t_view == nil) + return false; + + r_view = t_view; + return true; + } +} + void MCNativeLayerAndroid::addToMainView() { doRelayer(); @@ -228,14 +234,36 @@ bool MCNativeLayerAndroid::GetNativeView(void *&r_view) if (m_view == nil) return false; - r_view = m_view->getView(); + r_view = m_view; return true; } //////////////////////////////////////////////////////////////////////////////// -MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_view) +MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_view) { - return new MCNativeLayerAndroid(p_widget, (jobject)p_view); + return new MCNativeLayerAndroid(p_object, (jobject)p_view); } + +bool MCNativeLayer::CreateNativeContainer(void *&r_view) +{ + jobject t_view; + t_view = nil; + + MCAndroidEngineRemoteCall("createNativeLayerContainer", "o", &t_view); + + if (t_view == nil) + return false; + + r_view = MCJavaGetThreadEnv()->NewGlobalRef(t_view); + return true; +} + +void MCNativeLayer::ReleaseNativeView(void *p_view) +{ + if (p_view != nil) + MCJavaGetThreadEnv()->DeleteGlobalRef((jobject)p_view); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer-android.h b/engine/src/native-layer-android.h index 910ec60b824..ec827c5a738 100644 --- a/engine/src/native-layer-android.h +++ b/engine/src/native-layer-android.h @@ -26,17 +26,14 @@ class MCNativeLayerAndroid : public MCNativeLayer virtual bool GetCanRenderToContext(); - MCNativeLayerAndroid(MCWidgetRef p_widget, jobject p_view); + MCNativeLayerAndroid(MCObject *p_object, jobject p_view); ~MCNativeLayerAndroid(); virtual bool GetNativeView(void *&r_view); private: - // Wrapper class for android.view.View - class AndroidView; - - AndroidView *m_view; + jobject m_view; // Returns the NSWindow* for the stack containing this widget //NSWindow* getStackWindow(); @@ -47,6 +44,7 @@ class MCNativeLayerAndroid : public MCNativeLayer virtual bool doPaint(MCGContextRef p_context); virtual void doSetGeometry(const MCRectangle &p_rect); + virtual void doSetViewportGeometry(const MCRectangle &p_rect); virtual void doSetVisible(bool p_visible); // Performs a relayering operation @@ -54,6 +52,8 @@ class MCNativeLayerAndroid : public MCNativeLayer // Show/hide operations void addToMainView(); + + bool getParentView(jobject &r_view); }; #endif // ifndef __MC_NATIVE_LAYER_ANDROID__ diff --git a/engine/src/native-layer-ios.h b/engine/src/native-layer-ios.h index 367dc83dcf2..e79e6b5e8ec 100644 --- a/engine/src/native-layer-ios.h +++ b/engine/src/native-layer-ios.h @@ -28,7 +28,7 @@ class MCNativeLayerIOS : public MCNativeLayer virtual bool GetCanRenderToContext(); - MCNativeLayerIOS(MCWidgetRef, UIView *p_native_view); + MCNativeLayerIOS(MCObject *p_object, UIView *p_native_view); ~MCNativeLayerIOS(); virtual bool GetNativeView(void *&r_view); @@ -38,8 +38,8 @@ class MCNativeLayerIOS : public MCNativeLayer UIView* m_view; //NSBitmapImageRep *m_cached; - // Returns the main view - UIView* getMainView(); + // Returns the UIView of the parent of this control + bool getParentView(UIView *&r_view); // Performs the attach/detach operations virtual void doAttach(); @@ -47,6 +47,7 @@ class MCNativeLayerIOS : public MCNativeLayer virtual bool doPaint(MCGContextRef p_context); virtual void doSetGeometry(const MCRectangle &p_rect); + virtual void doSetViewportGeometry(const MCRectangle &p_rect); virtual void doSetVisible(bool p_visible); // Performs a relayering operation diff --git a/engine/src/native-layer-ios.mm b/engine/src/native-layer-ios.mm index c1741e4cd78..801619b7be1 100644 --- a/engine/src/native-layer-ios.mm +++ b/engine/src/native-layer-ios.mm @@ -40,6 +40,7 @@ #include "chunk.h" #include "graphicscontext.h" #include "objptr.h" +#include "group.h" #include "globals.h" #include "context.h" @@ -54,10 +55,10 @@ #include "graphics_util.h" -MCNativeLayerIOS::MCNativeLayerIOS(MCWidgetRef p_widget, UIView *p_native_view) : +MCNativeLayerIOS::MCNativeLayerIOS(MCObject *p_object, UIView *p_native_view) : m_view([p_native_view retain]) { - m_widget = p_widget; + m_object = p_object; } MCNativeLayerIOS::~MCNativeLayerIOS() @@ -71,12 +72,10 @@ void MCNativeLayerIOS::doAttach() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Act as if there was a re-layer to put the widget in the right place doRelayer(); - doSetVisible(ShouldShowWidget(t_widget)); + doSetVisible(ShouldShowLayer()); } void MCNativeLayerIOS::doDetach() @@ -98,6 +97,10 @@ return false; } +void MCNativeLayerIOS::doSetViewportGeometry(const MCRectangle& p_rect) +{ +} + void MCNativeLayerIOS::doSetGeometry(const MCRectangle& p_rect) { CGRect t_nsrect; @@ -117,48 +120,60 @@ [m_view setHidden:p_visible ? NO : YES]; }); if (p_visible) - doSetGeometry(MCWidgetGetHost(m_widget)->getrect()); + doSetGeometry(m_object->getrect()); } void MCNativeLayerIOS::doRelayer() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Find which native layer this should be inserted below - MCWidget* t_before; - MCNativeLayerIOS *t_before_layer = nil; - t_before = findNextLayerAbove(t_widget); - if (t_before != nil) - { - t_before_layer = reinterpret_cast(t_before->getNativeLayer()); - } - - UIView *t_view; - t_view = getMainView(); - + MCObject* t_before; + t_before = findNextLayerAbove(m_object); + + UIView *t_parent_view; + t_parent_view = nil; + + if (!getParentView(t_parent_view)) + return; + // Insert the widget in the correct place (but only if the card is current) - if (isAttached() && t_widget->getstack()->getcard() == t_widget->getstack()->getcurcard()) + if (isAttached() && m_object->getstack()->getcard() == m_object->getstack()->getcurcard()) { MCIPhoneRunBlockOnMainFiber(^{ [m_view removeFromSuperview]; - if (t_before_layer != nil) - { - // There is another native layer above this one - [t_view insertSubview:m_view belowSubview:t_before_layer->m_view]; - } + if (t_before != nil) + { + // There is another native layer above this one + UIView *t_before_view; + /* UNCHECKED */ t_before->GetNativeView((void*&)t_before_view); + [t_parent_view insertSubview:m_view belowSubview:t_before_view]; + } else { // This is the top-most native layer - [t_view addSubview:m_view]; + [t_parent_view addSubview:m_view]; } - [t_view setNeedsDisplay]; + [t_parent_view setNeedsDisplay]; }); } } -UIView* MCNativeLayerIOS::getMainView() +bool MCNativeLayerIOS::getParentView(UIView *&r_view) { - return MCIPhoneGetView(); + if (m_object->getparent()->gettype() == CT_GROUP) + { + MCNativeLayer *t_container; + t_container = nil; + + if (!((MCGroup*)m_object->getparent())->getNativeContainerLayer(t_container)) + return false; + + return t_container->GetNativeView((void*&)r_view); + } + else + { + r_view = MCIPhoneGetView(); + return true; + } } bool MCNativeLayerIOS::GetNativeView(void *&r_view) @@ -172,9 +187,55 @@ //////////////////////////////////////////////////////////////////////////////// -MCNativeLayer *MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_native_view) +MCNativeLayer *MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_native_view) +{ + return new MCNativeLayerIOS(p_object, (UIView*)p_native_view); +} + +////////// + +// IM-2015-12-16: [[ NativeLayer ]] Keep the coordinate system of group contents the same as +// the top-level window view by keeping its bounds the same as its frame. +// This allows us to place contents in terms of window coords without having to +// adjust for the location of the group container. +@interface com_runrev_livecode_MCContainerView: UIView + +- (void)setFrame:(CGRect)frame; + +@end + +@compatibility_alias MCContainerView com_runrev_livecode_MCContainerView; + +@implementation com_runrev_livecode_MCContainerView + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + [self setBounds:frame]; +} + +@end + +bool MCNativeLayer::CreateNativeContainer(void *&r_view) +{ + UIView *t_view; + t_view = [[[MCContainerView alloc] init] autorelease]; + + if (t_view == nil) + return false; + + [t_view setAutoresizesSubviews:NO]; + + r_view = t_view; + + return true; +} + +////////// + +void MCNativeLayer::ReleaseNativeView(void *p_view) { - return new MCNativeLayerIOS(p_widget, (UIView*)p_native_view); + MCIPhoneRunBlockOnMainFiber(^{[(UIView*)p_view release];}); } //////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer-mac.h b/engine/src/native-layer-mac.h index ebf1a9b01f8..802c4bca525 100644 --- a/engine/src/native-layer-mac.h +++ b/engine/src/native-layer-mac.h @@ -29,7 +29,7 @@ class MCNativeLayerMac : public MCNativeLayer virtual bool GetNativeView(void *&r_view); - MCNativeLayerMac(MCWidgetRef, NSView *p_view); + MCNativeLayerMac(MCObject *p_object, NSView *p_view); ~MCNativeLayerMac(); private: @@ -39,6 +39,10 @@ class MCNativeLayerMac : public MCNativeLayer // Returns the NSWindow* for the stack containing this widget NSWindow* getStackWindow(); + // Returns the nsview of the parent of this control + bool getParentView(NSView *&r_view); + + NSRect calculateFrameRect(const MCRectangle &p_rect); // Performs the attach/detach operations virtual void doAttach(); @@ -46,6 +50,7 @@ class MCNativeLayerMac : public MCNativeLayer virtual bool doPaint(MCGContextRef p_context); virtual void doSetGeometry(const MCRectangle &p_rect); + virtual void doSetViewportGeometry(const MCRectangle &p_rect); virtual void doSetVisible(bool p_visible); // Performs a relayering operation diff --git a/engine/src/native-layer-mac.mm b/engine/src/native-layer-mac.mm index 6f342e91046..93761ea1860 100644 --- a/engine/src/native-layer-mac.mm +++ b/engine/src/native-layer-mac.mm @@ -44,6 +44,7 @@ #include "globals.h" #include "context.h" +#include "group.h" #include "widget.h" #include "native-layer-mac.h" @@ -59,11 +60,11 @@ #include "graphics_util.h" -MCNativeLayerMac::MCNativeLayerMac(MCWidgetRef p_widget, NSView *p_view) : +MCNativeLayerMac::MCNativeLayerMac(MCObject *p_object, NSView *p_view) : m_view(p_view), m_cached(nil) { - m_widget = p_widget; + m_object = p_object; [m_view retain]; } @@ -82,8 +83,6 @@ void MCNativeLayerMac::doAttach() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Act as if there was a re-layer to put the widget in the right place // *** Can we assume open happens in back-to-front order? *** doRelayer(); @@ -91,8 +90,8 @@ // Restore the visibility state of the widget (in case it changed due to a // tool change while on another card - we don't get a message then) - doSetGeometry(t_widget->getrect()); - doSetVisible(ShouldShowWidget(t_widget)); + doSetGeometry(m_object->getrect()); + doSetVisible(ShouldShowLayer()); } void MCNativeLayerMac::doDetach() @@ -134,15 +133,24 @@ return true; } +NSRect MCNativeLayerMac::calculateFrameRect(const MCRectangle &p_rect) +{ + int32_t t_gp_height; + t_gp_height = m_object->getcard()->getrect().height; + + NSRect t_rect; + t_rect = NSMakeRect(p_rect.x, t_gp_height - (p_rect.y + p_rect.height), p_rect.width, p_rect.height); + + return t_rect; +} + +void MCNativeLayerMac::doSetViewportGeometry(const MCRectangle &p_rect) +{ +} + void MCNativeLayerMac::doSetGeometry(const MCRectangle &p_rect) { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - - NSRect t_nsrect; - MCRectangle t_cardrect; - t_cardrect = t_widget->getcard()->getrect(); - t_nsrect = NSMakeRect(p_rect.x, t_cardrect.height-p_rect.y-p_rect.height, p_rect.width, p_rect.height); - [m_view setFrame:t_nsrect]; + [m_view setFrame:calculateFrameRect(p_rect)]; [m_view setNeedsDisplay:YES]; [m_cached release]; m_cached = nil; @@ -155,36 +163,58 @@ void MCNativeLayerMac::doRelayer() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Find which native layer this should be inserted below - MCWidget* t_before; - t_before = findNextLayerAbove(t_widget); - + MCObject *t_before; + t_before = findNextLayerAbove(m_object); + + NSView *t_parent_view; + t_parent_view = nil; + + if (!getParentView(t_parent_view)) + return; + // Insert the widget in the correct place (but only if the card is current) - if (isAttached() && t_widget->getcard() == t_widget->getstack()->getcurcard()) + if (isAttached() && m_object->getcard() == m_object->getstack()->getcurcard()) { [m_view removeFromSuperview]; if (t_before != nil) { // There is another native layer above this one - MCNativeLayerMac *t_before_layer; - t_before_layer = reinterpret_cast(t_before->getNativeLayer()); - [[getStackWindow() contentView] addSubview:m_view positioned:NSWindowBelow relativeTo:t_before_layer->m_view]; + NSView *t_before_view; + /* UNCHECKED */ t_before->GetNativeView((void*&)t_before_view); + [t_parent_view addSubview:m_view positioned:NSWindowBelow relativeTo:t_before_view]; } else { // This is the top-most native layer - [[getStackWindow() contentView] addSubview:m_view]; + [t_parent_view addSubview:m_view]; } - [[getStackWindow() contentView] setNeedsDisplay:YES]; + [t_parent_view setNeedsDisplay:YES]; } } NSWindow* MCNativeLayerMac::getStackWindow() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - return ((MCMacPlatformWindow*)(t_widget->getstack()->getwindow()))->GetHandle(); + return ((MCMacPlatformWindow*)(m_object->getstack()->getwindow()))->GetHandle(); +} + +bool MCNativeLayerMac::getParentView(NSView *&r_view) +{ + if (m_object->getparent()->gettype() == CT_GROUP) + { + MCNativeLayer *t_container; + t_container = nil; + + if (!((MCGroup*)m_object->getparent())->getNativeContainerLayer(t_container)) + return false; + + return t_container->GetNativeView((void*&)r_view); + } + else + { + r_view = [getStackWindow() contentView]; + return true; + } } bool MCNativeLayerMac::GetNativeView(void *&r_view) @@ -195,11 +225,65 @@ //////////////////////////////////////////////////////////////////////////////// -MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_view) +MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_view) { if (p_view == nil) return nil; - return new MCNativeLayerMac(p_widget, (NSView*)p_view); + return new MCNativeLayerMac(p_object, (NSView*)p_view); +} + +////////// + +// IM-2015-12-16: [[ NativeLayer ]] Keep the coordinate system of group contents the same as +// the top-level window view by keeping its bounds the same as its frame. +// This allows us to place contents in terms of window coords without having to +// adjust for the location of the group container. +@interface com_runrev_livecode_MCContainerView: NSView + +- (void)setFrameOrigin:(NSPoint)newOrigin; +- (void)setFrameSize:(NSSize)newSize; + +@end + +@compatibility_alias MCContainerView com_runrev_livecode_MCContainerView; + +@implementation com_runrev_livecode_MCContainerView + +- (void)setFrameOrigin:(NSPoint)newOrigin +{ + [super setFrameOrigin:newOrigin]; + [self setBoundsOrigin:newOrigin]; +} + +- (void)setFrameSize:(NSSize)newSize +{ + [super setFrameSize:newSize]; + [self setBoundsSize:newSize]; +} + +@end + +bool MCNativeLayer::CreateNativeContainer(void *&r_view) +{ + NSView *t_view; + t_view = [[[ MCContainerView alloc] init] autorelease]; + + if (t_view == nil) + return false; + + [t_view setAutoresizesSubviews:NO]; + r_view = t_view; + + return true; } +////////// + +void MCNativeLayer::ReleaseNativeView(void *p_view) +{ + if (p_view == nil) + return; + + [(NSView*)p_view release]; +} diff --git a/engine/src/native-layer-srv.cpp b/engine/src/native-layer-srv.cpp index 5de486270a8..24e468b7565 100644 --- a/engine/src/native-layer-srv.cpp +++ b/engine/src/native-layer-srv.cpp @@ -23,10 +23,19 @@ //////////////////////////////////////////////////////////////////////////////// -// Stub method for server platforms -MCNativeLayer *MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_native_view) +// Stub methods for server platforms +MCNativeLayer *MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_native_view) { return nil; } +bool MCNativeLayer::CreateNativeContainer(void *&r_view) +{ + return false; +} + +void MCNativeLayer::ReleaseNativeView(void *p_view) +{ +} + //////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer-win32.cpp b/engine/src/native-layer-win32.cpp index 1b9d97526a4..ca4cbdb07b5 100644 --- a/engine/src/native-layer-win32.cpp +++ b/engine/src/native-layer-win32.cpp @@ -38,6 +38,7 @@ #include "redraw.h" #include "font.h" #include "chunk.h" +#include "group.h" #include "graphicscontext.h" #include "graphics_util.h" @@ -48,11 +49,12 @@ #include "native-layer-win32.h" -MCNativeLayerWin32::MCNativeLayerWin32(MCWidgetRef p_widget, HWND p_view) : - m_hwnd(p_view), - m_cached(NULL) +MCNativeLayerWin32::MCNativeLayerWin32(MCObject *p_object, HWND p_view) : + m_hwnd(p_view), + m_cached(NULL), + m_viewport_hwnd(nil) { - m_widget = p_widget; + m_object = p_object; } MCNativeLayerWin32::~MCNativeLayerWin32() @@ -63,33 +65,47 @@ MCNativeLayerWin32::~MCNativeLayerWin32() DeleteObject(m_cached); } +// IM-2016-01-19: [[ NativeLayer ]] Windows (prior to Windows 8) doesn't do transparent child windows +// so instead we place each child window in its own container, sized to expose only the area that +// should be visible when the native layer is clipped by the bounds of any groups it is in. void MCNativeLayerWin32::doAttach() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - + HWND t_parent; + t_parent = getStackWindow(); + + if (m_viewport_hwnd == nil) + /* UNCHECKED */ CreateNativeContainer((void*&)m_viewport_hwnd); + // Set the parent to the stack - SetParent(m_hwnd, getStackWindow()); + SetParent(m_viewport_hwnd, t_parent); + + SetParent(m_hwnd, m_viewport_hwnd); - // Restore the visibility state of the widget (in case it changed due to a + // Restore the state of the widget (in case it changed due to a // tool change while on another card - we don't get a message then) - doSetGeometry(t_widget->getrect()); - doSetVisible(ShouldShowWidget(t_widget)); + m_rect = m_object->getrect(); + if (m_object->getparent()->gettype() == CT_GROUP) + m_viewport_rect = ((MCGroup*)m_object->getparent())->getviewportgeometry(); + else + m_viewport_rect = m_rect; + + doSetViewportGeometry(m_viewport_rect); + doSetGeometry(m_rect); + doSetVisible(ShouldShowLayer()); } void MCNativeLayerWin32::doDetach() { // Change the window to an invisible child of the desktop - ShowWindow(m_hwnd, SW_HIDE); + doSetVisible(false); SetParent(m_hwnd, NULL); + SetParent(m_viewport_hwnd, NULL); } bool MCNativeLayerWin32::doPaint(MCGContextRef p_context) { - MCWidget *t_widget; - t_widget = MCWidgetGetHost(m_widget); - MCRectangle t_rect; - t_rect = t_widget->getrect(); + t_rect = m_object->getrect(); bool t_success; t_success = true; @@ -203,12 +219,31 @@ bool MCNativeLayerWin32::doPaint(MCGContextRef p_context) return t_success; } +void MCNativeLayerWin32::updateViewportGeometry() +{ + m_intersect_rect = MCU_intersect_rect(m_viewport_rect, m_rect); + MoveWindow(m_viewport_hwnd, m_intersect_rect.x, m_intersect_rect.y, m_intersect_rect.width, m_intersect_rect.height, ShouldShowLayer()); +} + +void MCNativeLayerWin32::doSetViewportGeometry(const MCRectangle &p_rect) +{ + m_viewport_rect = p_rect; + updateViewportGeometry(); +} + void MCNativeLayerWin32::doSetGeometry(const MCRectangle& p_rect) { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - + m_rect = p_rect; + updateViewportGeometry(); + + MCRectangle t_rect; + t_rect = m_rect; + + t_rect.x -= m_intersect_rect.x; + t_rect.y -= m_intersect_rect.y; + // Move the window. Only trigger a repaint if not in edit mode - MoveWindow(m_hwnd, p_rect.x, p_rect.y, p_rect.width, p_rect.height, t_widget->isInRunMode()); + MoveWindow(m_hwnd, t_rect.x, t_rect.y, t_rect.width, t_rect.height, ShouldShowLayer()); // We need to delete the bitmap that we've been caching DeleteObject(m_cached); @@ -218,18 +253,17 @@ void MCNativeLayerWin32::doSetGeometry(const MCRectangle& p_rect) void MCNativeLayerWin32::doSetVisible(bool p_visible) { ShowWindow(m_hwnd, p_visible ? SW_SHOWNOACTIVATE : SW_HIDE); + ShowWindow(m_viewport_hwnd, p_visible ? SW_SHOWNOACTIVATE : SW_HIDE); } void MCNativeLayerWin32::doRelayer() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Find which native layer this should be inserted after - MCWidget* t_before; - t_before = findNextLayerBelow(t_widget); + MCObject *t_before; + t_before = findNextLayerBelow(m_object); // Insert the widget in the correct place (but only if the card is current) - if (isAttached() && t_widget->getstack()->getcard() == t_widget->getstack()->getcurcard()) + if (isAttached() && m_object->getstack()->getcard() == m_object->getstack()->getcurcard()) { HWND t_insert_after; if (t_before != NULL) @@ -250,8 +284,7 @@ void MCNativeLayerWin32::doRelayer() HWND MCNativeLayerWin32::getStackWindow() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - return (HWND)t_widget->getstack()->getrealwindow(); + return (HWND)m_object->getstack()->getrealwindow(); } bool MCNativeLayerWin32::GetNativeView(void *&r_view) @@ -262,9 +295,62 @@ bool MCNativeLayerWin32::GetNativeView(void *&r_view) //////////////////////////////////////////////////////////////////////////////// -MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_view) +MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_view) +{ + return new MCNativeLayerWin32(p_object, (HWND)p_view); +} + +extern HINSTANCE MChInst; +bool getcontainerclass(ATOM &r_class) +{ + static ATOM s_container_class = nil; + + if (s_container_class == nil) + { + WNDCLASSEX t_class; + MCMemoryClear(t_class); + + t_class.cbSize = sizeof(WNDCLASSEX); + t_class.lpfnWndProc = DefWindowProc; + t_class.hInstance = MChInst; + t_class.lpszClassName = "LCCONTAINER"; + + s_container_class = RegisterClassEx(&t_class); + + DWORD t_err; + t_err = GetLastError(); + + if (s_container_class == nil) + return false; + } + + r_class = s_container_class; + + return true; +} + +bool MCNativeLayer::CreateNativeContainer(void *&r_container) +{ + ATOM t_class; + if (!getcontainerclass(t_class)) + return false; + + HWND t_container; + t_container = CreateWindow((LPCSTR)t_class, "Container", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 1, 1, (HWND)MCdefaultstackptr->getrealwindow(), nil, MChInst, nil); + + DWORD t_err; + t_err = GetLastError(); + + if (t_container == nil) + return false; + + r_container = t_container; + return true; +} + +void MCNativeLayer::ReleaseNativeView(void *p_view) { - return new MCNativeLayerWin32(p_widget, (HWND)p_view); + DestroyWindow((HWND)p_view); } //////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer-win32.h b/engine/src/native-layer-win32.h index ec72c046c5d..2007d657a1f 100644 --- a/engine/src/native-layer-win32.h +++ b/engine/src/native-layer-win32.h @@ -27,13 +27,16 @@ class MCNativeLayerWin32 : public MCNativeLayer virtual bool GetNativeView(void *&r_view); - MCNativeLayerWin32(MCWidgetRef, HWND p_view); + MCNativeLayerWin32(MCObject *p_object, HWND p_view); ~MCNativeLayerWin32(); private: HWND m_hwnd; HBITMAP m_cached; + + HWND m_viewport_hwnd; + MCRectangle m_intersect_rect; // Returns the HWND for the stack containing this widget HWND getStackWindow(); @@ -44,8 +47,11 @@ class MCNativeLayerWin32 : public MCNativeLayer virtual bool doPaint(MCGContextRef p_context); virtual void doSetGeometry(const MCRectangle &p_rect); + virtual void doSetViewportGeometry(const MCRectangle &p_rect); virtual void doSetVisible(bool p_visible); + void updateViewportGeometry(); + // Performs a relayering operation virtual void doRelayer(); }; diff --git a/engine/src/native-layer-x11.cpp b/engine/src/native-layer-x11.cpp index 3f5a2ce6988..c62281f87bf 100644 --- a/engine/src/native-layer-x11.cpp +++ b/engine/src/native-layer-x11.cpp @@ -54,13 +54,13 @@ #include -MCNativeLayerX11::MCNativeLayerX11(MCWidgetRef p_widget, x11::Window p_view) : +MCNativeLayerX11::MCNativeLayerX11(MCObject *p_object, x11::Window p_view) : m_child_window(NULL), m_input_shape(NULL), m_socket(NULL), m_widget_xid(p_view) { - m_widget = p_widget; + m_object = p_object; } MCNativeLayerX11::~MCNativeLayerX11() @@ -87,9 +87,7 @@ void MCNativeLayerX11::OnToolChanged(Tool p_new_tool) void MCNativeLayerX11::updateInputShape() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - - if (!t_widget->isInRunMode()) + if (m_show_for_tool) // In edit mode. Mask out all input events gdk_window_input_shape_combine_region(gtk_widget_get_window(GTK_WIDGET(m_child_window)), m_input_shape, 0, 0); else @@ -99,8 +97,6 @@ void MCNativeLayerX11::updateInputShape() void MCNativeLayerX11::doAttach() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - if (m_socket == NULL) { // Create a new GTK socket to deal with the XEMBED protocol @@ -109,7 +105,7 @@ void MCNativeLayerX11::doAttach() // Create a new GTK window to hold the socket MCRectangle t_rect; - t_rect = t_widget->getrect(); + t_rect = m_object->getrect(); m_child_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP)); gtk_widget_set_parent_window(GTK_WIDGET(m_child_window), getStackGdkWindow()); gtk_widget_realize(GTK_WIDGET(m_child_window)); @@ -139,8 +135,9 @@ void MCNativeLayerX11::doAttach() // Act as if there were a re-layer to put the widget in the right place doRelayer(); - - doSetVisible(ShouldShowWidget(t_widget)); + doSetViewportGeometry(m_viewport_rect); + doSetGeometry(m_rect); + doSetVisible(ShouldShowLayer()); } void MCNativeLayerX11::doDetach() @@ -160,33 +157,59 @@ bool MCNativeLayerX11::doPaint(MCGContextRef p_context) return false; } +void MCNativeLayerX11::updateContainerGeometry() +{ + m_intersect_rect = MCU_intersect_rect(m_viewport_rect, m_rect); + + // Clear any minimum size parameters for the GTK widgets + gtk_widget_set_size_request(GTK_WIDGET(m_child_window), -1, -1); + + // Resize by adjusting the widget's containing GtkWindow + gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(m_child_window)), m_intersect_rect.x, m_intersect_rect.y, m_intersect_rect.width, m_intersect_rect.height); + + // We need to set the requested minimum size in order to get in-process GTK + // widgets to re-size automatically. Unfortunately, that is the only widget + // category that this works for... others need to do it themselves. + gtk_widget_set_size_request(GTK_WIDGET(m_child_window), m_intersect_rect.width, m_intersect_rect.height); +} + +void MCNativeLayerX11::doSetViewportGeometry(const MCRectangle &p_rect) +{ + m_viewport_rect = p_rect; + updateContainerGeometry(); +} + +// IM-2016-01-21: [[ NativeLayer ]] Place the socket window relative to its +// container, so only the visible area (clipped by any containing groups) +// is displayed. void MCNativeLayerX11::doSetGeometry(const MCRectangle& p_rect) { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - + m_rect = p_rect; + updateContainerGeometry(); + + MCRectangle t_rect; + t_rect = m_rect; + t_rect.x -= m_intersect_rect.x; + t_rect.y -= m_intersect_rect.y; + // Move the overlay window first, to ensure events don't get stolen // Clear any minimum size parameters for the GTK widgets gtk_widget_set_size_request(GTK_WIDGET(m_socket), -1, -1); - gtk_widget_set_size_request(GTK_WIDGET(m_child_window), -1, -1); - - // Resize by adjusting the widget's containing GtkWindow - gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(m_child_window)), p_rect.x, p_rect.y, p_rect.width, p_rect.height); // Resize the socket - gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(m_socket)), 0, 0, p_rect.width, p_rect.height); + gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(m_socket)), t_rect.x, t_rect.y, t_rect.width, t_rect.height); // We need to set the requested minimum size in order to get in-process GTK // widgets to re-size automatically. Unfortunately, that is the only widget // category that this works for... others need to do it themselves. - gtk_widget_set_size_request(GTK_WIDGET(m_child_window), p_rect.width, p_rect.height); - gtk_widget_set_size_request(GTK_WIDGET(m_socket), p_rect.width, p_rect.height); + gtk_widget_set_size_request(GTK_WIDGET(m_socket), t_rect.width, t_rect.height); // Update the contained window too GdkWindow* t_remote; t_remote = gtk_socket_get_plug_window(m_socket); if (t_remote != NULL) - gdk_window_move_resize(t_remote, 0, 0, p_rect.width, p_rect.height); + gdk_window_move_resize(t_remote, t_rect.x, t_rect.y, t_rect.width, t_rect.height); } void MCNativeLayerX11::doSetVisible(bool p_visible) @@ -197,22 +220,20 @@ void MCNativeLayerX11::doSetVisible(bool p_visible) gtk_widget_hide(GTK_WIDGET(m_child_window)); if (p_visible) - doSetGeometry(MCWidgetGetHost(m_widget)->getrect()); + doSetGeometry(m_object->getrect()); } void MCNativeLayerX11::doRelayer() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - // Ensure that the input mask for the widget is up to date updateInputShape(); // Find which native layer this should be inserted below - MCWidget* t_before; - t_before = findNextLayerAbove(t_widget); + MCObject *t_before; + t_before = findNextLayerAbove(m_object); // Insert the widget in the correct place (but only if the card is current) - if (isAttached() && t_widget->getstack()->getcard() == t_widget->getstack()->getcurcard()) + if (isAttached() && m_object->getstack()->getcard() == m_object->getstack()->getcurcard()) { // If t_before_window == NULL, this will put the widget on the bottom layer MCNativeLayerX11 *t_before_layer; @@ -229,9 +250,6 @@ void MCNativeLayerX11::doRelayer() } gdk_window_restack(gtk_widget_get_window(GTK_WIDGET(m_child_window)), t_before_window, FALSE); } - - // Make the widget visible, if appropriate - doSetVisible(ShouldShowWidget(t_widget)); } //////////////////////////////////////////////////////////////////////////////// @@ -251,13 +269,23 @@ x11::Window MCNativeLayerX11::getStackX11Window() GdkWindow* MCNativeLayerX11::getStackGdkWindow() { - MCWidget* t_widget = MCWidgetGetHost(m_widget); - return t_widget->getstack()->getwindow(); + return m_object->getstack()->getwindow(); } //////////////////////////////////////////////////////////////////////////////// -MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCWidgetRef p_widget, void *p_native_view) +MCNativeLayer* MCNativeLayer::CreateNativeLayer(MCObject *p_object, void *p_native_view) +{ + return new MCNativeLayerX11(p_object, (x11::Window)p_native_view); +} + +bool MCNativeLayer::CreateNativeContainer(void *&r_view) +{ + return false; +} + +void MCNativeLayer::ReleaseNativeView(void *p_view) { - return new MCNativeLayerX11(p_widget, (x11::Window)p_native_view); } + +//////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer-x11.h b/engine/src/native-layer-x11.h index b38f44be81e..7dfc9919fb1 100644 --- a/engine/src/native-layer-x11.h +++ b/engine/src/native-layer-x11.h @@ -35,7 +35,7 @@ class MCNativeLayerX11 : public MCNativeLayer virtual bool GetNativeView(void *&r_view); - MCNativeLayerX11(MCWidgetRef p_widget, x11::Window p_view); + MCNativeLayerX11(MCObject *p_object, x11::Window p_view); ~MCNativeLayerX11(); private: @@ -44,6 +44,7 @@ class MCNativeLayerX11 : public MCNativeLayer GdkRegion* m_input_shape; GtkSocket* m_socket; x11::Window m_widget_xid; + MCRectangle m_intersect_rect; // Returns the handle for the stack containing this widget x11::Window getStackX11Window(); @@ -58,6 +59,7 @@ class MCNativeLayerX11 : public MCNativeLayer virtual bool doPaint(MCGContextRef p_context); virtual void doSetGeometry(const MCRectangle &p_rect); + virtual void doSetViewportGeometry(const MCRectangle &p_rect); virtual void doSetVisible(bool p_visible); // Performs a relayering operation @@ -65,6 +67,8 @@ class MCNativeLayerX11 : public MCNativeLayer // Updates the input mask for the widget (used to implement edit mode) void updateInputShape(); + + void updateContainerGeometry(); }; #endif // ifndef __MC_NATIVE_LAYER_X11__ diff --git a/engine/src/native-layer.cpp b/engine/src/native-layer.cpp index 6d0e6ce6d65..a47ff5a4c5b 100644 --- a/engine/src/native-layer.cpp +++ b/engine/src/native-layer.cpp @@ -49,8 +49,8 @@ //////////////////////////////////////////////////////////////////////////////// MCNativeLayer::MCNativeLayer() : - m_widget(nil), m_attached(false), m_can_render_to_context(true), - m_defer_geometry_changes(false) + m_object(nil), m_attached(false), m_can_render_to_context(true), + m_defer_geometry_changes(false), m_visible(false), m_show_for_tool(false) { ; } @@ -62,19 +62,6 @@ MCNativeLayer::~MCNativeLayer() //////////////////////////////////////////////////////////////////////////////// -void MCNativeLayer::OnOpen() -{ - // Unhide the widget, if required - if (isAttached()) - doAttach(); -} - -void MCNativeLayer::OnClose() -{ - if (isAttached()) - doDetach(); -} - void MCNativeLayer::OnAttach() { m_attached = true; @@ -92,35 +79,74 @@ bool MCNativeLayer::OnPaint(MCGContextRef p_context) return doPaint(p_context); } -void MCNativeLayer::OnGeometryChanged(const MCRectangle &p_old_rect) +void MCNativeLayer::OnGeometryChanged(const MCRectangle &p_new_rect) { if (!m_defer_geometry_changes) - doSetGeometry(MCWidgetGetHost(m_widget)->getrect()); + { + doSetGeometry(p_new_rect); + m_rect = p_new_rect; + } + else + m_deferred_rect = p_new_rect; +} + +void MCNativeLayer::OnViewportGeometryChanged(const MCRectangle &p_rect) +{ + if (!m_defer_geometry_changes) + { + doSetViewportGeometry(p_rect); + m_viewport_rect = p_rect; + } + else + m_deferred_viewport_rect = p_rect; } void MCNativeLayer::OnToolChanged(Tool p_new_tool) { - MCWidget* t_widget = MCWidgetGetHost(m_widget); + bool t_showing; + t_showing = ShouldShowLayer(); - OnVisibilityChanged(ShouldShowWidget(t_widget)); - t_widget->Redraw(); + m_show_for_tool = p_new_tool == T_BROWSE || p_new_tool == T_HELP; + + if (t_showing != (ShouldShowLayer())) + UpdateVisibility(); + + m_object->Redraw(); } void MCNativeLayer::OnVisibilityChanged(bool p_visible) { - if (p_visible) + bool t_showing; + t_showing = ShouldShowLayer(); + + m_visible = p_visible; + + if (t_showing != (ShouldShowLayer())) + UpdateVisibility(); +} + +void MCNativeLayer::UpdateVisibility() +{ + if (ShouldShowLayer()) { if (m_defer_geometry_changes) - doSetGeometry(MCWidgetGetHost(m_widget)->getrect()); + { + doSetViewportGeometry(m_deferred_viewport_rect); + doSetGeometry(m_deferred_rect); + } m_defer_geometry_changes = false; } else { if (!GetCanRenderToContext()) + { m_defer_geometry_changes = true; + m_deferred_rect = m_rect; + m_deferred_viewport_rect = m_viewport_rect; + } } - doSetVisible(p_visible); + doSetVisible(ShouldShowLayer()); } void MCNativeLayer::OnLayerChanged() @@ -135,38 +161,38 @@ bool MCNativeLayer::isAttached() const return m_attached; } -bool MCNativeLayer::ShouldShowWidget(MCWidget *p_widget) +bool MCNativeLayer::ShouldShowLayer() { - return p_widget->getflag(F_VISIBLE) && p_widget->isInRunMode(); + return m_show_for_tool && m_visible; } -struct MCNativeLayerFindWidgetObjectVisitor: public MCObjectVisitor +struct MCNativeLayerFindObjectVisitor: public MCObjectVisitor { - MCWidget *current_widget; - MCWidget *found_widget; + MCObject *current_object; + MCObject *found_object; bool find_above; bool reached_current; - bool OnWidget(MCWidget *p_widget) + bool OnObject(MCObject *p_object) { - // We are only looking for widgets with a native layer - if (p_widget->getNativeLayer() != nil) - return OnNativeLayerWidget(p_widget); + // We are only looking for objects with a native layer + if (p_object->getNativeLayer() != nil) + return OnNativeLayerObject(p_object); return true; } - bool OnNativeLayerWidget(MCWidget *p_widget) + bool OnNativeLayerObject(MCObject *p_object) { if (find_above) { if (reached_current) { - found_widget = p_widget; + found_object = p_object; return false; } - else if (p_widget == current_widget) + else if (p_object == current_object) { reached_current = true; return true; @@ -175,14 +201,14 @@ struct MCNativeLayerFindWidgetObjectVisitor: public MCObjectVisitor } else { - if (p_widget == current_widget) + if (p_object == current_object) { reached_current = true; return false; } else { - found_widget = p_widget; + found_object = p_object; return true; } } @@ -190,30 +216,30 @@ struct MCNativeLayerFindWidgetObjectVisitor: public MCObjectVisitor }; -MCWidget* MCNativeLayer::findNextLayerAbove(MCWidget* p_widget) +MCObject* MCNativeLayer::findNextLayerAbove(MCObject* p_object) { - MCNativeLayerFindWidgetObjectVisitor t_visitor; - t_visitor.current_widget = p_widget; - t_visitor.found_widget = nil; + MCNativeLayerFindObjectVisitor t_visitor; + t_visitor.current_object = p_object; + t_visitor.found_object = nil; t_visitor.reached_current = false; t_visitor.find_above = true; - p_widget->getcard()->visit(kMCObjectVisitorRecursive, 0, &t_visitor); + p_object->getparent()->visit_children(0, 0, &t_visitor); - return t_visitor.found_widget; + return t_visitor.found_object; } -MCWidget* MCNativeLayer::findNextLayerBelow(MCWidget* p_widget) +MCObject* MCNativeLayer::findNextLayerBelow(MCObject* p_object) { - MCNativeLayerFindWidgetObjectVisitor t_visitor; - t_visitor.current_widget = p_widget; - t_visitor.found_widget = nil; + MCNativeLayerFindObjectVisitor t_visitor; + t_visitor.current_object = p_object; + t_visitor.found_object = nil; t_visitor.reached_current = false; t_visitor.find_above = false; - p_widget->getcard()->visit(kMCObjectVisitorRecursive, 0, &t_visitor); + p_object->getparent()->visit_children(0, 0, &t_visitor); - return t_visitor.found_widget; + return t_visitor.found_object; } //////////////////////////////////////////////////////////////////////////////// diff --git a/engine/src/native-layer.h b/engine/src/native-layer.h index a9ccf22f621..1acc6c055e7 100644 --- a/engine/src/native-layer.h +++ b/engine/src/native-layer.h @@ -19,16 +19,17 @@ #define __MC_NATIVE_LAYER__ +class MCObject; + class MCNativeLayer { public: - virtual void OnOpen(); - virtual void OnClose(); virtual void OnAttach(); virtual void OnDetach(); virtual bool OnPaint(MCGContextRef p_context); - virtual void OnGeometryChanged(const MCRectangle& p_old_rect); + virtual void OnGeometryChanged(const MCRectangle& p_new_rect); + virtual void OnViewportGeometryChanged(const MCRectangle &p_rect); virtual void OnVisibilityChanged(bool p_visible); virtual void OnToolChanged(Tool p_new_tool); virtual void OnLayerChanged(); @@ -41,36 +42,49 @@ class MCNativeLayer virtual bool GetNativeView(void *&r_view) = 0; // Implemented by the platform-specific native layers: creates a new layer - static MCNativeLayer* CreateNativeLayer(MCWidgetRef p_widget, void *p_native_view); + static MCNativeLayer *CreateNativeLayer(MCObject *p_object, void *p_native_view); + static bool CreateNativeContainer(void *&r_view); + static void ReleaseNativeView(void *p_view); void SetCanRenderToContext(bool p_can_render); virtual bool GetCanRenderToContext(); protected: + void UpdateVisibility(); + // Platform-specific implementations virtual void doAttach() = 0; virtual void doDetach() = 0; virtual bool doPaint(MCGContextRef p_context) = 0; virtual void doSetVisible(bool p_visible) = 0; virtual void doSetGeometry(const MCRectangle &p_rect) = 0; + virtual void doSetViewportGeometry(const MCRectangle &p_rect) = 0; virtual void doRelayer() = 0; - MCWidgetRef m_widget; + MCObject *m_object; bool m_attached; + bool m_visible; + bool m_show_for_tool; bool m_can_render_to_context; + + MCRectangle m_rect; + MCRectangle m_viewport_rect; + bool m_defer_geometry_changes; - + MCRectangle m_deferred_rect; + MCRectangle m_deferred_viewport_rect; + MCNativeLayer(); - // Returns true if the widget should be currently visible - virtual bool ShouldShowWidget(MCWidget *p_widget); - + // Returns true if the layer should be currently visible + virtual bool ShouldShowLayer(); + // Utility function for subclasses: given a widget, finds the native layer // immediately below or above it. If none exist, returns nil. - static MCWidget* findNextLayerBelow(MCWidget*); - static MCWidget* findNextLayerAbove(MCWidget*); + static MCObject* findNextLayerBelow(MCObject*); + static MCObject* findNextLayerAbove(MCObject*); }; diff --git a/engine/src/object.cpp b/engine/src/object.cpp index d1853d19df9..7d4a586aa35 100644 --- a/engine/src/object.cpp +++ b/engine/src/object.cpp @@ -162,6 +162,9 @@ MCObject::MCObject() m_theme = kMCInterfaceThemeEmpty; m_theme_type = kMCPlatformControlTypeGeneric; + // IM-2016-01-21: Initialize native layer to nil + m_native_layer = nil; + // Attach ourselves to an object pool. MCDeletedObjectsOnObjectCreated(this); } @@ -264,6 +267,9 @@ MCObject::MCObject(const MCObject &oref) : MCDLlist(oref) m_theme = oref.m_theme; m_theme_type = oref.m_theme_type; + // IM-2016-01-21: Initialize native layer to nil + m_native_layer = nil; + // Attach ourselves to an object pool. MCDeletedObjectsOnObjectCreated(this); } @@ -322,6 +328,8 @@ MCObject::~MCObject() // If this object is a parent-script make sure we flush it from the table. if (m_is_parent_script) MCParentScript::FlushObject(this); + + delete m_native_layer; // Detach ourselves from the object pool. MCDeletedObjectsOnObjectDestroyed(this); @@ -376,6 +384,8 @@ void MCObject::open() for (uint32_t i = 0 ; i < npatterns ; i++) patterns[i].pattern = MCpatternlist->allocpat(patterns[i].id, this); + + OnOpen(); } void MCObject::close() @@ -383,6 +393,8 @@ void MCObject::close() if (opened == 0 || --opened != 0) return; + OnClose(); + if (state & CS_MENU_ATTACHED) closemenu(False, True); @@ -823,7 +835,14 @@ uint2 MCObject::gettransient() const return 0; } -void MCObject::setrect(const MCRectangle &nrect) +void MCObject::setrect(const MCRectangle &p_rect) +{ + applyrect(p_rect); + + geometrychanged(getrect()); +} + +void MCObject::applyrect(const MCRectangle &nrect) { rect = nrect; } @@ -1179,16 +1198,46 @@ void MCObject::recompute() { } -void MCObject::toolchanged(Tool) +void MCObject::toolchanged(Tool p_new_tool) { + if (getNativeLayer() != nil) + getNativeLayer()->OnToolChanged(p_new_tool); } void MCObject::layerchanged() { + if (getNativeLayer() != nil) + getNativeLayer()->OnLayerChanged(); } void MCObject::visibilitychanged(bool p_visible) { + if (getNativeLayer() != nil) + getNativeLayer()->OnVisibilityChanged(p_visible); +} + +void MCObject::geometrychanged(const MCRectangle &p_rect) +{ + if (getNativeLayer() != nil) + getNativeLayer()->OnGeometryChanged(p_rect); +} + +void MCObject::viewportgeometrychanged(const MCRectangle &p_rect) +{ + if (getNativeLayer() != nil) + getNativeLayer()->OnViewportGeometryChanged(p_rect); +} + +void MCObject::OnOpen() +{ + if (getNativeLayer() != nil) + getNativeLayer()->OnAttach(); +} + +void MCObject::OnClose() +{ + if (getNativeLayer() != nil) + getNativeLayer()->OnDetach(); } const MCRectangle& MCObject::getrect(void) const @@ -1315,16 +1364,15 @@ MCParentScript *MCObject::getparentscript(void) const return parent_script != NULL ? parent_script -> GetParent() : NULL; } -Boolean MCObject::isvisible() +bool MCObject::isvisible(bool p_effective) { - MCObject *p = this; - while (p->parent != NULL && p->parent->gettype() == CT_GROUP) - { - if (!(p->flags & F_VISIBLE)) - return False; - p = p->parent; - } - return (p->flags & F_VISIBLE) != 0; + if (!getflag(F_VISIBLE)) + return false; + + if (p_effective && parent != nil && parent->gettype() == CT_GROUP) + return parent->isvisible(true); + + return true; } Boolean MCObject::resizeparent() @@ -5133,6 +5181,65 @@ void MCObject::relayercontrol_insert(MCControl *p_control, MCControl *p_target) { } +//////////////////////////////////////////////////////////////////////////////// + +// Gets the current native layer (if any) associated with this object +MCNativeLayer* MCObject::getNativeLayer() const +{ + return m_native_layer; +} + +bool MCObject::GetNativeView(void *&r_view) +{ + if (m_native_layer == nil) + return false; + + return m_native_layer->GetNativeView(r_view); +} + +bool MCObject::SetNativeView(void *p_view) +{ + bool t_success; + t_success = true; + + MCNativeLayer *t_layer; + t_layer = nil; + + if (t_success && p_view != nil) + { + t_layer = MCNativeLayer::CreateNativeLayer(this, p_view); + t_success = t_layer != nil; + } + + if (t_success) + { + if (m_native_layer != nil) + delete m_native_layer; + + m_native_layer = t_layer; + if (m_native_layer != nil) + { + if (opened) + m_native_layer->OnAttach(); + + MCRectangle t_viewport; + if (getparent() != nil && getparent()->gettype() == CT_GROUP) + t_viewport = ((MCGroup*)getparent())->getviewportgeometry(); + else + t_viewport = getrect(); + + m_native_layer->OnGeometryChanged(getrect()); + m_native_layer->OnViewportGeometryChanged(t_viewport); + m_native_layer->OnToolChanged(getstack()->gettool(this)); + m_native_layer->OnVisibilityChanged(isvisible()); + } + } + + return t_success; +} + +//////////////////////////////////////////////////////////////////////////////// + void MCObject::scheduledelete(bool p_is_child) { if (!p_is_child) diff --git a/engine/src/object.h b/engine/src/object.h index 52aad63851e..7bf00e758ec 100644 --- a/engine/src/object.h +++ b/engine/src/object.h @@ -27,6 +27,8 @@ along with LiveCode. If not see . */ #include "parsedef.h" #include "platform.h" +#include "native-layer.h" + enum { MAC_SHADOW, MAC_THUMB_TOP, @@ -335,6 +337,10 @@ class MCObject : public MCDLlist static MCObjectPropertyTable kPropertyTable; static MCPropertyInfo kModeProperties[]; static MCObjectPropertyTable kModePropertyTable; + + // The native layer associated with this object + MCNativeLayer* m_native_layer; + public: MCObject(); MCObject(const MCObject &oref); @@ -374,7 +380,8 @@ class MCObject : public MCDLlist virtual void timer(MCNameRef mptr, MCParameter *params); virtual uint2 gettransient() const; - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); + void setrect(const MCRectangle &p_rect); // MW-2011-11-23: [[ Array Chunk Props ]] Add 'effective' param to arrayprop access. #ifdef LEGACY_EXEC @@ -410,6 +417,17 @@ class MCObject : public MCDLlist // AL-2015-09-23: [[ Native Widgets ]] Informs the object that its visibility has changed virtual void visibilitychanged(bool p_visible); + + // IM-2015-12-11: [[ Native Widgets ]] Informs the object that its rect has changed + virtual void geometrychanged(const MCRectangle &p_rect); + + // IM-2016-01-19: [[ NativeWidgets ]] Informs the object that its visible area has changed. + virtual void viewportgeometrychanged(const MCRectangle &p_rect); + + // IM-2015-12-16: [[ NativeWidgets ]] Informs the object that it has been opened. + virtual void OnOpen(); + // IM-2015-12-16: [[ NativeWidgets ]] Informs the object that it will be closed. + virtual void OnClose(); // MW-2011-09-20: [[ Collision ]] Compute the shape of the object's mask. virtual bool lockshape(MCObjectShape& r_shape); @@ -472,6 +490,12 @@ class MCObject : public MCDLlist virtual void relayercontrol_remove(MCControl *control); virtual void relayercontrol_insert(MCControl *control, MCControl *target); + bool GetNativeView(void *&r_view); + bool SetNativeView(void *p_view); + + // Gets the current native layer (if any) associated with this object + MCNativeLayer* getNativeLayer() const; + MCNameRef getdefaultpropsetname(void); #ifdef LEGACY_EXEC @@ -635,7 +659,10 @@ class MCObject : public MCDLlist MCImage *resolveimageid(uint4 image_id); MCImage *resolveimagename(MCStringRef name); - Boolean isvisible(); + // IM-2015-12-07: [[ ObjectVisibility ]] + // Returns the visibility of the object. If effective is true then only returns true if the parent (and its parent, etc.) is also visible. + bool isvisible(bool p_effective = true); + Boolean resizeparent(); Boolean getforecolor(uint2 di, Boolean reversed, Boolean hilite, MCColor &c, MCPatternRef &r_pattern, int2 &x, int2 &y, MCDC *dc, MCObject *o, bool selected = false); @@ -915,7 +942,6 @@ class MCObject : public MCDLlist void SetPattern(MCExecContext& ctxt, uint2 p_new_pixmap, uint4* p_new_id); bool GetPatterns(MCExecContext& ctxt, bool effective, MCStringRef& r_patterns); - void SetVisibility(MCExecContext& ctxt, uint32_t part, bool flag, bool visible); void SetRectProp(MCExecContext& ctxt, bool effective, MCRectangle p_rect); void GetRectPoint(MCExecContext& ctxt, bool effective, Properties which, MCPoint &r_point); void SetRectPoint(MCExecContext& ctxt, bool effective, Properties which, MCPoint point); diff --git a/engine/src/player-interface.h b/engine/src/player-interface.h index c93ee67dfe4..9c25cc02e0d 100644 --- a/engine/src/player-interface.h +++ b/engine/src/player-interface.h @@ -194,7 +194,6 @@ class MCPlayerInterface ////////// PROPERTY SUPPORT METHODS virtual void Redraw(void) = 0; - virtual void SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible) = 0; ////////// PROPERTY ACCESSORS @@ -256,7 +255,6 @@ class MCPlayerInterface virtual void SetShowBorder(MCExecContext& ctxt, bool setting) = 0; virtual void SetBorderWidth(MCExecContext& ctxt, uinteger_t width) = 0; virtual void SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting) = 0; - virtual void SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting) = 0; virtual void SetTraversalOn(MCExecContext& ctxt, bool setting) = 0; virtual void GetEnabledTracks(MCExecContext& ctxt, uindex_t& r_count, uinteger_t*& r_tracks) = 0; diff --git a/engine/src/player-legacy.cpp b/engine/src/player-legacy.cpp index 1bfe428ba40..f330fe0ab39 100755 --- a/engine/src/player-legacy.cpp +++ b/engine/src/player-legacy.cpp @@ -523,7 +523,7 @@ Boolean MCPlayer::doubleup(uint2 which) return MCControl::doubleup(which); } -void MCPlayer::setrect(const MCRectangle &nrect) +void MCPlayer::applyrect(const MCRectangle &nrect) { #ifdef FEATURE_QUICKTIME if (usingQT()) diff --git a/engine/src/player-legacy.h b/engine/src/player-legacy.h index d8a70b08cd2..31515196069 100644 --- a/engine/src/player-legacy.h +++ b/engine/src/player-legacy.h @@ -110,7 +110,7 @@ class MCPlayer : public MCControl, public MCPlayerInterface virtual Boolean mup(uint2 which, bool p_release); virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); virtual void timer(MCNameRef mptr, MCParameter *params); #ifdef LEGACY_EXEC @@ -411,7 +411,6 @@ class MCPlayer : public MCControl, public MCPlayerInterface ////////// PROPERTY SUPPORT METHODS virtual void Redraw(void); - virtual void SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible); ////////// PROPERTY ACCESSORS @@ -472,7 +471,6 @@ class MCPlayer : public MCControl, public MCPlayerInterface virtual void SetShowBorder(MCExecContext& ctxt, bool setting); virtual void SetBorderWidth(MCExecContext& ctxt, uinteger_t width); virtual void SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting); - virtual void SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting); virtual void SetTraversalOn(MCExecContext& ctxt, bool setting); virtual void GetEnabledTracks(MCExecContext& ctxt, uindex_t& r_count, uinteger_t*& r_tracks); diff --git a/engine/src/player-platform.cpp b/engine/src/player-platform.cpp index f2ff372d13b..2b1e52324a0 100644 --- a/engine/src/player-platform.cpp +++ b/engine/src/player-platform.cpp @@ -1136,7 +1136,7 @@ Boolean MCPlayer::doubleup(uint2 which) } -void MCPlayer::setrect(const MCRectangle &nrect) +void MCPlayer::applyrect(const MCRectangle &nrect) { rect = nrect; diff --git a/engine/src/player-platform.h b/engine/src/player-platform.h index 991f34a065b..41ac854b49d 100644 --- a/engine/src/player-platform.h +++ b/engine/src/player-platform.h @@ -111,7 +111,7 @@ class MCPlayer : public MCControl, public MCPlayerInterface virtual Boolean mup(uint2 which, bool p_release); virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); virtual void timer(MCNameRef mptr, MCParameter *params); #ifdef LEGACY_EXEC @@ -272,7 +272,6 @@ class MCPlayer : public MCControl, public MCPlayerInterface ////////// PROPERTY SUPPORT METHODS virtual void Redraw(void); - virtual void SetVisibility(MCExecContext& ctxt, uinteger_t part, bool setting, bool visible); ////////// PROPERTY ACCESSORS @@ -334,7 +333,6 @@ class MCPlayer : public MCControl, public MCPlayerInterface virtual void SetShowBorder(MCExecContext& ctxt, bool setting); virtual void SetBorderWidth(MCExecContext& ctxt, uinteger_t width); virtual void SetVisible(MCExecContext& ctxt, uinteger_t part, bool setting); - virtual void SetInvisible(MCExecContext& ctxt, uinteger_t part, bool setting); virtual void SetTraversalOn(MCExecContext& ctxt, bool setting); virtual void GetEnabledTracks(MCExecContext& ctxt, uindex_t& r_count, uinteger_t*& r_tracks); diff --git a/engine/src/scrolbar.cpp b/engine/src/scrolbar.cpp index c79aa7d7a0d..df3f3b95aae 100644 --- a/engine/src/scrolbar.cpp +++ b/engine/src/scrolbar.cpp @@ -589,7 +589,7 @@ Boolean MCScrollbar::doubleup(uint2 which) return MCControl::doubleup(which); } -void MCScrollbar::setrect(const MCRectangle &nrect) +void MCScrollbar::applyrect(const MCRectangle &nrect) { rect = nrect; compute_barsize(); diff --git a/engine/src/scrolbar.h b/engine/src/scrolbar.h index d4ce259f660..dd5fde7d058 100644 --- a/engine/src/scrolbar.h +++ b/engine/src/scrolbar.h @@ -84,7 +84,7 @@ class MCScrollbar : public MCControl virtual Boolean mup(uint2 which, bool p_release); virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); virtual void timer(MCNameRef mptr, MCParameter *params); #ifdef LEGACY_EXEC diff --git a/engine/src/stack.cpp b/engine/src/stack.cpp index 07823654886..384126d27c1 100644 --- a/engine/src/stack.cpp +++ b/engine/src/stack.cpp @@ -1233,7 +1233,7 @@ MCRectangle MCStack::getrectangle(bool p_effective) const return getwindowrect(); } -void MCStack::setrect(const MCRectangle &nrect) +void MCStack::applyrect(const MCRectangle &nrect) { // IM-2013-09-30: [[ FullscreenMode ]] allow setrect on mobile, // which now has an effect on fullscreen scaled stacks diff --git a/engine/src/stack.h b/engine/src/stack.h index b14f3ca820a..2748b1c0196 100644 --- a/engine/src/stack.h +++ b/engine/src/stack.h @@ -328,7 +328,7 @@ class MCStack : public MCObject virtual Boolean doubledown(uint2 which); virtual Boolean doubleup(uint2 which); virtual void timer(MCNameRef mptr, MCParameter *params); - virtual void setrect(const MCRectangle &nrect); + virtual void applyrect(const MCRectangle &nrect); #ifdef LEGACY_EXEC virtual Exec_stat getprop_legacy(uint4 parid, Properties which, MCExecPoint &, Boolean effective, bool recursive = false); diff --git a/engine/src/widget-ref.cpp b/engine/src/widget-ref.cpp index 13e62123c65..ce2ea519a00 100644 --- a/engine/src/widget-ref.cpp +++ b/engine/src/widget-ref.cpp @@ -210,9 +210,6 @@ bool MCWidgetBase::OnOpen(void) if (!DispatchRecursive(kDispatchOrderBeforeBottomUp, MCNAME("OnOpen"))) return false; - if (GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnOpen(); - return OnAttach(); } @@ -221,9 +218,6 @@ bool MCWidgetBase::OnClose(void) if (!OnDetach()) return false; - if (GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnClose(); - bool t_success; t_success = true; @@ -427,29 +421,16 @@ bool MCWidgetBase::OnMouseScroll(coord_t p_delta_x, coord_t p_delta_y, bool& r_b bool MCWidgetBase::OnGeometryChanged(void) { - if (GetHost() != nil && - GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnGeometryChanged(GetHost()->getrect()); - return Dispatch(MCNAME("OnGeometryChanged")); } bool MCWidgetBase::OnLayerChanged() { - if (GetHost() != nil && - GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnLayerChanged(); - return Dispatch(MCNAME("OnLayerChanged")); } bool MCWidgetBase::OnVisibilityChanged(bool p_visible) { - if (GetHost() != nil && - GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnVisibilityChanged(p_visible); - - MCAutoValueRefArray t_args; if (!t_args . New(1)) return false; @@ -469,10 +450,6 @@ bool MCWidgetBase::OnParentPropertyChanged(void) bool MCWidgetBase::OnToolChanged(Tool p_tool) { - if (GetHost() != nil && - GetHost()->getNativeLayer()) - GetHost()->getNativeLayer()->OnToolChanged(p_tool); - bool t_success; t_success = true; if (p_tool == T_BROWSE) diff --git a/engine/src/widget.cpp b/engine/src/widget.cpp index e95f6aa474e..a5a0cf5893a 100644 --- a/engine/src/widget.cpp +++ b/engine/src/widget.cpp @@ -87,7 +87,6 @@ MCWidget::MCWidget(void) m_kind = nil; m_rep = nil; m_widget = nil; - m_native_layer = nil; } MCWidget::MCWidget(const MCWidget& p_other) : @@ -96,7 +95,6 @@ MCWidget::MCWidget(const MCWidget& p_other) : m_kind = nil; m_rep = nil; m_widget = nil; - m_native_layer = nil; } MCWidget::~MCWidget(void) @@ -104,7 +102,6 @@ MCWidget::~MCWidget(void) MCValueRelease(m_widget); MCValueRelease(m_kind); MCValueRelease(m_rep); - delete m_native_layer; } void MCWidget::bind(MCNameRef p_kind, MCValueRef p_rep) @@ -160,22 +157,6 @@ bool MCWidget::visit_self(MCObjectVisitor* p_visitor) return p_visitor -> OnWidget(this); } -void MCWidget::open(void) -{ - MCControl::open(); - // IM-2015-09-01: [[ Bug 15836 ]] Only send widget event when transitioning from 0 -> 1 - if (opened == 1 && m_widget != nil) - MCwidgeteventmanager->event_open(this); -} - -void MCWidget::close(void) -{ - // IM-2015-09-01: [[ Bug 15836 ]] Only send widget event when transitioning from 1 -> 0 - if (opened == 1 && m_widget != nil) - MCwidgeteventmanager->event_close(this); - MCControl::close(); -} - void MCWidget::kfocus(void) { MCControl::kfocus(); @@ -351,17 +332,6 @@ void MCWidget::timer(MCNameRef p_message, MCParameter *p_parameters) } } -void MCWidget::setrect(const MCRectangle& p_rectangle) -{ - MCRectangle t_old_rect; - t_old_rect = rect; - - rect = p_rectangle; - - if (m_widget != nil) - MCwidgeteventmanager->event_setrect(this, t_old_rect); -} - void MCWidget::recompute(void) { if (m_widget != nil) @@ -660,26 +630,50 @@ bool MCWidget::setcustomprop(MCExecContext& ctxt, MCNameRef p_set_name, MCNameRe void MCWidget::toolchanged(Tool p_new_tool) { - if (m_widget == nil) - return; - - MCwidgeteventmanager -> event_toolchanged(this, p_new_tool); + MCControl::toolchanged(p_new_tool); + + if (m_widget != nil) + MCwidgeteventmanager -> event_toolchanged(this, p_new_tool); } void MCWidget::layerchanged() { - if (m_widget == nil) - return; - - MCwidgeteventmanager -> event_layerchanged(this); + MCControl::layerchanged(); + + if (m_widget != nil) + MCwidgeteventmanager -> event_layerchanged(this); } void MCWidget::visibilitychanged(bool p_visible) { - if (m_widget == nil) - return; - - MCwidgeteventmanager -> event_visibilitychanged(this, p_visible); + MCControl::visibilitychanged(p_visible); + + if (m_widget != nil) + MCwidgeteventmanager -> event_visibilitychanged(this, p_visible); +} + +void MCWidget::geometrychanged(const MCRectangle &p_rect) +{ + MCControl::geometrychanged(p_rect); + + if (m_widget != nil) + MCwidgeteventmanager -> event_setrect(this, p_rect); +} + +void MCWidget::OnOpen() +{ + if (m_widget != nil) + MCwidgeteventmanager -> event_open(this); + + MCControl::OnOpen(); +} + +void MCWidget::OnClose() +{ + MCControl::OnClose(); + + if (m_widget != nil) + MCwidgeteventmanager -> event_close(this); } Exec_stat MCWidget::handle(Handler_type p_type, MCNameRef p_method, MCParameter *p_parameters, MCObject *p_passing_object) @@ -904,44 +898,6 @@ void MCWidget::SetDisabled(MCExecContext& ctxt, uint32_t p_part_id, bool p_flag) recompute(); } -bool MCWidget::GetNativeView(void *&r_view) -{ - if (m_native_layer == nil) - return false; - - return m_native_layer->GetNativeView(r_view); -} - -bool MCWidget::SetNativeView(void *p_view) -{ - bool t_success; - t_success = true; - - MCNativeLayer *t_layer; - t_layer = nil; - - if (t_success && p_view != nil) - { - t_layer = MCNativeLayer::CreateNativeLayer(getwidget(), p_view); - t_success = t_layer != nil; - } - - if (t_success) - { - if (m_native_layer != nil) - delete m_native_layer; - - m_native_layer = t_layer; - if (opened && m_native_layer != nil) - { - m_native_layer->OnOpen(); - m_native_layer->OnAttach(); - } - } - - return t_success; -} - MCWidgetRef MCWidget::getwidget(void) const { return m_widget; diff --git a/engine/src/widget.h b/engine/src/widget.h index a3d26b2fc80..4c79a0d65a5 100644 --- a/engine/src/widget.h +++ b/engine/src/widget.h @@ -130,9 +130,6 @@ class MCWidget: public MCControl virtual bool visit_self(MCObjectVisitor *p_visitor); - virtual void open(void); - virtual void close(void); - virtual void kfocus(void); virtual void kunfocus(void); virtual Boolean kdown(MCStringRef p_key_string, KeySym p_key); @@ -152,7 +149,6 @@ class MCWidget: public MCControl virtual void timer(MCNameRef p_message, MCParameter *p_parameters); - virtual void setrect(const MCRectangle& p_rectangle); virtual void recompute(void); virtual Exec_stat handle(Handler_type, MCNameRef, MCParameter *, MCObject *pass_from); @@ -173,9 +169,9 @@ class MCWidget: public MCControl virtual void toolchanged(Tool p_new_tool); virtual void visibilitychanged(bool p_visible); virtual void layerchanged(); - - bool GetNativeView(void *&r_view); - bool SetNativeView(void *p_view); + virtual void geometrychanged(const MCRectangle &p_rect); + virtual void OnOpen(); + virtual void OnClose(); virtual void SetDisabled(MCExecContext& ctxt, uint32_t part, bool flag); @@ -192,12 +188,6 @@ class MCWidget: public MCControl bool isInRunMode(); - // Gets the current native layer (if any) associated with this widget - MCNativeLayer* getNativeLayer() const - { - return m_native_layer; - } - protected: static MCPropertyInfo kProperties[]; static MCObjectPropertyTable kPropertyTable; @@ -212,9 +202,6 @@ class MCWidget: public MCControl // The LCB Widget object. MCWidgetRef m_widget; - - // The native layer associated with this widget - MCNativeLayer* m_native_layer; }; ////////////////////////////////////////////////////////////////////////////////