mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-05 21:58:44 +08:00
1. add View::postInvalidateDelayed;2.fix progressbar's crash caused by View::postInvalidate
This commit is contained in:
parent
124b28111e
commit
b38f04a3ec
@ -46,6 +46,7 @@ public:
|
||||
std::streambuf::pos_type seekoff(std::streambuf::off_type off, std::ios_base::seekdir way,
|
||||
std::ios_base::openmode mode/*ios_base::in | ios_base::out*/)override;
|
||||
};
|
||||
|
||||
struct MemoryInputStream: virtual MemoryBuf, std::istream {
|
||||
MemoryInputStream(char const* base, size_t size)
|
||||
: MemoryBuf(base, size)
|
||||
|
@ -4973,7 +4973,32 @@ void View::invalidate(bool invalidateCache){
|
||||
}
|
||||
|
||||
void View::postInvalidate(){
|
||||
postDelayed([this](){ invalidate(true);},30);
|
||||
postInvalidateDelayed(0);
|
||||
}
|
||||
|
||||
void View::postInvalidate(int left,int top,int width,int height){
|
||||
postInvalidateDelayed(0,left,top,width,height);
|
||||
}
|
||||
|
||||
void View::postInvalidateDelayed(long delayMilliseconds) {
|
||||
// We try only with the AttachInfo because there's no point in invalidating
|
||||
// if we are not attached to our window
|
||||
if (mAttachInfo) {
|
||||
mAttachInfo->mRootView->dispatchInvalidateDelayed(this, delayMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void View::postInvalidateDelayed(long delayMilliseconds, int left, int top,
|
||||
int width, int height) {
|
||||
|
||||
// We try only with the AttachInfo because there's no point in invalidating
|
||||
// if we are not attached to our window
|
||||
if (mAttachInfo) {
|
||||
AttachInfo::InvalidateInfo* info = AttachInfo::InvalidateInfo::obtain();
|
||||
info->target= this;
|
||||
info->rect.set(left,top,width,height);
|
||||
mAttachInfo->mRootView->dispatchInvalidateRectDelayed(info, delayMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void View::cleanupDraw(){
|
||||
@ -5215,7 +5240,7 @@ bool View::requestFocusNoSearch(int direction,Rect*previouslyFocusedRect) {
|
||||
bool View::requestFocusFromTouch(){
|
||||
if(isInTouchMode()){
|
||||
ViewGroup* viewRoot = (ViewGroup*)getRootView();
|
||||
//if(viewRoot)viewRoot->ensureTouchMode(false);
|
||||
if(viewRoot)viewRoot->ensureTouchMode(false);
|
||||
}
|
||||
return requestFocus(View::FOCUS_DOWN);
|
||||
}
|
||||
@ -7218,6 +7243,28 @@ void View::measure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
//mMeasureCache.insert(std::pair<Size,Size>(key,szMeasured)); // suppress sign extension
|
||||
}
|
||||
|
||||
View::AttachInfo::InvalidateInfo::InvalidateInfo(){
|
||||
target = nullptr;
|
||||
rect.set(0,0,0,0);
|
||||
}
|
||||
std::vector<View::AttachInfo::InvalidateInfo*>View::AttachInfo::InvalidateInfo::sPool;
|
||||
|
||||
View::AttachInfo::InvalidateInfo*View::AttachInfo::InvalidateInfo::obtain(){
|
||||
AttachInfo::InvalidateInfo*ret = nullptr;
|
||||
if(sPool.empty()){
|
||||
ret = new AttachInfo::InvalidateInfo();
|
||||
}else{
|
||||
ret = sPool.back();
|
||||
sPool.pop_back();
|
||||
}
|
||||
ret->rect.set(0,0,0,0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void View::AttachInfo::InvalidateInfo::recycle(){
|
||||
sPool.push_back(this);
|
||||
}
|
||||
|
||||
View::AttachInfo::AttachInfo(Context*ctx){
|
||||
mHardwareAccelerated =false;
|
||||
mWindowVisibility = VISIBLE;
|
||||
|
@ -194,8 +194,20 @@ protected:
|
||||
ForegroundInfo();
|
||||
~ForegroundInfo();
|
||||
};
|
||||
public:
|
||||
class AttachInfo{
|
||||
public:
|
||||
class InvalidateInfo{
|
||||
private:
|
||||
static std::vector<InvalidateInfo*>sPool;
|
||||
public:
|
||||
View* target;
|
||||
Rect rect;
|
||||
static InvalidateInfo*obtain();
|
||||
InvalidateInfo();
|
||||
void recycle();
|
||||
};
|
||||
|
||||
ViewGroup*mRootView;
|
||||
bool mHardwareAccelerated;
|
||||
float mApplicationScale;
|
||||
@ -687,6 +699,9 @@ public:
|
||||
|
||||
bool isDirty()const;
|
||||
void postInvalidate();
|
||||
void postInvalidate(int left, int top, int width, int height);
|
||||
void postInvalidateDelayed(long delayMilliseconds);
|
||||
void postInvalidateDelayed(long delayMilliseconds, int left, int top,int width, int height);
|
||||
void postInvalidateOnAnimation();
|
||||
void postInvalidateOnAnimation(int left, int top, int width, int height);
|
||||
void invalidateDrawable(Drawable& who)override;
|
||||
|
@ -253,6 +253,10 @@ int ViewGroup::getTextAlignment()const{
|
||||
return View::TEXT_ALIGNMENT_RESOLVED_DEFAULT;
|
||||
}
|
||||
|
||||
bool ViewGroup::ensureTouchMode(bool){
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewGroup::cancelAndClearTouchTargets(MotionEvent* event){
|
||||
if (mFirstTouchTarget==nullptr)return;
|
||||
|
||||
@ -890,7 +894,13 @@ void ViewGroup::finishAnimatingView(View* view, Animation* animation) {
|
||||
void ViewGroup::dispatchInvalidateOnAnimation(View* view){
|
||||
}
|
||||
|
||||
void ViewGroup::dispatchInvalidateRectOnAnimation(View*,const Rect&){
|
||||
void ViewGroup::dispatchInvalidateRectOnAnimation(View*view,const Rect&rect){
|
||||
}
|
||||
|
||||
void ViewGroup::dispatchInvalidateDelayed(View* view,long){
|
||||
}
|
||||
|
||||
void ViewGroup::dispatchInvalidateRectDelayed(const AttachInfo::InvalidateInfo*,long){
|
||||
}
|
||||
|
||||
void ViewGroup::cancelInvalidate(View* view){
|
||||
|
@ -261,6 +261,7 @@ public:
|
||||
ViewGroup(int x,int y,int w,int h);
|
||||
ViewGroup(Context*ctx,const AttributeSet& attrs);
|
||||
virtual ~ViewGroup();
|
||||
virtual bool ensureTouchMode(bool);
|
||||
bool getTouchscreenBlocksFocus()const;
|
||||
bool shouldBlockFocusForTouchscreen()const;
|
||||
int getDescendantFocusability()const;
|
||||
@ -395,6 +396,8 @@ public:
|
||||
|
||||
virtual void dispatchInvalidateOnAnimation(View* view);
|
||||
virtual void dispatchInvalidateRectOnAnimation(View*,const Rect&);
|
||||
virtual void dispatchInvalidateDelayed(View*,long delay);
|
||||
virtual void dispatchInvalidateRectDelayed(const AttachInfo::InvalidateInfo*,long delay);
|
||||
virtual void cancelInvalidate(View* view);
|
||||
virtual bool showContextMenuForChild(View* originalView);
|
||||
virtual bool showContextMenuForChild(View* originalView, float x, float y);
|
||||
|
@ -108,6 +108,94 @@ void Window::bringToFront(){
|
||||
WindowManager::getInstance().bringToFront(this);
|
||||
}
|
||||
|
||||
bool Window::ensureTouchMode(bool inTouchMode) {
|
||||
LOGD("ensureTouchMode( %d), current touch mode is ",inTouchMode, mAttachInfo->mInTouchMode);
|
||||
if (mAttachInfo->mInTouchMode == inTouchMode) return false;
|
||||
// tell the window manager
|
||||
/*try {
|
||||
IWindowManager windowManager = WindowManagerGlobal.getWindowManagerService();
|
||||
windowManager.setInTouchMode(inTouchMode, getDisplayId());
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}*/
|
||||
// handle the change
|
||||
return ensureTouchModeLocally(inTouchMode);
|
||||
}
|
||||
|
||||
bool Window::ensureTouchModeLocally(bool inTouchMode) {
|
||||
LOGD("ensureTouchModeLocally(%d), current touch mode is ",inTouchMode, mAttachInfo->mInTouchMode);
|
||||
|
||||
if (mAttachInfo->mInTouchMode == inTouchMode) return false;
|
||||
|
||||
mAttachInfo->mInTouchMode = inTouchMode;
|
||||
mAttachInfo->mTreeObserver->dispatchOnTouchModeChanged(inTouchMode);
|
||||
|
||||
return (inTouchMode) ? enterTouchMode() : leaveTouchMode();
|
||||
}
|
||||
|
||||
ViewGroup*Window::findAncestorToTakeFocusInTouchMode(View* focused) {
|
||||
ViewGroup* parent = focused->getParent();
|
||||
while (parent){
|
||||
ViewGroup* vgParent = (ViewGroup*) parent;
|
||||
if (vgParent->getDescendantFocusability() == ViewGroup::FOCUS_AFTER_DESCENDANTS
|
||||
&& vgParent->isFocusableInTouchMode()) {
|
||||
return vgParent;
|
||||
}
|
||||
/*if (vgParent->isRootNamespace()) {
|
||||
return nullptr;
|
||||
} else */{
|
||||
parent = vgParent->getParent();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Window::enterTouchMode() {
|
||||
if (hasFocus()) {
|
||||
// note: not relying on mFocusedView here because this could
|
||||
// be when the window is first being added, and mFocused isn't
|
||||
// set yet.
|
||||
View* focused = findFocus();
|
||||
if (focused && !focused->isFocusableInTouchMode()) {
|
||||
ViewGroup* ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused);
|
||||
if (ancestorToTakeFocus != nullptr) {
|
||||
// there is an ancestor that wants focus after its
|
||||
// descendants that is focusable in touch mode.. give it
|
||||
// focus
|
||||
return ancestorToTakeFocus->requestFocus();
|
||||
} else {
|
||||
// There's nothing to focus. Clear and propagate through the
|
||||
// hierarchy, but don't attempt to place new focus.
|
||||
//focused->clearFocusInternal(nullptr, true, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Window::leaveTouchMode() {
|
||||
if (mChildren.size()) {
|
||||
if (hasFocus()) {
|
||||
View* focusedView = findFocus();
|
||||
if (dynamic_cast<ViewGroup*>(focusedView)==nullptr) {
|
||||
// some view has focus, let it keep it
|
||||
return false;
|
||||
} else if (((ViewGroup*) focusedView)->getDescendantFocusability() !=
|
||||
ViewGroup::FOCUS_AFTER_DESCENDANTS) {
|
||||
// some view group has focus, and doesn't prefer its children
|
||||
// over itself for focus, so let them keep it.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// find the best view to give focus to in this brave new non-touch-mode
|
||||
// world
|
||||
return restoreDefaultFocus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::draw(){
|
||||
if(mVisibleRgn&&mVisibleRgn->get_num_rectangles()==0){
|
||||
return;
|
||||
@ -416,22 +504,32 @@ void Window::dispatchInvalidateRectOnAnimation(View*view,const Rect&rect){
|
||||
mInvalidateOnAnimationRunnable.addViewRect(view,rect);
|
||||
}
|
||||
|
||||
void Window::dispatchInvalidateDelayed(View*view, long delayMilliseconds){
|
||||
LOGW_IF(delayMilliseconds,"Delay is NOT IMPLEMENTED");
|
||||
if(0==delayMilliseconds) dispatchInvalidateOnAnimation(view);
|
||||
}
|
||||
|
||||
void Window::dispatchInvalidateRectDelayed(const AttachInfo::InvalidateInfo*info,long delayMilliseconds){
|
||||
LOGW_IF(delayMilliseconds,"Delay is NOT IMPLEMENTED");
|
||||
if(0==delayMilliseconds) dispatchInvalidateRectOnAnimation(info->target,info->rect);
|
||||
}
|
||||
|
||||
void Window::cancelInvalidate(View* view){
|
||||
mInvalidateOnAnimationRunnable.removeView(view);
|
||||
}
|
||||
|
||||
Window::InvalidateOnAnimationRunnable::InvalidateOnAnimationRunnable(){
|
||||
mOwner =nullptr;
|
||||
mPosted=false;
|
||||
mOwner = nullptr;
|
||||
mPosted= false;
|
||||
}
|
||||
|
||||
void Window::InvalidateOnAnimationRunnable::setOwner(Window*w){
|
||||
mOwner=w;
|
||||
}
|
||||
|
||||
std::vector<Window::InvalidateInfo>::iterator Window::InvalidateOnAnimationRunnable::find(View*v){
|
||||
std::vector<View::AttachInfo::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();
|
||||
@ -440,13 +538,13 @@ std::vector<Window::InvalidateInfo>::iterator Window::InvalidateOnAnimationRunna
|
||||
void Window::InvalidateOnAnimationRunnable::addView(View* view){
|
||||
auto it=find(view);
|
||||
if(it==mInvalidateViews.end()){
|
||||
InvalidateInfo info;
|
||||
info.target = view;
|
||||
info.rect.set(0,0,0,0);
|
||||
AttachInfo::InvalidateInfo* info = AttachInfo::InvalidateInfo::obtain();
|
||||
info->target = view;
|
||||
info->rect.set(0,0,0,0);
|
||||
mInvalidateViews.push_back(info);
|
||||
}else{
|
||||
InvalidateInfo& info=(*it);
|
||||
info.rect.set(0,0,0,0);
|
||||
AttachInfo::InvalidateInfo* info=(*it);
|
||||
info->rect.set(0,0,0,0);
|
||||
}
|
||||
postIfNeededLocked();
|
||||
}
|
||||
@ -454,14 +552,14 @@ void Window::InvalidateOnAnimationRunnable::addView(View* view){
|
||||
void Window::InvalidateOnAnimationRunnable::addViewRect(View* view,const Rect&rect){
|
||||
auto it=find(view);
|
||||
if(it == mInvalidateViews.end()){
|
||||
InvalidateInfo info;
|
||||
info.target =view;
|
||||
info.rect = rect;
|
||||
AttachInfo::InvalidateInfo* info = AttachInfo::InvalidateInfo::obtain();
|
||||
info->target =view;
|
||||
info->rect = rect;
|
||||
mInvalidateViews.push_back(info);
|
||||
}else{
|
||||
InvalidateInfo& info=(*it);
|
||||
if(!info.rect.empty())
|
||||
info.rect.Union(rect);
|
||||
AttachInfo::InvalidateInfo* info=(*it);
|
||||
if(!info->rect.empty())
|
||||
info->rect.Union(rect);
|
||||
}
|
||||
postIfNeededLocked();
|
||||
}
|
||||
@ -478,11 +576,11 @@ void Window::InvalidateOnAnimationRunnable::removeView(View* view){
|
||||
|
||||
void Window::InvalidateOnAnimationRunnable::run(){
|
||||
mPosted = false;
|
||||
std::vector<InvalidateInfo>temp = mInvalidateViews;
|
||||
std::vector<View::AttachInfo::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);
|
||||
}
|
||||
@ -491,7 +589,8 @@ void Window::InvalidateOnAnimationRunnable::run(){
|
||||
void Window::InvalidateOnAnimationRunnable::postIfNeededLocked() {
|
||||
if (!mPosted) {
|
||||
//Choreographer::getInstance().postCallback(Choreographer::CALLBACK_ANIMATION,nullptr,this);
|
||||
Runnable run;run=std::bind(&InvalidateOnAnimationRunnable::run,this);
|
||||
Runnable run;
|
||||
run=std::bind(&InvalidateOnAnimationRunnable::run,this);
|
||||
mOwner->postDelayed(run,AnimationHandler::getFrameDelay());
|
||||
mPosted = true;
|
||||
}
|
||||
|
@ -14,17 +14,13 @@ protected:
|
||||
friend class WindowManager;
|
||||
friend class GraphDevice;
|
||||
friend class UIEventSource;
|
||||
struct InvalidateInfo{
|
||||
View* target;
|
||||
Rect rect;
|
||||
};
|
||||
class InvalidateOnAnimationRunnable:public Runnable{
|
||||
private:
|
||||
bool mPosted;
|
||||
Window*mOwner;
|
||||
std::vector<InvalidateInfo>mInvalidateViews;
|
||||
std::vector<AttachInfo::InvalidateInfo*>mInvalidateViews;
|
||||
void postIfNeededLocked();
|
||||
std::vector<InvalidateInfo>::iterator find(View*v);
|
||||
std::vector<AttachInfo::InvalidateInfo*>::iterator find(View*v);
|
||||
public:
|
||||
InvalidateOnAnimationRunnable();
|
||||
void setOwner(Window*w);
|
||||
@ -48,6 +44,10 @@ private:
|
||||
void doLayout();
|
||||
bool performFocusNavigation(KeyEvent& event);
|
||||
static View*inflate(Context*ctx,std::istream&stream);
|
||||
static ViewGroup*findAncestorToTakeFocusInTouchMode(View* focused);
|
||||
bool ensureTouchModeLocally(bool);
|
||||
bool enterTouchMode();
|
||||
bool leaveTouchMode();
|
||||
protected:
|
||||
std::vector<View*>mLayoutRequesters;
|
||||
Cairo::RefPtr<Cairo::Region>mVisibleRgn;
|
||||
@ -93,6 +93,7 @@ public:
|
||||
virtual void setText(const std::string&);
|
||||
const std::string getText()const;
|
||||
virtual View& setPos(int x,int y)override;
|
||||
bool ensureTouchMode(bool inTouchMode)override;
|
||||
View& setAlpha(float a);
|
||||
void sendToBack();
|
||||
void bringToFront();
|
||||
@ -108,6 +109,8 @@ public:
|
||||
bool removeCallbacks(const Runnable& what)override;
|
||||
void dispatchInvalidateOnAnimation(View* view)override;
|
||||
void dispatchInvalidateRectOnAnimation(View*,const Rect&)override;
|
||||
void dispatchInvalidateDelayed(View*, long delayMilliseconds)override;
|
||||
void dispatchInvalidateRectDelayed(const AttachInfo::InvalidateInfo*,long delayMilliseconds)override;
|
||||
bool dispatchTouchEvent(MotionEvent& event)override;
|
||||
void cancelInvalidate(View* view)override;
|
||||
ViewGroup::LayoutParams* generateLayoutParams(const AttributeSet&)const override;
|
||||
|
@ -219,6 +219,7 @@ void ProgressBar::initProgressBar(){
|
||||
mHasAnimation = false;
|
||||
mInDrawing = false;
|
||||
mAggregatedIsVisible = false;
|
||||
mShouldStartAnimationDrawable = false;
|
||||
mRefreshIsPosted = false;
|
||||
mDatas.insert(std::pair<int,RefreshData>(R::id::progress,RefreshData()));
|
||||
mDatas.insert(std::pair<int,RefreshData>(R::id::secondaryProgress,RefreshData()));
|
||||
|
Loading…
Reference in New Issue
Block a user