zoukankan      html  css  js  c++  java
  • 构思一个在windows下仿objc基于动画层ui编程的ui引擎

    用c/c++编程有些年了,十个指头可以数齐,在涉入iOS objc开发后,有种无比舒服的感觉,尤其在UI开发上。

    在QuartzCore.framework下动画和透明窗口等许多效果的事都变得那么方便和自然。因为在windows窗口机制中没有动画和透明窗口(Aero 除外)等效果的引擎层,还有GDI中不支持ARGB,开发中都要依靠不断重复而且大量的BitBlt和Timer来完成,工作量与开发iOS不可比。

    大体上就是尝试引入UIKit.framework那样的编程体验。首先要有QuartzCore.framework的CALayer和CATransition,以及objc的NSObject支持。

    第一阶段已经完成了下面些基本功能:

    NSObject.h,

    NSObjectRuntime.h, (obj_class)

    NSAutoreleasePool.h,

    NSArrary,

    CALayer.h,

    CGContext.h,

    CGAffineTransform.h,

    CAAnimation.h,

    CoreGraphics.h(CGPoint等的定义)

    因为不是objc,runtime中的实现的是obj_class而不是objc_class。

    现阶段可以在windows窗口中组建层动画。

    代码风格如下:

    _testLayer = NSObject::allocT<CATestLayer>();
    _testLayer->setFrame(CGRect(20.f, 100.f, 40.f, 40.f));
    _testLayer->set_backgroundColor(CGColor(CGColor::Pink));
    _normalLayer = NSObject::allocT<CALayer>();
    _normalLayer->setFrame(CGRect(20.f, 500.f, 40.f, 40.f));
    _normalLayer->set_backgroundColor(CGColor(CGColor::Pink));
    CATestLayer* _testLayer2 = (CATestLayer*) NSObject::allocT<CATestLayer>()->autorelease();
    _testLayer2->setFrame(CGRect(5.f, 5.f, 10.f, 10.f));
    _testLayer2->set_backgroundColor(CGColor(123, 24, 53));
    _normalLayer->addSublayer(_testLayer2);
    
    ::isKindOfClass<CALayer>(_testLayer2);
    ::isKindOfClass<NSArray>(_testLayer2);            

    投递动画:

    { _0_autoreleasepool 
        _normalLayer->setFrame(CGRect(20.f, 500.f, 40.f, 40.f));
        _normalLayer->setTransform(CGAffineTransform());
        ::CAAnimation* anime = CAAnimation::beginAnimating(_normalLayer, 1.f);
        {
            anime->setFrame(CGRect(320.f, 500.f, 20.f, 20.f));
            anime->translate(0.f, -100.f);
            anime->rotate(360.f);
            anime->commit();
        }
         _1_autoreleasepool                                                
    }
    View Code

    类定义:

    class CALayer : public NSObject
    {
    public:
        virtual ~CALayer();
        CALayer();
    
        void setNeedslayout();
        BOOL needsLayout();
        void layoutIfNeeded();
        virtual void layoutSublayers();
    
        void display(CGContext* ctx);
        virtual void drawInContext(CGContext* ctx);
        void renderInContext(CGContext* ctx);
    
        void addSublayer(CALayer* layer);
    private:
        virtual void applyAnimating();
    
    protected:
        _0_property_setter01(setFrame,                    CGRect, frame);
        _0_property_setter01(setBounds,                    CGRect, bounds);
        _0_property_setter(setAnchorPoint,                CGPoint, anchorPoint);
        _0_property_setter(setZPosition,                CGFloat, zPosition);
        //_0_property_pri_pwi_pti(public:, transform, ;, public:, setTransform, ;, protected:,        CGAffineTransform, transform);
        _0_property_setter(setTransform,                CGAffineTransform, transform);
        _0_property_getset(isHidden,setHidden,            BOOL, hidden);
        _0_property_assign2(setSuperLayer,                CALayer*, superLayer);
        _0_property_retain2(setSublayers,                NSArray*, sublayers);
        _0_property_retain2(setMask,                    CALayer*, mask);            // no impl
        _0_property_getset(isMaskToBounds, setMaskToBounds, BOOL, maskToBounds);        // no impl
    #ifdef CALAYER_IMPL_CONTENTS
        NSObject* _contents;    // no impl
        CGRect _contentRect;
        NSString* _contentsGravity;
        CGFloat _contentScale;
        CGFloat _contentConter;
    #endif
        _0_property_getset(isOpaque, setOpaque,            BOOL, opaque);
        _0_property_getter(isNeedsDisplayOnBoundsChange, BOOL, needsDisplayOnBoundsChange);
        _0_property_getter(isDrawsAsynchronously,        BOOL, drawsAsynchronously);    // no impl
        _0_property(CGColor, backgroundColor);
        _0_property(CGColor, cornerRadius);
        _0_property(CGFloat, borderWidth);
        _0_property(CGColor, borderColor);
        _0_property(CGFloat, opacity);
        _0_property_setter(isAllowsGroupOpacity,        BOOL, allowsGroupOpacity);
        _0_property_retain2(setFilters,                    NSArray*, filters);
        _0_property_retain2(setBackgroundFilters,        NSArray*, backgroundFilters);
        _0_property_setter(isShouldRasterize,            BOOL, shouldRasterize);
        _0_property(CGFloat, rasterizationScale);
        _0_property(CGColor, shadowColor);
        _0_property(CGFloat, shadowOpacity);
        _0_property(CGFloat, shadowRadius);

    1.由NSObject继承下来的类不能显式调用new, delete。必须通过模板NSObject::allocTx<typename T>(...)来分配对象,以及release()或autorelease()成员函数来释放。但是由于不是采用COM接口方式(接口和实现完全分离,工厂类构建对象返回接口),没有办法防止在局部和全局中构建对象。

    2.支持autorelease(),以及局部范围内的autorelease()。

    3.支持仿射变换,子层model变换坐标。

    4.支持isKindOfClass方法,可以帮助按正确类型访问NSArray等容器中元素。

    5.支持层与层之间的opaque,以及ARGB颜色。

    下一阶段准备要引入UIView和UIViewController, FisrtResponder这些概念。完成一些像NSString, NSDictionary等基本功能类。

     ps: 代码中_0_property_xxx是自动完成getter和setter的宏,因为宏定义不允许使用字母"@"只好用"_0_"来代替。

      时下像迅雷的UI开发库已经很多很好,本作只是兴趣和用于个人功底自我修炼。

    ps@20200508:

    构思阶段的代码在 https://github.com/bbqz007/xw

     自己用引擎做了两个demo

          1. 各种层动画效果示例

          2. 仿QQ管家悬浮窗口

    逆向深入objc,c++ windows下仿objc动画层UI引擎
  • 相关阅读:
    vue过滤器filters
    vue指令
    java命令
    mysql的information_schema表
    es6 Object的keys values entries方法
    mysql information_schema.INNODB_TRX
    流动相似性例子
    【转】time 模块详解(时间获取和转换)
    查找——平衡二叉树的实现(代码超详细注释)
    py中变量名的“秘密”
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/5064087.html
Copyright © 2011-2022 走看看