fix rotatedrawable,and RING shape...

This commit is contained in:
houzh 2024-02-23 23:35:05 +08:00
parent 60093286ed
commit dbf5d80dea
12 changed files with 74 additions and 57 deletions

View File

@ -874,7 +874,7 @@ void GradientDrawable::draw(Canvas&canvas) {
const bool haveFill = currFillAlpha>0;
const bool useLayer =(haveStroke || haveFill) && (st->mShape!=LINE) &&
(currStrokeAlpha<255) && ((mAlpha<255)|| colorFilter);
const float sweep = getUseLevel()/*st->mUseLevelForShape*/ ? (360.f*getLevel()/10000.f) : 360.f;
const float sweep = st->mUseLevelForShape ? (360.f*getLevel()/10000.f) : 360.f;
float rad = .0f, innerRadius = .0f;
std::vector<float>radii;
@ -940,9 +940,17 @@ void GradientDrawable::draw(Canvas&canvas) {
innerRadius=std::min(mRect.width,mRect.height)/2.f-thickness;
canvas.begin_new_sub_path();
if( sweep<360.f && sweep>-360.f ) {
canvas.arc(x,y,innerRadius,0,M_PI*2*sweep/360.f);
canvas.begin_new_sub_path();
canvas.arc_negative(x,y,innerRadius+thickness,sweep*M_PI*2.f/360.f,0.f);
double ddd = (thickness/2)/(innerRadius+thickness/2);
double end_angle = M_PI*2*sweep/360.f-ddd;
double cx = x + (innerRadius+thickness/2) * std::cos(end_angle);
double cy = y + (innerRadius+thickness/2) * std::sin(end_angle);
//canvas.set_fill_rule(Cairo::Context::FillRule::WINDING);//EVEN_ODD);//WINDING);
canvas.move_to(x+innerRadius,y);
canvas.arc(x,y,innerRadius,0.f+ddd,end_angle);
canvas.arc(cx,cy,thickness/2,end_angle,end_angle+M_PI);
canvas.arc_negative(x,y,innerRadius+thickness,end_angle,0.f+ddd);
canvas.arc_negative(x+innerRadius+thickness/2,y,thickness/2,0.f+ddd,M_PI+ddd);
canvas.close_path();
} else {
//canvas.set_fill_rule(Cairo::Context::FillRule::EVEN_ODD);
canvas.arc(x,y,innerRadius,0,M_PI*2.f);

View File

@ -134,13 +134,25 @@ void RotateDrawable::draw(Canvas& canvas) {
float px = mState->mPivotXRel ? (w * mState->mPivotX) : mState->mPivotX;
float py = mState->mPivotYRel ? (h * mState->mPivotY) : mState->mPivotY;
#if 1
d->setBounds(bounds);
canvas.save();
canvas.translate(px,py);
canvas.rotate_degrees(mState->mCurrentDegrees);
Rect rd = d->getBounds();
rd.offset(-w/2,-h/2);
d->setBounds(rd);
d->draw(canvas);
rd.offset(w/2,h/2);
d->setBounds(rd);
//LOGD("pos=%d,%d/%.f,%.f level=%d degress=%d",bounds.left,bounds.top,px,py,getLevel(),int(mState->mCurrentDegrees));
canvas.restore();
#else
const float radians=M_PI*2.f*mState->mCurrentDegrees/360.f;
const float fsin=sin(radians);
const float fcos=cos(radians);
#if 0//Anti clockwise
Matrix mtx(fcos,-fsin, fsin,fcos, sdot(-fsin,py,1-fcos,px), sdot(fsin,px,1-fcos,py));
#else//Clockwise
Matrix mtx(fcos,fsin, -fsin,fcos, sdot(fsin,py,1-fcos,px), sdot(-fsin,px,1-fcos,py));
Matrix mtx(fcos,-fsin, fsin,fcos, sdot(-fsin,py,1-fcos,px), sdot(fsin,px,1-fcos,py));//Anti clockwise
Matrix mtx(fcos,fsin, -fsin,fcos, sdot(fsin,py,1-fcos,px), sdot(-fsin,px,1-fcos,py));//Clockwise
canvas.save();
canvas.translate(bounds.left,bounds.top);
canvas.transform(mtx);
@ -156,10 +168,12 @@ void RotateDrawable::draw(Canvas& canvas) {
Drawable*RotateDrawable::inflate(Context*ctx,const AttributeSet&atts){
Drawable*d = createWrappedDrawable(ctx,atts);
RotateDrawable*rd = new RotateDrawable(d);
rd->setPivotX(atts.getFraction("pivotX",1,1,0));
rd->setPivotY(atts.getFraction("pivotY",1,1,0));
//rd->setPivotXRelative();
//rd->setPivotYRelative();
const float px = atts.getFraction("pivotX",1,1,0.5f);
const float py = atts.getFraction("pivotY",1,1,0.5f);
rd->setPivotX(px);
rd->setPivotY(py);
rd->setPivotXRelative(px<=1.f);
rd->setPivotYRelative(py<=1.f);
rd->setFromDegrees(atts.getFloat("fromDegrees",0));
rd->setToDegrees(atts.getFloat("toDegrees",360.0));
rd->onLevelChange(0);

View File

@ -2,7 +2,6 @@
#include <widgetEx/recyclerview/childhelper.h>
namespace cdroid{
static constexpr int _DEBUG=1;
ChildHelper::ChildHelper(ChildHelper::Callback& callback){
mCallback = callback;
mBucket = new Bucket();
@ -39,7 +38,7 @@ void ChildHelper::addView(View* child, int index, bool hidden){
hideViewInternal(child);
}
mCallback.addView(child, offset);
LOGD("addViewAt %d,h:%d",index,hidden);
LOGD_IF(_DEBUG,"addViewAt %d,h:%d",index,hidden);
}
int ChildHelper::getOffset(int index){
@ -72,7 +71,7 @@ void ChildHelper::removeView(View* view){
unhideViewInternal(view);
}
mCallback.removeViewAt(index);
LOGD("remove View off:%d",index);
LOGD_IF(_DEBUG,"remove View off:%d",index);
}
void ChildHelper::removeViewAt(int index){
@ -85,7 +84,7 @@ void ChildHelper::removeViewAt(int index){
unhideViewInternal(view);
}
mCallback.removeViewAt(offset);
LOGD("removeViewAt %d off:%d",index,offset);
LOGD_IF(_DEBUG,"removeViewAt %d off:%d",index,offset);
}
View* ChildHelper::getChildAt(int index){
@ -101,7 +100,7 @@ void ChildHelper::removeAllViewsUnfiltered(){
}
mHiddenViews.clear();
mCallback.removeAllViews();
LOGD("removeAllViewsUnfiltered");
LOGD_IF(_DEBUG,"removeAllViewsUnfiltered");
}
View* ChildHelper::findHiddenNonRemovedView(int position){
@ -131,7 +130,7 @@ void ChildHelper::attachViewToParent(View* child, int index, ViewGroup::LayoutPa
hideViewInternal(child);
}
mCallback.attachViewToParent(child, offset, layoutParams);
LOGD("attach view to parent index:%d off:%d h:%d ",index,offset,hidden);
LOGD_IF(_DEBUG,"attach view to parent index:%d off:%d h:%d ",index,offset,hidden);
}
int ChildHelper::getChildCount(){
@ -150,7 +149,7 @@ void ChildHelper::detachViewFromParent(int index){
const int offset = getOffset(index);
mBucket->remove(offset);
mCallback.detachViewFromParent(offset);
LOGD("detach view from parent %d of:%d",index,offset);
LOGD_IF(_DEBUG,"detach view from parent %d of:%d",index,offset);
}
int ChildHelper::indexOfChild(View* child){
@ -184,7 +183,7 @@ void ChildHelper::hide(View* view){
}
mBucket->set(offset);
hideViewInternal(view);
LOGD("hiding child %p at offset",view,offset);
LOGD_IF(_DEBUG,"hiding child %p at offset",view,offset);
}
void ChildHelper::unhide(View* view){

View File

@ -22,6 +22,7 @@ public:
Bucket* mBucket;
std::vector<View*>mHiddenViews;
private:
static constexpr bool _DEBUG = false;
void hideViewInternal(View* child);
bool unhideViewInternal(View* child);
int getOffset(int index);

View File

@ -5,7 +5,7 @@ namespace cdroid{
class GridLayoutManager:public LinearLayoutManager {
private:
static constexpr bool _DEBUG = true;
static constexpr bool _DEBUG = false;
public:
static constexpr int DEFAULT_SPAN_COUNT = -1;
class SpanSizeLookup;

View File

@ -240,7 +240,7 @@ void LinearLayoutManager::onLayoutChildren(RecyclerView::Recycler& recycler, Rec
// 3) fill towards end, stacking from top
// 4) scroll to fulfill requirements like stack from bottom.
// create layout state
LOGD("is pre layout:%d",state.isPreLayout());
LOGD_IF(_DEBUG,"is pre layout:%d",state.isPreLayout());
if (mPendingSavedState || mPendingScrollPosition != RecyclerView::NO_POSITION) {
if (state.getItemCount() == 0) {
removeAndRecycleAllViews(recycler);
@ -281,7 +281,7 @@ void LinearLayoutManager::onLayoutChildren(RecyclerView::Recycler& recycler, Rec
// child which can change between layout passes).
mAnchorInfo->assignFromViewAndKeepVisibleRect(focused, getPosition(focused));
}
LOGD("Anchor info:%p",mAnchorInfo);
LOGD_IF(_DEBUG,"Anchor info:%p",mAnchorInfo);
// LLM may decide to layout items for "extra" pixels to account for scrolling target,
// caching or predictive animations.

View File

@ -7,7 +7,7 @@ namespace cdroid{
class GridLayoutManager;
class LinearLayoutManager:public RecyclerView::LayoutManager{
private:
static constexpr int _DEBUG=1;
static constexpr bool _DEBUG=false;
static constexpr float MAX_SCROLL_FACTOR = 1.f / 3.f;
public:
static constexpr int HORIZONTAL = RecyclerView::HORIZONTAL;

View File

@ -21,10 +21,10 @@ protected:
public:
LinearSmoothScroller(Context* context);
~LinearSmoothScroller();
void onStart();
void onTargetFound(View* targetView, RecyclerView::State& state, Action& action);
void onSeekTargetStep(int dx, int dy, RecyclerView::State& state, Action& action);
void onStop();
void onStart()override;
void onTargetFound(View* targetView, RecyclerView::State& state, Action& action)override;
void onSeekTargetStep(int dx, int dy, RecyclerView::State& state, Action& action)override;
void onStop()override;
float calculateSpeedPerPixel(DisplayMetrics& displayMetrics);
int calculateTimeForDeceleration(int dx);
int calculateTimeForScrolling(int dx);

View File

@ -16,16 +16,13 @@ PagerSnapHelper::~PagerSnapHelper(){
void PagerSnapHelper::calculateDistanceToFinalSnap(RecyclerView::LayoutManager& layoutManager,
View& targetView,int out[2]) {
out[0] = out[1] = 0;
if (layoutManager.canScrollHorizontally()) {
out[0] = distanceToCenter(layoutManager, targetView,getHorizontalHelper(layoutManager));
} else {
out[0] = 0;
}
if (layoutManager.canScrollVertically()) {
out[1] = distanceToCenter(layoutManager, targetView,getVerticalHelper(layoutManager));
} else {
out[1] = 0;
}
}

View File

@ -250,7 +250,6 @@ void RecyclerView::setAccessibilityDelegate(RecyclerViewAccessibilityDelegate* a
void RecyclerView::createLayoutManager(Context* context,const std::string& className,
const AttributeSet& attrs/*,int defStyleAttr, int defStyleRes*/) {
LOGD("%s",className.c_str());
if(!className.compare("LinearLayoutManager")){
setLayoutManager(new LinearLayoutManager(context,attrs));
}else if(!className.compare("GridLayoutManager")){
@ -703,7 +702,7 @@ void RecyclerView::setScrollState(int state) {
if (state == mScrollState) {
return;
}
LOGD("setting scroll state from %d to %d",mScrollState,state);
LOGD_IF(_DEBUG,"setting scroll state from %d to %d",mScrollState,state);
mScrollState = state;
if (state != SCROLL_STATE_SETTLING) {
stopScrollersInternal();
@ -1094,32 +1093,32 @@ bool RecyclerView::fling(int velocityX, int velocityY) {
return false;
}
bool canScrollHorizontal = mLayout->canScrollHorizontally();
bool canScrollVertical = mLayout->canScrollVertically();
const bool bCanScrollHorizontal = mLayout->canScrollHorizontally();
const bool bCanScrollVertical = mLayout->canScrollVertically();
if (!canScrollHorizontal || std::abs(velocityX) < mMinFlingVelocity) {
velocityX = 0;
if ((bCanScrollHorizontal==false) || (std::abs(velocityX) < mMinFlingVelocity)) {
//velocityX = 0;
}
if (!canScrollVertical || std::abs(velocityY) < mMinFlingVelocity) {
velocityY = 0;
if ((bCanScrollVertical==false) || (std::abs(velocityY) < mMinFlingVelocity)) {
//velocityY = 0;
}
if (velocityX == 0 && velocityY == 0) {
if ((velocityX == 0) && (velocityY == 0)) {
// If we don't have any velocity, return false
return false;
}
if (!dispatchNestedPreFling(velocityX, velocityY)) {
const bool canScroll = canScrollHorizontal || canScrollVertical;
const bool canScroll = bCanScrollHorizontal || bCanScrollVertical;
dispatchNestedFling(velocityX, velocityY, canScroll);
if (mOnFlingListener && mOnFlingListener(velocityX, velocityY)){//->onFling(velocityX, velocityY)) {
return true;
}
if (canScroll) {
int nestedScrollAxis = View::SCROLL_AXIS_NONE;
if (canScrollHorizontal) {
if (bCanScrollHorizontal) {
nestedScrollAxis |= View::SCROLL_AXIS_HORIZONTAL;
}
if (canScrollVertical) {
if (bCanScrollVertical) {
nestedScrollAxis |= View::SCROLL_AXIS_VERTICAL;
}
startNestedScroll(nestedScrollAxis, TYPE_NON_TOUCH);
@ -1881,6 +1880,7 @@ bool RecyclerView::onTouchEvent(MotionEvent& e) {
mVelocityTracker->computeCurrentVelocity(1000, mMaxFlingVelocity);
const float xvel = bCanScrollHorizontally ? -mVelocityTracker->getXVelocity(mScrollPointerId) : 0;
const float yvel = bCanScrollVertically ? -mVelocityTracker->getYVelocity(mScrollPointerId) : 0;
LOGD("xvel=%.2f yvel=%.2f",xvel,yvel);
if (!(((xvel != 0) || (yvel != 0)) && fling((int) xvel, (int) yvel))) {
setScrollState(SCROLL_STATE_IDLE);
}
@ -3909,7 +3909,7 @@ RecyclerView::ViewHolder* RecyclerView::Recycler::tryGetViewHolderForPositionByD
}
}
if (holder == nullptr) { // fallback to pool
LOGD("tryGetViewHolderForPositionByDeadline(%d) fetching from shared pool",position);
LOGD_IF(_DEBUG,"tryGetViewHolderForPositionByDeadline(%d) fetching from shared pool",position);
holder = getRecycledViewPool().getRecycledView(type);
if (holder != nullptr) {
holder->resetInternal();
@ -3935,7 +3935,7 @@ RecyclerView::ViewHolder* RecyclerView::Recycler::tryGetViewHolderForPositionByD
}
const long end = mRV->getNanoTime();
mRecyclerPool->factorInCreateTime(type, end - start);
LOGD("tryGetViewHolderForPositionByDeadline created new ViewHolder");
LOGD_IF(_DEBUG,"tryGetViewHolderForPositionByDeadline created new ViewHolder");
}
}
@ -3959,10 +3959,8 @@ RecyclerView::ViewHolder* RecyclerView::Recycler::tryGetViewHolderForPositionByD
// do not update unless we absolutely have to.
holder->mPreLayoutPosition = position;
} else if (!holder->isBound() || holder->needsUpdate() || holder->isInvalid()) {
if (_DEBUG && holder->isRemoved()) {
LOGE("Removed holder should be bound and it should"
LOGE_IF(_DEBUG && holder->isRemoved(),"Removed holder should be bound and it should"
" come here only in pre-layout. Holder: %p",holder);
}
const int offsetPosition = mRV->mAdapterHelper->findPositionOffset(position);
bound = tryBindViewHolderByDeadline(*holder, offsetPosition, position, deadlineNs);
}
@ -4057,9 +4055,9 @@ void RecyclerView::Recycler::recycleAndClearCachedViews() {
}
void RecyclerView::Recycler::recycleCachedViewAt(int cachedViewIndex) {
LOGD("Recycling cached view at index %d" ,cachedViewIndex);
LOGD_IF(_DEBUG,"Recycling cached view at index %d" ,cachedViewIndex);
ViewHolder* viewHolder = mCachedViews.at(cachedViewIndex);
LOGD("CachedViewHolder to be recycled:%p ", viewHolder);
LOGD_IF(_DEBUG,"CachedViewHolder to be recycled:%p ", viewHolder);
addViewHolderToRecycledViewPool(*viewHolder, true);
mCachedViews.erase(mCachedViews.begin()+cachedViewIndex);//remove(cachedViewIndex);
}
@ -4279,7 +4277,7 @@ RecyclerView::ViewHolder* RecyclerView::Recycler::getScrapOrHiddenOrCachedHolder
if (!dryRun) {
mCachedViews.erase(mCachedViews.begin()+i);//remove(i);
}
LOGD("getScrapOrHiddenOrCachedHolderForPosition(%d) found match in cache:%p",position,holder);
LOGD_IF(_DEBUG,"getScrapOrHiddenOrCachedHolderForPosition(%d) found match in cache:%p",position,holder);
return holder;
}
}
@ -4349,7 +4347,7 @@ void RecyclerView::Recycler::dispatchViewRecycled(ViewHolder& holder) {
if (mRV->mState != nullptr) {
mRV->mViewInfoStore->removeViewHolder(&holder);
}
LOGD("dispatchViewRecycled: %p" ,&holder);
LOGD_IF(_DEBUG,"dispatchViewRecycled: %p" ,&holder);
}
void RecyclerView::Recycler::onAdapterChanged(Adapter* oldAdapter, Adapter* newAdapter,

View File

@ -9,7 +9,7 @@ class StaggeredGridLayoutManager:public RecyclerView::LayoutManager{
private:
static constexpr float MAX_SCROLL_FACTOR = 1.f / 3.f;
public:
static constexpr bool _DEBUG = true;
static constexpr bool _DEBUG = false;
static constexpr int HORIZONTAL = RecyclerView::HORIZONTAL;
static constexpr int VERTICAL = RecyclerView::VERTICAL;
static constexpr int GAP_HANDLING_NONE = 0;