在BREW中打造自己的GUI(7)-动态效果的实现

2023-11-23 08:08

本文主要是介绍在BREW中打造自己的GUI(7)-动态效果的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天讨论关于GUI的另一个话题:如何在两个界面切换中表现出比较炫一点的效果,比如渐变、缩放等等。同样我们还是用组件的方式来做。IGSlider,负责管理两个IControl切换的动态效果,它的使用比较简单:
static   void  loadMenu(DisplayFavt  *  pMe,uint16 wParam)
{
    TItemData    
*pData;
    IControl 
* p1,*p2;
    uint16 style;

    pData
=NULL;

       
//加载第一个IControl,即起始界面
    if(pMe->pCurrentTabOpt && pMe->pCurrentTabOpt->pMenu)
    
{
        ICONTROL_SetActive(pMe
->pCurrentTabOpt->pMenu,FALSE);
        p1
=pMe->pCurrentTabOpt->pMenu;
    }


    
//得到第二个IControl,即结束界面
    pMe->currentTab=IGTABPANECTL_GetSel(pMe->pApp->pMenuTab);
    MainItemQueue_FindById(pMe
->pApp->pTabList,pMe->currentTab,&pData);
    
if(pData==NULL)
        
return;

    IGTABPANECTL_GetItemData(pMe
->pApp->pMenuTab,pMe->currentTab,(uint32*)&pMe->pCurrentTabOpt);

    p2
=pMe->pCurrentTabOpt->pMenu;

        
//设置切换效果的风格
    
//style =(wParam==0)?0:((wParam==AVK_LEFT)?SLIDER_STYLE_RTOL:SLIDER_STYLE_LTOR);
    style=(wParam==0)?0:SLIDER_STYLE_DTOB;

    
if(p1 && p2 && style!=0)
    
{
        AEERect rec;
        SET_CTL_RECT(
&rec);
                
//两个界面应该同样大小
        IGSLIDER_SetRect(pMe->pApp->pSlider,&rec);
                
//将两个界面IControl加入IGSlider
        if(IGSLIDER_AddControls(pMe->pApp->pSlider,p1,p2))
        
{
                        
//初始化,设置回调、风格、动态效果显示时长
            IGSLIDER_Init(pMe->pApp->pSlider,style,3,(PFNNOTIFY)loadMenuDone,(void*)pMe);
                        
//启动
            IGSLIDER_Start(pMe->pApp->pSlider);
            
return;
        }

    }


    
{
        ICONTROL_SetActive((IControl
*)pMe->pCurrentTabOpt->pMenu,TRUE);
        ICONTROL_Redraw(pMe
->pCurrentTabOpt->pMenu);
        pMe
->pApp->state=STATE_COMMAND;
    }


}

原理比较简单:
1、我们要将两个 IControl绘入两个IBitmap中,然后才能进行各种图像操作(渐变、淡化、缩放等)。
2、用一个定时器来控制这个切换时的效果显示。
3、需要一个回调函数,在完成切换时需要调一下它,来处理善后事项。

先看看这个组件包含的成员,如上所述,除了两个ICotrol和两个IBitmap以外,还要那个回调m_cbDone、风格m_style、时间控制m_delay等等。
struct  _IGSlider  {
    
    
const AEEVTBL(IGSlider) * pvt;

    uint32          m_nRefs;    
    IShell            
*m_pIShell;
    IDisplay        
*m_pIDisplay;
    IModule            
*m_pIModule;

    IControl        
*m_pFirst;
    IControl        
*m_pSecond;

    
int                m_delay;
    
int                m_style;

    boolean            m_isActive;

    PFNNOTIFY        m_cbDone;
    
void           *m_pNotifyData;
    AEERect            m_Rect;

    IBitmap            
*pFirst;
    IBitmap            
*pSecond;
    
int                tick;
    uint8            flag;

    IBitmap            
*pTemp;

}
;

然后需要声明的接口函数包括以下几个:
AEEINTERFACE(IGSlider)
{
    DECLARE_IBASE(IGSlider)    

    boolean     (
*Redraw)       (IGSlider * po);
    
void        (*SetRect)      (IGSlider * po, const AEERect *);

    boolean        (
*AddControls)  (IGSlider * po, IControl * p1,IControl * p2);
    boolean        (
*AddControlsD) (IGSlider * po, IControl * p1,IControl * p2);
    boolean        (
*AddControlFrom)    (IGSlider * po,IControl * p1);
    boolean        (
*AddControlTo)        (IGSlider * po,IControl * p2);
    boolean        (
*AddControlFromBitmap)    (IGSlider * po,IBitmap * p1);
    boolean        (
*AddControlToBitmap)        (IGSlider * po,IBitmap * p2);

    IBitmap
*        (*GetBitmapFirst)        (IGSlider * po);
    IBitmap
*        (*GetBitmapSecond)        (IGSlider * po);
    
    boolean        (
*IsActive)        (IGSlider * po);
    
void        (*Init)            (IGSlider * po, uint16 style,uint32 delay,PFNNOTIFY cbDone,void * pUser);
    
void        (*Start)        (IGSlider * po);
    
void        (*Stop)            (IGSlider * po);
    
}
;

实现方面主要是这个addControls函数,在加入两个ICotrol同时,将它绘制到IBitmap上去。
static  boolean IGSlider_AddControls(IGSlider  *  pMe,IControl  *  p1,IControl  *  p2)
{

    AEERect        r;

    
if(SUCCESS!=IDISPLAY_SetDestination(pMe->m_pIDisplay,pMe->pFirst))
        
return FALSE;

    SETAEERECT(
&r,0,0,pMe->m_Rect.dx,pMe->m_Rect.dy);
    ICONTROL_SetRect(p1,
&r);
    ICONTROL_Redraw(p1);
    IDISPLAY_Update(pMe
->m_pIDisplay);
    ICONTROL_SetRect(p1,
&pMe->m_Rect);

    
if(SUCCESS!=IDISPLAY_SetDestination(pMe->m_pIDisplay,pMe->pSecond))
        
return FALSE;
    
    SETAEERECT(
&r,0,0,pMe->m_Rect.dx,pMe->m_Rect.dy);
    ICONTROL_SetRect(p2,
&r);
    ICONTROL_Redraw(p2);
    IDISPLAY_Update(pMe
->m_pIDisplay);
    ICONTROL_SetRect(p2,
&pMe->m_Rect);

    IDISPLAY_SetDestination(pMe
->m_pIDisplay,NULL);
    
    
return TRUE;
}

启动效果切换的工作是根据当前设置的风格调用不同的图像处理函数,还要提供一个停止函数来随时中止效果变化(其实就是Cancel掉定时器罢了)。
static   void  IGSlider_Start(IGSlider  *  pMe)
{
    pMe
->tick = 0;
    pMe
->flag=0;
    pMe
->m_isActive=TRUE;    
    
    
if(pMe->m_style==SLIDER_STYLE_RTOL)
        drawRTOL(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_LTOR)
        drawLTOR(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_DARK)
        drawDARK(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_BRIT)
        drawBRIT(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_SIZE)
        drawSize(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_GRID)
        drawGRID(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_SIZE2)
        drawSize2(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_LTORD)
        drawLTORD(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_RTOLD)
        drawRTOLD(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_BTOT)
        drawBTOT(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_TTOB)
        drawTTOB(pMe);
    
else if(pMe->m_style==SLIDER_STYLE_DTOB)
        drawDTOB(pMe);

}

static   void  IGSlider_Stop(IGSlider  *  pMe)
{
    pMe
->m_isActive=FALSE;
    ISHELL_CancelTimer(pMe
->m_pIShell,NULL,(void*)pMe);

}

各种效果的实现并不复杂,去google一下就能得到很多图像处理方法了。下面给出两个典型的处理,一是由暗变亮的实现,即第一个界面由亮变暗而第二个界面由暗变亮。
static   void  drawDTOB(IGSlider  *  pMe)
{
    ITransform    
*pTransform;
    AEEBitmapInfo inf;
    IBitmap 
*bmp;
    AEETransformMatrix matrix;
    
int x,y;

    pMe
->tick++;

    IBITMAP_SetTransparencyColor(pMe
->pFirst,MAKE_RGB(0,0,0));
    
if(pMe->flag==0)
    
{
        IBITMAP_GetInfo(pMe
->pFirst,&inf,sizeof(AEEBitmapInfo));
        
for(x=0;x<inf.cx;x++)
            
for(y=0;y<inf.cy;y++)
            
{
                NativeColor tc;
                RGBVAL ocolor,ncolor;

                IBITMAP_GetPixel(pMe
->pFirst,x,y,&tc);
                ocolor
=IBITMAP_NativeToRGB(pMe->pFirst,tc);
                ncolor 
= __transColor(pMe,ocolor,-50);
                tc
= IBITMAP_RGBToNative(pMe->pFirst,ncolor);
                IBITMAP_DrawPixel(pMe
->pFirst,x,y,tc,AEE_RO_COPY);
            }

        IDISPLAY_BitBlt(pMe
->m_pIDisplay,pMe->m_Rect.x,pMe->m_Rect.y,pMe->m_Rect.dx,pMe->m_Rect.dy,pMe->pFirst,0,0,AEE_RO_TRANSPARENT);
        IDISPLAY_Update(pMe
->m_pIDisplay);

        
if(pMe->tick<pMe->m_delay)
            ISHELL_SetTimer(pMe
->m_pIShell,5,(PFNNOTIFY)drawDTOB,(void*)pMe);
        
else
        
{
            pMe
->flag=1;
            pMe
->tick=1;            
        }

        
    }

    
    
if(pMe->flag==1)
    
{
        IBITMAP_GetInfo(pMe
->pSecond,&inf,sizeof(AEEBitmapInfo));

        
if(pMe->pTemp)
            IBITMAP_Release(pMe
->pTemp);
        IBITMAP_CreateCompatibleBitmap(pMe
->pSecond,&pMe->pTemp,inf.cx,inf.cy);

        
for(x=0;x<inf.cx;x++)
            
for(y=0;y<inf.cy;y++)
            
{
                NativeColor tc;
                RGBVAL ocolor,ncolor;

                IBITMAP_GetPixel(pMe
->pSecond,x,y,&tc);
                ocolor
=IBITMAP_NativeToRGB(pMe->pSecond,tc);
                ncolor 
= __transColor(pMe,ocolor,-50*(pMe->m_delay-pMe->tick));
                tc
= IBITMAP_RGBToNative(pMe->pSecond,ncolor);
                IBITMAP_DrawPixel(pMe
->pTemp,x,y,tc,AEE_RO_COPY);
            }

        IDISPLAY_BitBlt(pMe
->m_pIDisplay,pMe->m_Rect.x,pMe->m_Rect.y,pMe->m_Rect.dx,pMe->m_Rect.dy,pMe->pTemp,0,0,AEE_RO_TRANSPARENT);
        IDISPLAY_Update(pMe
->m_pIDisplay);

        
if(pMe->tick<pMe->m_delay)
            ISHELL_SetTimer(pMe
->m_pIShell,5,(PFNNOTIFY)drawDTOB,(void*)pMe);
        
else
        
{
            pMe
->m_isActive=FALSE;
        
            
if(pMe->m_cbDone)
                pMe
->m_cbDone(pMe->m_pNotifyData);        
        }

    }

}

还有一个上下滑动效果的实现,即第两个界面由上向下将第一个界面推出屏幕:
static   void  drawBTOT(IGSlider  *  pMe)
{
    pMe
->tick+=pMe->m_Rect.dy/pMe->m_delay;

    
if(pMe->tick<pMe->m_Rect.dy)
    
{
        IDISPLAY_BitBlt(pMe
->m_pIDisplay,pMe->m_Rect.x,pMe->m_Rect.y,pMe->m_Rect.dx,(pMe->m_Rect.dy-pMe->tick),pMe->pFirst,0,pMe->tick,AEE_RO_COPY);
        IDISPLAY_BitBlt(pMe
->m_pIDisplay,pMe->m_Rect.x,pMe->m_Rect.y+(pMe->m_Rect.dy-pMe->tick),pMe->m_Rect.dx,pMe->tick,pMe->pSecond,0,0,AEE_RO_COPY);

        IDISPLAY_Update(pMe
->m_pIDisplay);
        
if(pMe->tick<pMe->m_Rect.dy*1/3)
            ISHELL_SetTimer(pMe
->m_pIShell,10,(PFNNOTIFY)drawBTOT,(void*)pMe);
        
else if(pMe->tick<pMe->m_Rect.dy*2/3)
            ISHELL_SetTimer(pMe
->m_pIShell,50,(PFNNOTIFY)drawBTOT,(void*)pMe);
        
else
            ISHELL_SetTimer(pMe
->m_pIShell,10,(PFNNOTIFY)drawBTOT,(void*)pMe);
    }

    
else
    
{
        pMe
->m_isActive=FALSE;
        
if(pMe->m_cbDone)
            pMe
->m_cbDone(pMe->m_pNotifyData);
    }


}


这篇关于在BREW中打造自己的GUI(7)-动态效果的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/416519

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现