modify toolbar,add FPS Banner to SurfaceComposer,fix some memleak

This commit is contained in:
侯歌 2022-03-23 17:40:45 +08:00
parent d89fcb74ec
commit 619ae65983
27 changed files with 440 additions and 176 deletions

View File

@ -85,8 +85,8 @@ App::App(int argc,const char*argv[],const struct option*extoptions){
addEventHandler(inputsource);
inputsource->playback(getArg("monkey",""));
signal(SIGINT,[](int){
LOGD("sigint...");
signal(SIGTERM,[](int){
LOGD("SIGTERM...");
App::mInst->mQuitFlag = true;
});
}
@ -96,8 +96,8 @@ App::~App(){
WindowManager::getInstance().shutDown();
delete Looper::getDefault();
delete &GraphDevice::getInstance();
exit(mExitCode);
LOGD("%p Destroied",this);
exit(mExitCode);
}
const std::string App::getDataPath()const{

16
src/gui/core/assets.cc Normal file → Executable file
View File

@ -34,11 +34,13 @@ Assets::~Assets(){
for(auto it=mResources.begin();it!=mResources.end();it++){
delete it->second;
}
mResources.clear();
//for(auto d:mDrawables) d.second = nullptr;
mDrawables.clear();
printf(" assets destroied\r\n");
LOGD("%p Destroied",this);
mIDS.clear();
mResources.clear();
mStrings.clear();
mStyles.clear();
std::cout<<" Assets destroied!"<<std::endl;
}
const DisplayMetrics& Assets::getDisplayMetrics(){
@ -211,7 +213,7 @@ void Assets::loadStrings(const std::string&lan){
Json::parseFromStream(builder,*zipis,&root,&errs);
Json::Value::Members mems=root.getMemberNames();
for(auto m:mems){
strings[m]=root[m].asString();
mStrings[m]=root[m].asString();
}
delete zipis;
}
@ -250,8 +252,8 @@ const std::string& Assets::getString(const std::string& id,const std::string&lan
if((!lan.empty())&&(mLanguage!=lan)){
loadStrings(lan);
}
auto itr=strings.find(id);
if(itr!=strings.end()&&!itr->second.empty()){
auto itr=mStrings.find(id);
if(itr !=mStrings.end()&&!itr->second.empty()){
return itr->second;
}
return id;

2
src/gui/core/assets.h Normal file → Executable file
View File

@ -15,7 +15,7 @@ private:
std::string mDefault;//default resource
std::string mThemeName;
AttributeSet mTheme;
std::map<const std::string,std::string>strings;
std::map<const std::string,std::string>mStrings;
std::map<const std::string,int>mIDS;
std::map<const std::string,std::vector<std::string>>mArraies;
std::map<const std::string,std::weak_ptr<Drawable::ConstantState>>mDrawables;

19
src/gui/core/attributeset.cc Normal file → Executable file
View File

@ -42,7 +42,7 @@ std::string AttributeSet::normalize(const std::string&pkg,const std::string&prop
}
if( (value.find(':')==std::string::npos) && (value.find('/')!=std::string::npos) ){
value= pkg+":"+value;
return std::string(pkg+":"+value);
}
return value;
}
@ -52,13 +52,13 @@ int AttributeSet::set(const char*atts[],int size){
for(int i=0;atts[i]&&(size==0||i<size);i+=2,rc+=1){
const char* key=strrchr(atts[i],' ');
if(key)key++;else key=atts[i];
mAttrs.insert(std::make_pair<const std::string,std::string>
mAttrs.insert(std::make_pair<std::string,std::string>
(std::string(key),normalize(mPackage,std::string(atts[i+1]))));
}
return mAttrs.size();
}
std::map<const std::string,std::string>&AttributeSet::getEntries(){
std::map<std::string,std::string>&AttributeSet::getEntries(){
return mAttrs;
}
@ -66,7 +66,7 @@ int AttributeSet::inherit(const AttributeSet&other){
int inheritedCount=0;
for(auto it=other.mAttrs.begin();it!=other.mAttrs.end();it++){
if(mAttrs.find(it->first)==mAttrs.end()){
mAttrs.insert(std::make_pair<const std::string,std::string>
mAttrs.insert(std::make_pair<std::string,std::string>
(it->first.c_str(),normalize(mPackage,it->second)));
inheritedCount++;
}
@ -76,11 +76,12 @@ int AttributeSet::inherit(const AttributeSet&other){
bool AttributeSet::add(const std::string&key,const std::string&value){
if(mAttrs.find(key)!=mAttrs.end())
return false;
const char*ks=strrchr(key.c_str(),' ');
if(ks)ks++;else ks=key.c_str();
mAttrs.insert(std::make_pair<const std::string,std::string>
(std::string(ks),normalize(mPackage,value)));
return false;
std::string ks = key;
size_t pos =ks.find(' ');
if(pos!=std::string::npos)ks=ks.substr(pos+1);
mAttrs.insert(std::make_pair<std::string,std::string>
((std::string)ks,normalize(mPackage,value)));
return true;
}

4
src/gui/core/attributeset.h Normal file → Executable file
View File

@ -7,7 +7,7 @@ class AttributeSet{
private:
std::string mPackage;
class Context*mContext;
std::map<const std::string,std::string>mAttrs;
std::map<std::string,std::string>mAttrs;
public:
AttributeSet();
AttributeSet(Context*ctx,const std::string&package);
@ -17,7 +17,7 @@ public:
int size()const;
int set(const char*atts[],int size=0);
static std::string normalize(const std::string&pkg,const std::string&property);
std::map<const std::string,std::string>&getEntries();
std::map<std::string,std::string>&getEntries();
int inherit(const AttributeSet&other);
const std::string getAttributeValue(const std::string&key)const;
bool getBoolean(const std::string&key,bool def=false)const;

9
src/gui/core/color.cc Normal file → Executable file
View File

@ -1,5 +1,7 @@
#include <color.h>
#include <map>
#include <mutex>
#include <iostream>
namespace cdroid{
static std::map<const std::string ,unsigned int>sColorNameMap={
{"aquamarine",0xFF7FFFD4}, {"beige" , 0xFFF5F5DC}, {"black" , 0xFF000000}, {"blue" , 0xFF0000FF},
@ -70,6 +72,13 @@ unsigned int Color::parseColor(const std::string& colorString){
unsigned int Color::getHtmlColor(const std::string&colorname){
auto it=sColorNameMap.find(colorname);
static std::once_flag sInit;
std::call_once(sInit,[&](){
atexit([](){
sColorNameMap.clear();
std::cout<<"sColorNameMap.cleared"<<std::endl;
});
});
if(it== sColorNameMap.end())return -1;
return it->second;
}

View File

@ -12,6 +12,8 @@
#include <pixman.h>
#include <systemclock.h>
#include <thread>
#include <sys/time.h>
#include <sys/resource.h>
using namespace Cairo;
@ -39,12 +41,16 @@ GraphDevice::GraphDevice(int fmt){
GFXCreateSurface(&mPrimarySurface,mScreenWidth,mScreenHeight,mFormat,1);
GFXLockSurface(mPrimarySurface,(void**)&buffer,&pitch);
GFXCreateSurface(&mBannerSurface,200,40,mFormat,0);
mLastComposeTime = SystemClock::uptimeMillis();
LOGD("PrimarySurface=%p size=%dx%d",mPrimarySurface,mScreenWidth,mScreenHeight);
RefPtr<Surface>surf=ImageSurface::create(buffer,Surface::Format::ARGB32,mScreenWidth,mScreenHeight,pitch);
mPrimaryContext = new Canvas(surf);
mRectBanner.set(0,0,400,40);
mBannerContext = new Canvas(mRectBanner.width,mRectBanner.height);
mBannerSurface = mBannerContext->mHandle;
mLastComposeTime = SystemClock::uptimeMillis();
mInvalidateRgn = Region::create();
mComposing = 0;
mQuitFlag = false;
@ -84,10 +90,19 @@ void GraphDevice::trackFPS() {
long totalTime = nowTime - mFpsStartTime;
mFpsPrevTime = nowTime;
if (totalTime > 1000) {
float fps = (float) mFpsNumFrames * 1000 / totalTime;
LOGV("\tFPS:%f",fps);
const float fps = (float) mFpsNumFrames * 1000 / totalTime;
mFpsStartTime = nowTime;
mFpsNumFrames = 0;
std::string fpsText = std::to_string(fps);
Cairo::Context::Operator oop = mBannerContext->get_operator();
mBannerContext->set_operator(Cairo::Context::Operator::SOURCE);
mBannerContext->set_source_rgba(0,0,0,.5);
mBannerContext->rectangle(0,0,mRectBanner.width,mRectBanner.height);
mBannerContext->fill();
mBannerContext->set_operator(oop);
mBannerContext->set_source_rgb(1,1,1);
mBannerContext->set_font_size(22);
mBannerContext->draw_text(mRectBanner,fpsText,DT_CENTER);
}
}
}
@ -208,6 +223,9 @@ void GraphDevice::composeSurfaces(){
LOGV("%d:(%d,%d,%d,%d)",i,r.x,r.y,r.width,r.height);
}
mInvalidateRgn->do_xor(mInvalidateRgn);
if(mPrimarySurface&&mBannerSurface){
GFXBlit(mPrimarySurface,mScreenWidth-mRectBanner.width,mScreenHeight-mRectBanner.height,mBannerSurface,nullptr);
}
GFXFlip(mPrimarySurface);
t2=SystemClock::uptimeMillis();
mLastComposeTime = SystemClock::uptimeMillis();

View File

@ -20,6 +20,7 @@ private:
uint64_t mFpsStartTime;
uint64_t mFpsPrevTime;
uint64_t mFpsNumFrames;
Rect mRectBanner;
std::mutex mMutex;
std::condition_variable mCV;
HANDLE mPrimarySurface;

6
src/gui/core/inputmethodmanager.cc Normal file → Executable file
View File

@ -175,9 +175,9 @@ InputMethodManager::~InputMethodManager(){
delete kcm;
LOGD("InputMethodManager Destroied!");
if(imeWindow)WindowManager::getInstance().removeWindow(imeWindow);
for_each(imemethods.begin(),imemethods.end(),[](std::map<std::string,InputMethod*>::reference it){
delete it.second;
});
for(auto ime:imemethods){
delete ime.second;
}
imemethods.erase(imemethods.begin(),imemethods.end());
}

12
src/gui/view/layoutinflater.cc Normal file → Executable file
View File

@ -19,6 +19,18 @@ LayoutInflater*LayoutInflater::from(Context*context){
if(it==mMaps.end()){
LayoutInflater*flater=new LayoutInflater(context);
it=mMaps.insert(std::pair<Context*,LayoutInflater*>(context,flater)).first;
if(mMaps.size()==1){
atexit([](){
INFLATERMAPPER& fmap=LayoutInflater::getInflaterMap();
STYLEMAPPER& smap=getStyleMap();
fmap.clear();
smap.clear();
for(auto m:mMaps)
delete m.second;
mMaps.clear();
std::cout<<"LayoutInflater::Destroied!"<<std::endl;
});
}
}
return it->second;
}

118
src/gui/view/menu.h Normal file → Executable file
View File

@ -9,72 +9,78 @@ class SubMenu;
class MenuItem;
class Menu{
protected:
std::vector<MenuItem*>mMenuItems;
void *owner;/*menu owner/container*/
std::vector<MenuItem*>mMenuItems;
void *owner;/*menu owner/container*/
public:
Menu();
~Menu();
MenuItem& add(const std::string&title);
MenuItem& add(int groupId, int itemId, int order,const std::string&title);
SubMenu& addSubMenu(const std::string&title);
SubMenu& addSubMenu(int groupId,int itemId,int order,const std::string& title);
void popup(int x,int y);
void close();
void removeItem(int id);
void removeGroup(int groupId);
void clear();
void setGroupCheckable(int group, bool checkable, bool exclusive);
void setGroupEnabled(int group, bool enabled);
bool hasVisibleItems()const;
MenuItem*findItem(int id)const;
int size()const;
virtual MenuItem* getItem(int index)const;
Menu();
~Menu();
MenuItem& add(const std::string&title);
MenuItem& add(int groupId, int itemId, int order,const std::string&title);
SubMenu& addSubMenu(const std::string&title);
SubMenu& addSubMenu(int groupId,int itemId,int order,const std::string& title);
void popup(int x,int y);
void close();
void removeItem(int id);
void removeGroup(int groupId);
void clear();
void setGroupCheckable(int group, bool checkable, bool exclusive);
void setGroupEnabled(int group, bool enabled);
bool hasVisibleItems()const;
MenuItem*findItem(int id)const;
int size()const;
virtual MenuItem* getItem(int index)const;
};
class MenuItem{
protected:
std::string mTitle;
std::string mTooltip;
int mItemId;
int mGroupId;
int mOrder;
bool mCheckable;
bool mChecked;
bool mVisible;
bool mEnabled;
RefPtr<ImageSurface>mIcon;
SubMenu*mSubMenu;
friend class Menu;
public:
MenuItem();
MenuItem& setEnabled(bool v);
MenuItem& setVisible(bool v);
MenuItem& setTitle(const std::string&);
std::string getTitle()const{return mTitle;}
MenuItem& setTooltipText(const std::string&tips);
std::string getTooltipText()const{return mTooltip;}
SubMenu* getSubMenu()const;
bool hasSubMenu()const;
DECLARE_UIEVENT(void,OnMenuItemClickListener,MenuItem&);
struct OnActionExpandListener{
CallbackBase<bool,MenuItem&>onMenuItemActionExpand;
CallbackBase<bool,MenuItem&>onMenuItemActionCollapse;
};
protected:
std::string mTitle;
std::string mTooltip;
int mItemId;
int mGroupId;
int mOrder;
bool mCheckable;
bool mChecked;
bool mVisible;
bool mEnabled;
RefPtr<ImageSurface>mIcon;
SubMenu*mSubMenu;
friend class Menu;
public:
MenuItem();
MenuItem& setEnabled(bool v);
MenuItem& setVisible(bool v);
MenuItem& setTitle(const std::string&);
std::string getTitle()const{return mTitle;}
MenuItem& setTooltipText(const std::string&tips);
std::string getTooltipText()const{return mTooltip;}
SubMenu* getSubMenu()const;
bool hasSubMenu()const;
bool isEnabled()const{return mEnabled;}
bool isVisible()const{return mVisible;}
bool isCheckable()const{return mCheckable;}
bool isChecked()const{return mChecked;}
int getGroupId()const{return mGroupId;}
int getItemId()const{return mItemId;}
int getOrder()const{return mOrder;}
bool isEnabled()const{return mEnabled;}
bool isVisible()const{return mVisible;}
bool isCheckable()const{return mCheckable;}
bool isChecked()const{return mChecked;}
int getGroupId()const{return mGroupId;}
int getItemId()const{return mItemId;}
int getOrder()const{return mOrder;}
};
class SubMenu:public Menu{
public:
SubMenu& setHeaderTitle(const std::string&);
SubMenu& setHeaderIcon(const std::string&iconRes);
SubMenu& setHeaderIcon(Drawable*);
SubMenu& setHeaderView(View*);
void clearHeader();
SubMenu& setIcon(const std::string&iconRes);
SubMenu& setIcon(Drawable*);
MenuItem*getItem()const;
SubMenu& setHeaderTitle(const std::string&);
SubMenu& setHeaderIcon(const std::string&iconRes);
SubMenu& setHeaderIcon(Drawable*);
SubMenu& setHeaderView(View*);
void clearHeader();
SubMenu& setIcon(const std::string&iconRes);
SubMenu& setIcon(Drawable*);
MenuItem*getItem()const;
};
}

View File

@ -1,4 +1,4 @@
#include <widget/swipehelper.h>
#include <view/swipehelper.h>
#include <core/systemclock.h>
#include <private/windowmanager.h>
#include <cdlog.h>

1
src/gui/view/velocitytracker.cc Normal file → Executable file
View File

@ -997,6 +997,7 @@ float VelocityTracker::getXVelocity(int id){
float VelocityTracker::getYVelocity(){
return getYVelocity(ACTIVE_POINTER_ID);
}
float VelocityTracker::getYVelocity(int id){
float vy;
getVelocity(id, nullptr, &vy);

23
src/gui/view/view.cc Normal file → Executable file
View File

@ -6364,27 +6364,4 @@ View::AttachInfo::AttachInfo(){
mViewRequestingLayout = nullptr;
}
std::vector<View::AttachInfo::InvalidateInfo*>View::AttachInfo::sPool;
View::AttachInfo::InvalidateInfo* View::AttachInfo::InvalidateInfo::obtain(){
InvalidateInfo*info=nullptr;
if(sPool.size()==0){
info= new InvalidateInfo();
}else{
info = sPool.back();
sPool.pop_back();
}
return info;
}
void View::AttachInfo::InvalidateInfo::recycle(){
if(sPool.size()<POOL_LIMIT ){
target = nullptr;
rect.set(0,0,0,0);
sPool.push_back(this);
}else{
delete this;
}
}
}//endof namespace

11
src/gui/view/view.h Normal file → Executable file
View File

@ -157,17 +157,6 @@ protected:
};
class AttachInfo{
public:
class InvalidateInfo{
public:
View* target;
Rect rect;
static InvalidateInfo*obtain();
void recycle();
};
private:
static const int POOL_LIMIT = 64;
static std::vector<InvalidateInfo*>sPool;
public:
View*mRootView;
bool mHardwareAccelerated;

View File

@ -318,6 +318,10 @@ void AbsListView::initAbsListView(const AttributeSet&atts) {
}
AbsListView::~AbsListView(){
if(mVelocityTracker){
mVelocityTracker->recycle();
mVelocityTracker = nullptr;
}
delete mSelector;
delete mFastScroll;
delete mRecycler;

View File

@ -6,6 +6,7 @@
namespace cdroid{
class DataSetObserver{
public:
virtual ~DataSetObserver()=default;
virtual void onChanged()=0;
virtual void onInvalidated()=0;
virtual void clearSavedState()=0;

36
src/gui/widget/cdwindow.cc Normal file → Executable file
View File

@ -22,7 +22,7 @@
#include <expat.h>
#include <systemclock.h>
#include <widget/measurespec.h>
#include <widget/swipehelper.h>
#include <view/swipehelper.h>
#include <fstream>
namespace cdroid {
@ -380,9 +380,9 @@ void Window::InvalidateOnAnimationRunnable::setOwner(Window*w){
mOwner=w;
}
std::vector<View::AttachInfo::InvalidateInfo*>::iterator Window::InvalidateOnAnimationRunnable::find(View*v){
std::vector<Window::InvalidateInfo>::iterator Window::InvalidateOnAnimationRunnable::find(View*v){
for(auto it=mInvalidateViews.begin();it!=mInvalidateViews.end();it++){
if((*it)->target == v)
if((*it).target == v)
return it;
}
return mInvalidateViews.end();
@ -391,28 +391,28 @@ std::vector<View::AttachInfo::InvalidateInfo*>::iterator Window::InvalidateOnAni
void Window::InvalidateOnAnimationRunnable::addView(View* view){
auto it=find(view);
if(it==mInvalidateViews.end()){
AttachInfo::InvalidateInfo*info = AttachInfo::InvalidateInfo::obtain();
info->target = view;
info->rect.set(0,0,0,0);
InvalidateInfo info;
info.target = view;
info.rect.set(0,0,0,0);
mInvalidateViews.push_back(info);
}else{
(*it)->rect.set(0,0,0,0);
InvalidateInfo& info=(*it);
info.rect.set(0,0,0,0);
}
postIfNeededLocked();
}
void Window::InvalidateOnAnimationRunnable::addViewRect(View* view,const Rect&rect){
auto it=find(view);
AttachInfo::InvalidateInfo*info=nullptr;
if(it == mInvalidateViews.end()){
info = AttachInfo::InvalidateInfo::obtain();
info->target =view;
info->rect = rect;
InvalidateInfo info;
info.target =view;
info.rect = rect;
mInvalidateViews.push_back(info);
}else{
info=(*it);
if(!info->rect.empty())
info->rect.Union(rect);
InvalidateInfo& info=(*it);
if(!info.rect.empty())
info.rect.Union(rect);
}
postIfNeededLocked();
}
@ -421,7 +421,6 @@ void Window::InvalidateOnAnimationRunnable::removeView(View* view){
auto it=find(view);
if(it != mInvalidateViews.end()){
mInvalidateViews.erase(it);
(*it)->recycle();
}
if(mInvalidateViews.size()==0){
mPosted = false;
@ -433,15 +432,14 @@ void Window::InvalidateOnAnimationRunnable::run(){
int viewRectCount;
mPosted = false;
std::vector<AttachInfo::InvalidateInfo*>temp=mInvalidateViews;
std::vector<InvalidateInfo>temp=mInvalidateViews;
mInvalidateViews.clear();
for (auto i:temp){
Rect&r = i->rect;
View*v = i->target;
Rect&r = i.rect;
View*v = i.target;
if(r.width<=0||r.height<=0) v->invalidate();
else v->invalidate(r.left,r.top,r.width,r.height);
i->recycle();
}
}

8
src/gui/widget/cdwindow.h Normal file → Executable file
View File

@ -9,13 +9,17 @@ class Window : public ViewGroup {
protected:
friend class WindowManager;
friend class GraphDevice;
struct InvalidateInfo{
View* target;
Rect rect;
};
class InvalidateOnAnimationRunnable:public Runnable{
private:
bool mPosted;
Window*mOwner;
std::vector<AttachInfo::InvalidateInfo*>mInvalidateViews;
std::vector<InvalidateInfo>mInvalidateViews;
void postIfNeededLocked();
std::vector<AttachInfo::InvalidateInfo*>::iterator find(View*v);
std::vector<InvalidateInfo>::iterator find(View*v);
public:
InvalidateOnAnimationRunnable();
void setOwner(Window*w);

5
src/gui/widget/horizontalscrollview.cc Normal file → Executable file
View File

@ -19,8 +19,11 @@ HorizontalScrollView::HorizontalScrollView(Context*ctx,const AttributeSet&atts)
}
HorizontalScrollView::~HorizontalScrollView(){
if(mVelocityTracker){
mVelocityTracker->recycle();
mVelocityTracker = nullptr;
}
delete mScroller;
delete mVelocityTracker;
delete mEdgeGlowLeft;
delete mEdgeGlowRight;
}

1
src/gui/widget/overscroller.cc Normal file → Executable file
View File

@ -377,6 +377,7 @@ OverScroller::~OverScroller(){
}
void OverScroller::setInterpolator(Interpolator* interpolator) {
delete mInterpolator;
if (interpolator == nullptr) {
mInterpolator = new Scroller::ViscousFluidInterpolator();
} else {

View File

@ -0,0 +1,58 @@
#include <widget/rtlspacinghelper.h>
namespace cdroid{
int RtlSpacingHelper::getLeft()const{
return mLeft;
}
int RtlSpacingHelper::getRight()const{
return mRight;
}
int RtlSpacingHelper::getStart()const{
return mIsRtl ? mRight : mLeft;
}
int RtlSpacingHelper::getEnd()const{
return mIsRtl ? mLeft : mRight;
}
void RtlSpacingHelper::setRelative(int start, int end) {
mStart = start;
mEnd = end;
mIsRelative = true;
if (mIsRtl) {
if (end != UNDEFINED) mLeft = end;
if (start != UNDEFINED) mRight = start;
} else {
if (start != UNDEFINED) mLeft = start;
if (end != UNDEFINED) mRight = end;
}
}
void RtlSpacingHelper::setAbsolute(int left, int right) {
mIsRelative = false;
if (left != UNDEFINED) mLeft = mExplicitLeft = left;
if (right != UNDEFINED) mRight = mExplicitRight = right;
}
void RtlSpacingHelper::setDirection(bool isRtl) {
if (isRtl == mIsRtl) {
return;
}
mIsRtl = isRtl;
if (mIsRelative) {
if (isRtl) {
mLeft = mEnd != UNDEFINED ? mEnd : mExplicitLeft;
mRight = mStart != UNDEFINED ? mStart : mExplicitRight;
} else {
mLeft = mStart != UNDEFINED ? mStart : mExplicitLeft;
mRight = mEnd != UNDEFINED ? mEnd : mExplicitRight;
}
} else {
mLeft = mExplicitLeft;
mRight = mExplicitRight;
}
}
}//endof namespace

View File

@ -0,0 +1,28 @@
#ifndef __RTLSPACINGHELPER_H__
#define __RTLSPACINGHELPER_H__
#include <limits.h>
namespace cdroid{
class RtlSpacingHelper{
public:
static constexpr int UNDEFINED = INT_MIN;
private:
int mLeft = 0;
int mRight = 0;
int mStart = UNDEFINED;
int mEnd = UNDEFINED;
int mExplicitLeft = 0;
int mExplicitRight = 0;
bool mIsRtl = false;
bool mIsRelative = false;
public:
int getLeft()const;
int getRight()const;
int getStart()const;
int getEnd()const;
void setRelative(int start, int end);
void setAbsolute(int left, int right);
void setDirection(bool isRtl);
};
}
#endif

193
src/gui/widget/toolbar.cc Normal file → Executable file
View File

@ -4,6 +4,10 @@ namespace cdroid{
//DECLARE_WIDGET(ToolBar)
ToolBar::ToolBar(Context*ctx,const AttributeSet&atts):ViewGroup(ctx,atts){
initToolBar();
}
void ToolBar::initToolBar(){
}
@ -88,7 +92,8 @@ void ToolBar::setLogo(Drawable* drawable){
}
} else if (mLogoView && isChildOrHidden(mLogoView)) {
removeView(mLogoView);
//mHiddenViews.remove(mLogoView);
auto it = std::find(mHiddenViews.begin(),mHiddenViews.end(),mLogoView);
mHiddenViews.erase(it);//mHiddenViews.remove(mLogoView)
}
if (mLogoView) {
mLogoView->setImageDrawable(drawable);
@ -131,31 +136,30 @@ std::string ToolBar::getTitle()const{
}
void ToolBar::setTitle(const std::string&title){
#if 0
if (!title.empty()) {
if (mTitleTextView == nullptr) {
Context* context = getContext();
mTitleTextView = new TextView(context,AttributeSet());
mTitleTextView->setSingleLine(true);
//mTitleTextView->setEllipsize(TextUtils.TruncateAt.END);
if (mTitleTextAppearance != 0) {
//mTitleTextView->setTextAppearance(mTitleTextAppearance);
}
if (mTitleTextColor != 0) {
mTitleTextView->setTextColor(mTitleTextColor);
}
}
if (!isChildOrHidden(mTitleTextView)) {
addSystemView(mTitleTextView, true);
}
if (mTitleTextView == nullptr) {
Context* context = getContext();
mTitleTextView = new TextView(context,AttributeSet());
mTitleTextView->setSingleLine(true);
//mTitleTextView->setEllipsize(TextUtils.TruncateAt.END);
if (mTitleTextAppearance != 0) {
//mTitleTextView->setTextAppearance(mTitleTextAppearance);
}
if (mTitleTextColor != 0) {
mTitleTextView->setTextColor(mTitleTextColor);
}
}
if (!isChildOrHidden(mTitleTextView)) {
addSystemView(mTitleTextView, true);
}
} else if (mTitleTextView && isChildOrHidden(mTitleTextView)) {
removeView(mTitleTextView);
mHiddenViews->remove(mTitleTextView);
removeView(mTitleTextView);
auto it = std::find(mHiddenViews.begin(),mHiddenViews.end(),mTitleTextView);
mHiddenViews.erase(it);
}
if (mTitleTextView) {
mTitleTextView->setText(title);
}
#endif
mTitleText=title;
}
@ -163,15 +167,46 @@ std::string ToolBar::getSubtitle()const{
return mSubtitleText;
}
void ToolBar::setSubtitle(const std::string&){
void ToolBar::setSubtitle(const std::string&subtitle){
if (!subtitle.empty()) {
if (mSubtitleTextView == nullptr) {
mSubtitleTextView = new TextView(mContext,AttributeSet());
mSubtitleTextView->setSingleLine(true);
//mSubtitleTextView->setEllipsize(TextUtils.TruncateAt.END);
if (mSubtitleTextAppearance != 0) {
//mSubtitleTextView->setTextAppearance(mSubtitleTextAppearance);
}
if (mSubtitleTextColor != 0) {
mSubtitleTextView->setTextColor(mSubtitleTextColor);
}
}
if (!isChildOrHidden(mSubtitleTextView)) {
addSystemView(mSubtitleTextView, true);
}
} else if (mSubtitleTextView && isChildOrHidden(mSubtitleTextView)) {
removeView(mSubtitleTextView);
auto it = std::find(mHiddenViews.begin(),mHiddenViews.end(),mSubtitleTextView);
mHiddenViews.erase(it);
//mHiddenViews.remove(mSubtitleTextView);
}
if (mSubtitleTextView != nullptr) {
mSubtitleTextView->setText(subtitle);
}
mSubtitleText = subtitle;
}
void ToolBar::setTitleTextColor(int color){
mTitleTextColor = color;
if (mTitleTextView != nullptr) {
mTitleTextView->setTextColor(color);
}
}
void ToolBar::setSubtitleTextColor(int color){
mSubtitleTextColor = color;
if (mSubtitleTextView != nullptr) {
mSubtitleTextView->setTextColor(color);
}
}
std::string ToolBar::getNavigationContentDescription()const{
@ -201,70 +236,150 @@ View*ToolBar::getNavigationView()const{
return mNavButtonView;
}
//void ToolBar::setOnMenuItemClickListener(OnMenuItemClickListener listener){}
void ToolBar::setOnMenuItemClickListener(MenuItem::OnMenuItemClickListener listener){
mOnMenuItemClickListener = listener;
}
void ToolBar::setContentInsetsRelative(int contentInsetStart, int contentInsetEnd) {
//ensureContentInsets();
//mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
ensureContentInsets();
mContentInsets->setRelative(contentInsetStart, contentInsetEnd);
}
int ToolBar::getContentInsetStart()const{
return mContentInsets ? mContentInsets->getStart() : 0;
}
int ToolBar::getContentInsetEnd()const{
return mContentInsets ? mContentInsets->getEnd() : 0;
}
void ToolBar::setContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight){
ensureContentInsets();
mContentInsets->setAbsolute(contentInsetLeft, contentInsetRight);
}
int ToolBar::getContentInsetLeft()const{
return 0;//mContentInsets ? mContentInsets->getLeft() : 0;
return mContentInsets ? mContentInsets->getLeft() : 0;
}
int ToolBar::getContentInsetRight()const{
return 0;//mContentInsets ? mContentInsets->getRight() : 0;
return mContentInsets ? mContentInsets->getRight() : 0;
}
int ToolBar::getContentInsetStartWithNavigation()const{
return 0;
return mContentInsetStartWithNavigation != RtlSpacingHelper::UNDEFINED
? mContentInsetStartWithNavigation : getContentInsetStart();
}
void ToolBar::setContentInsetStartWithNavigation(int insetStartWithNavigation){
if (insetStartWithNavigation < 0) {
insetStartWithNavigation = RtlSpacingHelper::UNDEFINED;
}
if (insetStartWithNavigation != mContentInsetStartWithNavigation) {
mContentInsetStartWithNavigation = insetStartWithNavigation;
if (getNavigationIcon() != nullptr) {
requestLayout();
}
}
}
int ToolBar::getContentInsetEndWithActions()const{
return 0;
return mContentInsetEndWithActions != RtlSpacingHelper::UNDEFINED
? mContentInsetEndWithActions
: getContentInsetEnd();
}
void ToolBar::setContentInsetEndWithActions(int insetEndWithActions){
if (insetEndWithActions < 0) {
insetEndWithActions = RtlSpacingHelper::UNDEFINED;
}
if (insetEndWithActions != mContentInsetEndWithActions) {
mContentInsetEndWithActions = insetEndWithActions;
if (getNavigationIcon() != nullptr) {
requestLayout();
}
}
}
int ToolBar::getCurrentContentInsetStart()const{
return getNavigationIcon() ? std::max(getContentInsetStart(), std::max(mContentInsetStartWithNavigation, 0))
: getContentInsetStart();
}
int ToolBar::getCurrentContentInsetEnd()const{
bool hasActions = false;
if (mMenuView != nullptr) {
//MenuBuilder mb = mMenuView->peekMenu();
//hasActions = mb != nullptr && mb.hasVisibleItems();
}
return hasActions
? std::max(getContentInsetEnd(), std::max(mContentInsetEndWithActions, 0))
: getContentInsetEnd();
}
int ToolBar::getCurrentContentInsetLeft()const{
return isLayoutRtl()
? getCurrentContentInsetEnd()
: getCurrentContentInsetStart();
}
int ToolBar::getCurrentContentInsetRight()const{
return isLayoutRtl()
? getCurrentContentInsetStart()
: getCurrentContentInsetEnd();
}
void ToolBar::ensureNavButtonView(){
if (mNavButtonView == nullptr) {
mNavButtonView = new ImageButton(getContext(),AttributeSet());// null, 0, mNavButtonStyle);
LayoutParams* lp = (LayoutParams*)generateDefaultLayoutParams();
lp->gravity = Gravity::START | (mButtonGravity & Gravity::VERTICAL_GRAVITY_MASK);
mNavButtonView->setLayoutParams(lp);
}
}
void ToolBar::ensureCollapseButtonView(){
if (mCollapseButtonView == nullptr) {
mCollapseButtonView = new ImageButton(getContext(),AttributeSet());// null, 0, mNavButtonStyle);
mCollapseButtonView->setImageDrawable(mCollapseIcon);
mCollapseButtonView->setContentDescription(mCollapseDescription);
LayoutParams* lp = (LayoutParams*)generateDefaultLayoutParams();
lp->gravity = Gravity::START | (mButtonGravity & Gravity::VERTICAL_GRAVITY_MASK);
lp->mViewType = LayoutParams::EXPANDED;
mCollapseButtonView->setLayoutParams(lp);
mCollapseButtonView->setOnClickListener([this](View&v){
collapseActionView();
});
}
}
void ToolBar::addSystemView(View* v, bool allowHide){
ViewGroup::LayoutParams* vlp = v->getLayoutParams();
LayoutParams* lp = nullptr;
if (vlp == nullptr) {
lp = (LayoutParams*)generateDefaultLayoutParams();
} else if (!checkLayoutParams(vlp)) {
lp = (LayoutParams*)generateLayoutParams(vlp);
} else {
lp = (LayoutParams*) vlp;
}
lp->mViewType = LayoutParams::SYSTEM;
if (allowHide && mExpandedActionView) {
v->setLayoutParams(lp);
mHiddenViews.push_back(v);
} else {
addView(v, lp);
}
}
void ToolBar::postShowOverflowMenu(){
removeCallbacks(mShowOverflowMenuRunnable);
post(mShowOverflowMenuRunnable);
}
void ToolBar::onDetachedFromWindow(){
ViewGroup::onDetachedFromWindow();
removeCallbacks(mShowOverflowMenuRunnable);
}
bool ToolBar::onTouchEvent(MotionEvent&ev){
@ -864,6 +979,26 @@ void ToolBar::addChildrenForExpandedActionView() {
bool ToolBar::isChildOrHidden(View* child) {
return child->getParent() == this;// || mHiddenViews.contains(child);
}
void ToolBar::setCollapsible(bool collapsible) {
mCollapsible = collapsible;
requestLayout();
}
/*void ToolBar::setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb){
mActionMenuPresenterCallback = pcb;
mMenuBuilderCallback = mcb;
if (mMenuView != null) {
mMenuView.setMenuCallbacks(pcb, mcb);
}
}*/
void ToolBar::ensureContentInsets() {
if (mContentInsets == nullptr) {
mContentInsets = new RtlSpacingHelper();
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
ToolBar::LayoutParams::LayoutParams(Context* c,const AttributeSet& attrs)
:ActionBar::LayoutParams(c, attrs){

13
src/gui/widget/toolbar.h Normal file → Executable file
View File

@ -4,7 +4,10 @@
#include <widget/imageview.h>
#include <widget/imagebutton.h>
#include <view/viewgroup.h>
#include <view/menu.h>
#include <widget/actionbar.h>
#include <widget/rtlspacinghelper.h>
namespace cdroid{
typedef View ActionMenuView;
class Menu;
@ -54,7 +57,7 @@ private:
int mTitleMarginTop;
int mTitleMarginBottom;
//RtlSpacingHelper mContentInsets;
RtlSpacingHelper* mContentInsets;
int mContentInsetStartWithNavigation;
int mContentInsetEndWithActions;
@ -69,7 +72,10 @@ private:
bool mEatingTouch;
std::vector<View*> mHiddenViews;
bool mCollapsible;
Runnable mShowOverflowMenuRunnable;
MenuItem::OnMenuItemClickListener mOnMenuItemClickListener;
private:
void initToolBar();
void ensureLogoView();
void ensureNavButtonView();
void ensureCollapseButtonView();
@ -94,6 +100,7 @@ private:
int getHorizontalMargins(View* v);
int getVerticalMargins(View* v);
static bool isCustomView(View*);
void ensureContentInsets();
protected:
void onAttachedToWindow()override;
void onDetachedFromWindow()override;
@ -140,7 +147,7 @@ public:
void setOverflowIcon(Drawable*);
Drawable*getOverflowIcon();
void inflateMenu(const std::string&);
//void setOnMenuItemClickListener(OnMenuItemClickListener listener);
void setOnMenuItemClickListener(MenuItem::OnMenuItemClickListener listener);
void setContentInsetsRelative(int contentInsetStart, int contentInsetEnd);
int getContentInsetStart()const;
int getContentInsetEnd()const;
@ -157,6 +164,8 @@ public:
int getCurrentContentInsetRight()const;
bool onTouchEvent(MotionEvent&)override;
ViewGroup::LayoutParams* generateLayoutParams(const AttributeSet& attrs)const override;
void setCollapsible(bool);
//void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb);
};
}//namespace

View File

@ -26,7 +26,11 @@ ViewPager::~ViewPager(){
delete mMarginDrawable;
delete mScroller;
for(auto item: mItems)
delete item;
delete item;
if(mVelocityTracker){
mVelocityTracker->recycle();
mVelocityTracker = nullptr;
}
}
ViewPager::ViewPager(Context* context,const AttributeSet& attrs)
@ -111,6 +115,7 @@ void ViewPager::setAdapter(PagerAdapter* adapter){
for (int i = 0; i < mItems.size(); i++) {
ItemInfo* ii = mItems[i];
mAdapter->destroyItem(this, ii->position, ii->object);
delete ii;
}
mAdapter->finishUpdate(this);
mItems.clear();
@ -464,7 +469,7 @@ void ViewPager::dataSetChanged(){
}
if (newPos == PagerAdapter::POSITION_NONE) {
mItems.erase(mItems.begin()+i);
delete *mItems.erase(mItems.begin()+i);
i--;
if (!isUpdating) {
@ -582,6 +587,7 @@ void ViewPager::populate(int newCurrentItem){
mItems.erase(mItems.begin()+itemIndex);
mAdapter->destroyItem(this, pos, ii->object);
LOGD("destroyItem() with pos:%d/%d view:%p curitem=%d/%d",pos,ii->position,ii->object,mCurItem,mItems.size());
delete ii;
itemIndex--;
curIndex--;
ii = itemIndex >= 0 ? mItems[itemIndex] : nullptr;
@ -612,6 +618,7 @@ void ViewPager::populate(int newCurrentItem){
if (pos == ii->position && !ii->scrolling) {
mItems.erase(mItems.begin()+itemIndex);
mAdapter->destroyItem(this, pos, ii->object);
delete ii;
ii = itemIndex < mItems.size() ? mItems[itemIndex] : nullptr;
}
} else if (ii != nullptr && pos == ii->position) {