make resource reference more compatibale with android

This commit is contained in:
侯歌 2022-03-09 14:05:56 +08:00
parent b9d606f2bb
commit 3e3a837fde
13 changed files with 87 additions and 75 deletions

View File

@ -38,22 +38,6 @@ const std::string Assets::getTheme()const{
return mThemeName;
}
std::string Assets::normalizeProperty(const std::string&pkg,const std::string&property){
std::string value= property;
size_t pos=value.find('?');
bool hasat=false;
if(pos!=std::string::npos){
value.erase(pos,1); hasat=true;
}
if((pos=value.find('@'))!=std::string::npos){
value.erase(pos,1); hasat=true;
}
if( hasat && (value.find(':')==std::string::npos) && (value.find('/')!=std::string::npos) ){
value= pkg+":"+value;
}
return value;
}
void Assets::setTheme(const std::string&theme){
auto it=mStyles.find(theme);
if(it!=mStyles.end()){
@ -91,8 +75,8 @@ void Assets::parseItem(const std::string&package,const std::vector<std::string>&
if(styleParent.length())it->second.add("parent",styleParent);
LOGV("style:%s",styleName.c_str());
}
std::string normalizedValue = normalizeProperty(package,value);
it->second.add(atts[1].getString("name"),value);
const std::string normalizedValue = AttributeSet::normalize(package,value);
it->second.add(atts[1].getString("name"),normalizedValue);
}else if(tag0.compare("array")==0){
const std::string name=atts[0].getString("name");
auto it=mArraies.find(name);
@ -155,12 +139,10 @@ static bool guessExtension(ZIPArchive*pak,std::string&ioname){
void Assets::parseResource(const std::string&fullResId,std::string*res,std::string*ns)const{
std::string relname,pkg=mName;
std::string fullid = fullResId;
size_t pos=fullid.find('@');
if(pos!=std::string::npos){//remove @+
fullid = fullid.erase(pos,1);
pos=fullid.find('+');
if(pos!=std::string::npos)fullid = fullid.erase(pos,1);
}
size_t pos=fullid.find_last_of("@+");
if(pos!=std::string::npos)fullid =fullid.erase(0,pos+1);
pos=fullid.find(":");
if(pos != std::string::npos){
pkg = fullid.substr(0,pos);
@ -189,11 +171,14 @@ ZIPArchive*Assets::getResource(const std::string&fullResId,std::string*relativeR
return pak;
}
std::unique_ptr<std::istream> Assets::getInputStream(const std::string&fullresid){
std::unique_ptr<std::istream> Assets::getInputStream(const std::string&fullresid,std::string*outpkg){
std::string resname;
ZIPArchive*pak=getResource(fullresid,&resname);
std::istream*stream=pak?pak->getInputStream(resname):nullptr;
std::unique_ptr<std::istream>is(stream);
if(outpkg&&pak){
parseResource(fullresid,nullptr,outpkg);
}
return is;
}
@ -240,6 +225,7 @@ int Assets::getId(const std::string&key)const{
if(key.length()&&(key.find('/')==std::string::npos))
return TextUtils::strtol(key);
parseResource(key,&resid,&pkg);
auto it=mIDS.find(pkg+":"+resid);
return it==mIDS.end()?-1:it->second;
}
@ -319,7 +305,7 @@ Drawable* Assets::getDrawable(const std::string&fullresid){
int Assets::getColor(const std::string&refid){
std::string pkg,name=refid;
parseResource(name,nullptr,&pkg);
normalizeProperty(pkg,name);
name=AttributeSet::normalize(pkg,name);
auto it = mColors.find(name);
if(it!=mColors.end()){
return nonstd::get<int>(it->second);

View File

@ -26,7 +26,6 @@ private:
void parseResource(const std::string&fullresid,std::string*res,std::string*ns)const;
void parseItem(const std::string&package,const std::vector<std::string>&tag,std::vector<AttributeSet>atts,const std::string&value);
ZIPArchive*getResource(const std::string & fullresid, std::string* relativeResid)const;
std::string normalizeProperty(const std::string&pkg,const std::string&value);
protected:
std::string mName;
DisplayMetrics mDisplayMetrics;
@ -47,7 +46,7 @@ public:
const std::string& getString(const std::string&id,const std::string&lan="")override;
RefPtr<Cairo::ImageSurface> getImage(const std::string&resname)override;
std::vector<std::string> getStringArray(const std::string&resname,const std::string&arrayname)const;
std::unique_ptr<std::istream> getInputStream(const std::string&resname)override;
std::unique_ptr<std::istream> getInputStream(const std::string&resname,std::string*outpkg=nullptr)override;
Drawable * getDrawable(const std::string&resid)override;
int getColor(const std::string&resid)override;
int getArray(const std::string&resname,std::vector<std::string>&)override;

View File

@ -32,6 +32,22 @@ void AttributeSet::setContext(Context*ctx){
mContext=ctx;
}
std::string AttributeSet::normalize(const std::string&pkg,const std::string&property){
std::string value= property;
size_t pos=value.find('?');
bool hasat=false;
if(pos!=std::string::npos){
value.erase(pos,1); hasat=true;
}
if((pos=value.find('@'))!=std::string::npos){
value.erase(pos,1); hasat=true;
}
if( hasat && (value.find(':')==std::string::npos) && (value.find('/')!=std::string::npos) ){
value= pkg+":"+value;
}
return value;
}
int AttributeSet::set(const char*atts[],int size){
int rc=0;
for(int i=0;atts[i]&&(size==0||i<size);i+=2,rc+=1){
@ -60,7 +76,9 @@ 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;
mAttrs.insert(std::make_pair<const std::string,std::string>(key.c_str(),value.c_str()));
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),value.c_str()));
return true;
}
@ -197,7 +215,7 @@ int AttributeSet::getLayoutDimension(const std::string&key,int def)const{
}
void AttributeSet::dump()const{
for(auto it=mAttrs.begin();it!=mAttrs.end();it++){
LOGD("%s:%s",it->first.c_str(),it->second.c_str());
LOGD("%s = %s",it->first.c_str(),it->second.c_str());
}
}

View File

@ -15,6 +15,7 @@ public:
bool hasAttribute(const std::string&key)const;
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();
int inherit(const AttributeSet&other);
const std::string getAttributeValue(const std::string&key)const;

View File

@ -26,7 +26,7 @@ public:
static RefPtr<Cairo::ImageSurface> loadImage( std::istream&istream ){
return Cairo::ImageSurface::create_from_stream(istream);
}
virtual std::unique_ptr<std::istream>getInputStream(const std::string&)=0;
virtual std::unique_ptr<std::istream>getInputStream(const std::string&,std::string*outpkg=nullptr)=0;
virtual RefPtr<Cairo::ImageSurface> getImage(const std::string&resname)=0;
virtual Drawable* getDrawable(const std::string&resid)=0;
Drawable* getDrawable(const AttributeSet&atts,const std::string&key){

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:cdroid="http://schemas.android.com/apk/res/android">
<item cdroid:id="@+cdroid:id/background">
<item cdroid:id="@+id/background">
<shape cdroid:shape="rectangle">
<corners cdroid:radius="5dip" />
<gradient
@ -14,7 +14,7 @@
</shape>
</item>
<item cdroid:id="@+cdroid:id/progress">
<item cdroid:id="@+id/progress">
<clip>
<shape cdroid:shape="rectangle">
<corners cdroid:radius="5dip" />
@ -29,7 +29,7 @@
</clip>
</item>
<item cdroid:id="@+cdroid:id/secondaryProgress">
<item cdroid:id="@+id/secondaryProgress">
<clip>
<shape cdroid:shape="rectangle">
<corners cdroid:radius="5dip" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:cdroid="http://schemas.cdroid.com/apk/res/cdroid"
cdroid:id="@cdroid:id/parentPanel"
cdroid:id="@id/parentPanel"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:orientation="vertical"
@ -10,12 +10,12 @@
cdroid:paddingStart="3dip"
cdroid:paddingEnd="1dip">
<LinearLayout cdroid:id="@cdroid:id/topPanel"
<LinearLayout cdroid:id="@id/topPanel"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:minHeight="54dip"
cdroid:orientation="vertical">
<LinearLayout cdroid:id="@cdroid:id/title_template"
<LinearLayout cdroid:id="@id/title_template"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:orientation="horizontal"
@ -24,16 +24,16 @@
cdroid:layout_marginBottom="9dip"
cdroid:layout_marginStart="10dip"
cdroid:layout_marginEnd="10dip">
<ImageView cdroid:id="@cdroid:id/icon"
<ImageView cdroid:id="@id/icon"
cdroid:layout_width="wrap_content"
cdroid:layout_height="wrap_content"
cdroid:layout_gravity="top"
cdroid:paddingTop="6dip"
cdroid:paddingEnd="10dip"
cdroid:src="@cdroid:mipmap/ic_dialog_info" />
cdroid:src="@mipmap/ic_dialog_info" />
<!--com.cdroid.internal.widget.DialogTitle-->
<TextView
cdroid:id="@cdroid:id/alertTitle"
cdroid:id="@id/alertTitle"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
style="?cdroid:attr/textAppearanceLarge"
@ -41,17 +41,17 @@
cdroid:ellipsize="end"
cdroid:textAlignment="viewStart" />
</LinearLayout>
<ImageView cdroid:id="@cdroid:id/titleDivider"
<ImageView cdroid:id="@id/titleDivider"
cdroid:layout_width="match_parent"
cdroid:layout_height="1dip"
cdroid:visibility="gone"
cdroid:scaleType="fitXY"
cdroid:gravity="fill_horizontal"
cdroid:src="@cdroid:mipmap/divider_horizontal_dark" />
cdroid:src="@mipmap/divider_horizontal_dark" />
<!-- If the client uses a customTitle, it will be added here. -->
</LinearLayout>
<LinearLayout cdroid:id="@cdroid:id/contentPanel"
<LinearLayout cdroid:id="@id/contentPanel"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:layout_weight="1"
@ -72,18 +72,18 @@
</ScrollView>
</LinearLayout>
<FrameLayout cdroid:id="@cdroid:id/customPanel"
<FrameLayout cdroid:id="@id/customPanel"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:layout_weight="1">
<FrameLayout cdroid:id="@cdroid:id/custom"
<FrameLayout cdroid:id="@id/custom"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:paddingTop="5dip"
cdroid:paddingBottom="5dip" />
</FrameLayout>
<LinearLayout cdroid:id="@cdroid:id/buttonPanel"
<LinearLayout cdroid:id="@id/buttonPanel"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:minHeight="54dip"
@ -97,34 +97,34 @@
cdroid:paddingStart="2dip"
cdroid:paddingEnd="2dip"
cdroid:measureWithLargestChild="true">
<LinearLayout cdroid:id="@cdroid:id/leftSpacer"
<LinearLayout cdroid:id="@id/leftSpacer"
cdroid:layout_weight="0.25"
cdroid:layout_width="0dip"
cdroid:layout_height="wrap_content"
cdroid:orientation="horizontal"
cdroid:visibility="gone" />
<Button cdroid:id="@cdroid:id/button1"
<Button cdroid:id="@id/button1"
cdroid:layout_width="0dip"
cdroid:layout_gravity="start"
cdroid:layout_weight="1"
style="?cdroid:attr/buttonBarButtonStyle"
cdroid:maxLines="2"
cdroid:layout_height="wrap_content" />
<Button cdroid:id="@cdroid:id/button3"
<Button cdroid:id="@id/button3"
cdroid:layout_width="0dip"
cdroid:layout_gravity="center_horizontal"
cdroid:layout_weight="1"
style="?cdroid:attr/buttonBarButtonStyle"
cdroid:maxLines="2"
cdroid:layout_height="wrap_content" />
<Button cdroid:id="@cdroid:id/button2"
<Button cdroid:id="@id/button2"
cdroid:layout_width="0dip"
cdroid:layout_gravity="end"
cdroid:layout_weight="1"
style="?cdroid:attr/buttonBarButtonStyle"
cdroid:maxLines="2"
cdroid:layout_height="wrap_content" />
<LinearLayout cdroid:id="@cdroid:id/rightSpacer"
<LinearLayout cdroid:id="@id/rightSpacer"
cdroid:layout_width="0dip"
cdroid:layout_weight="0.25"
cdroid:layout_height="wrap_content"

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:cdroid="http://schemas.android.com/apk/res/android"
cdroid:layout_width="wrap_content" cdroid:layout_height="match_parent">
<ProgressBar cdroid:id="@cdroid:+id/progress"
style="?cdroid:attr/progressBarStyleHorizontal"
<ProgressBar cdroid:id="@+id/progress"
style="?attr/progressBarStyleHorizontal"
cdroid:layout_width="match_parent"
cdroid:layout_height="wrap_content"
cdroid:layout_marginTop="12dip"
@ -11,23 +11,23 @@
cdroid:layout_marginEnd="10dip"
cdroid:layout_centerHorizontal="true" />
<TextView
cdroid:id="@cdroid:+id/progress_percent"
cdroid:id="@+id/progress_percent"
cdroid:layout_width="wrap_content"
cdroid:layout_height="wrap_content"
cdroid:paddingBottom="12dip"
cdroid:layout_marginStart="10dip"
cdroid:layout_marginEnd="10dip"
cdroid:layout_alignParentStart="true"
cdroid:layout_below="@cdroid:id/progress"
cdroid:layout_below="@id/progress"
/>
<TextView
cdroid:id="@cdroid:+id/progress_number"
cdroid:id="@+id/progress_number"
cdroid:layout_width="wrap_content"
cdroid:layout_height="wrap_content"
cdroid:paddingBottom="12dip"
cdroid:layout_marginStart="10dip"
cdroid:layout_marginEnd="10dip"
cdroid:layout_alignParentEnd="true"
cdroid:layout_below="@cdroid:id/progress"
cdroid:layout_below="@id/progress"
/>
</RelativeLayout>

View File

@ -272,7 +272,7 @@
</style>
<style name="Widget.ExpandableListView.White">
<item name="childDivider">@drawable/divider_horizontal_bright_opaque</item>
<item name="childDivider">@mipmap/divider_horizontal_bright_opaque</item>
</style>
<style name="Widget.FragmentBreadCrumbs">
@ -396,12 +396,12 @@
<style name="Widget.ListView.White" parent="Widget.AbsListView">
<item name="listSelector">@drawable/list_selector_background</item>
<item name="cacheColorHint">?attr/colorBackgroundCacheHint</item>
<item name="divider">@drawable/divider_horizontal_bright_opaque</item>
<item name="divider">@mipmap/divider_horizontal_bright_opaque</item>
</style>
<style name="Widget.ListView.DropDown">
<item name="cacheColorHint">@null</item>
<item name="divider">@drawable/divider_horizontal_bright_opaque</item>
<item name="divider">@mipmap/divider_horizontal_bright_opaque</item>
</style>
<style name="Widget.ListView.Menu" parent="Widget.Holo.ListView">

View File

@ -111,7 +111,7 @@ please see themes_device_defaults.xml.
<item name="textAppearanceButton">@style/TextAppearance.Widget.Button</item>
<item name="editTextColor">@color/primary_text_light</item>
<item name="editTextBackground">@cdroid:drawable/edit_text</item>
<item name="editTextBackground">@drawable/edit_text</item>
<item name="candidatesTextStyleSpans">@string/candidates_style</item>
@ -149,17 +149,17 @@ please see themes_device_defaults.xml.
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
<item name="listDivider">@cdroid:mipmap/divider_horizontal_dark</item>
<item name="listSeparatorTextViewStyle">@cdroid:style/Widget.TextView.ListSeparator</item>
<item name="listDivider">@mipmap/divider_horizontal_dark</item>
<item name="listSeparatorTextViewStyle">@style/Widget.TextView.ListSeparator</item>
<item name="listChoiceIndicatorSingle">@drawable/btn_radio</item>
<item name="listChoiceIndicatorMultiple">@drawable/btn_check</item>
<item name="listChoiceBackgroundIndicator">@cdroid:drawable/list_selector_background</item>
<item name="listChoiceBackgroundIndicator">@drawable/list_selector_background</item>
<item name="activatedBackgroundIndicator">@drawable/activated_background</item>
<item name="listDividerAlertDialog">@cdroid:mipmap/divider_horizontal_bright</item>
<item name="listDividerAlertDialog">@mipmap/divider_horizontal_bright</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
<item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
@ -436,7 +436,7 @@ please see themes_device_defaults.xml.
<item name="accessibilityFocusedDrawable">@drawable/view_accessibility_focused</item>
<!-- Autofilled highlight drawable -->
<item name="autofilledHighlight">@cdroid:drawable/autofilled_highlight</item>
<item name="autofilledHighlight">@drawable/autofilled_highlight</item>
<!-- Lighting and shadow properties -->
<item name="lightY">@dimen/light_y</item>

View File

@ -5,6 +5,7 @@
#include <cdlog.h>
#include <string.h>
#include <fstream>
#include <iomanip>
namespace cdroid{
@ -58,17 +59,19 @@ bool LayoutInflater::registInflater(const std::string&name,const std::string&def
View* LayoutInflater::inflate(const std::string&resource,ViewGroup*root,bool attachToRoot){
View*v=nullptr;
if(mContext){
std::unique_ptr<std::istream>stream=mContext->getInputStream(resource);
if(stream && stream->good()) v=inflate(*stream,root,attachToRoot && (root!=nullptr));
std::string package;
std::unique_ptr<std::istream>stream=mContext->getInputStream(resource,&package);
if(stream && stream->good()) v=inflate(package,*stream,root,attachToRoot && (root!=nullptr));
}else{
std::ifstream fin(resource);
v=inflate(fin,root,root!=nullptr);
v=inflate(resource,fin,root,root!=nullptr);
}
return v;
}
typedef struct{
Context*ctx;
std::string package;
XML_Parser parser;
bool attachToRoot;
ViewGroup* root;
@ -80,10 +83,13 @@ typedef struct{
static void startElement(void *userData, const XML_Char *name, const XML_Char **satts){
WindowParserData*pd=(WindowParserData*)userData;
AttributeSet atts(satts);
AttributeSet atts;
LayoutInflater::ViewInflater inflater=LayoutInflater::getInflater(name);
ViewGroup*parent=pd->root;
atts.setContext(pd->ctx);
for(int i=0;satts[i];i+=2){
atts.add(satts[i],AttributeSet::normalize(pd->package,satts[i+1]));
}
if(pd->views.size())
parent=dynamic_cast<ViewGroup*>(pd->views.back());
if(strcmp(name,"merge")==0){
@ -117,7 +123,7 @@ static void startElement(void *userData, const XML_Char *name, const XML_Char **
pd->parsedView++;
pd->flags.push_back(0);
pd->views.push_back(v);
LOGV("%p:%08x [%s] %s",v,v->getId(),name,stname.c_str());
LOG(VERBOSE)<<std::setw(pd->views.size()*8)<<v<<":"<<v->getId()<<"["<<name<<"]"<<stname;
if( parent){//(parent && (parent==pd->root) && pd->attachToRoot )||(parent!=pd->root)){
LayoutParams*lp=parent->generateLayoutParams(atts);
parent->addViewInLayout(v,-1,lp,true);
@ -137,14 +143,16 @@ static void endElement(void *userData, const XML_Char *name){
pd->views.pop_back();
}
View* LayoutInflater::inflate(std::istream&stream,ViewGroup*root,bool attachToRoot){
View* LayoutInflater::inflate(const std::string&package,std::istream&stream,ViewGroup*root,bool attachToRoot){
int len=0;
char buf[256];
XML_Parser parser=XML_ParserCreateNS(nullptr,' ');
WindowParserData pd={mContext,parser};
WindowParserData pd;
ULONGLONG tstart=SystemClock::uptimeMillis();
pd.ctx = mContext;
pd.root = root;
pd.package=package;
pd.parsedView = 0;
pd.returnedView= nullptr;
pd.attachToRoot = attachToRoot;

View File

@ -17,7 +17,7 @@ private:
static INFLATERMAPPER& getInflaterMap();
static STYLEMAPPER& getStyleMap();
protected:
View* inflate(std::istream&stream,ViewGroup*root,bool attachToRoot);
View* inflate(const std::string&package,std::istream&stream,ViewGroup*root,bool attachToRoot);
public:
static LayoutInflater*from(Context*context);
static ViewInflater getInflater(const std::string&);

View File

@ -1246,7 +1246,7 @@ bool ViewPager::onInterceptTouchEvent(MotionEvent& ev){
// direction to be counted as a drag... abort
// any attempt to drag horizontally, to work correctly
// with children that have scrolling containers.
LOGD("Starting unable to drag! yDiff=%f mTouchSlop=%d",yDiff,mTouchSlop);
LOGV("Starting unable to drag! yDiff=%f mTouchSlop=%d",yDiff,mTouchSlop);
mIsUnableToDrag = true;
}
if (mIsBeingDragged) {