def createListLayoutCode(self, listMetadata, index, listView): baseListItemMetadata = listMetadata.mListItemMetadatas[0] # document = XmlUtil.createDocument() rootView = RectView(baseListItemMetadata.bound, None) for rectView in baseListItemMetadata.baseViews: rootView.addChild(rectView) for rectView in baseListItemMetadata.additionalViews: rootView.addChild(rectView) rootView.mChildren.sort( key=cmp_to_key(RectUtil.getTopBottomComparator())) rootView.mChildren.sort( key=cmp_to_key(RectUtil.getLeftRightComparator())) rootElement = XmlUtil.createRoot(self.mDipCalculator, FRAMELAYOUT_ELEMENT, rootView, self.mColorWriter) _map = {} self.addChildrenLayout(rootElement, rootView, listView.x, listView.y, _map) rectViews = RectUtil.toRects(rootView) rectViews.remove(rootView) XmlUtil.writeDocument( rootView, self.mOutProjectFolder + Constants.DEFAULT_LAYOUT_PATH + "/" + Constants.DEFAULT_LAYOUT_LIST_PREFIX + index + ".xml")
def canGenerateListAndGetAdditionListInfo(self, listMetadataRoot): groups = listMetadataRoot.getListItemMetadatas() if len(groups) <= 1: return None newGroups = [] ratio = 0 # only allow list not too much different from each other in size alignmentType = listMetadataRoot.getAlignmentType() if alignmentType == RectUtil.ALIGNMENT_RIGHT: newGroups = [] newGroups.extend(groups) newGroups.sort(key=cmp_to_key(RectUtil.getTopBottomComparator())) ratio = groups[0].bound.height * self.MAX_DISTANCE_RATIO_OF_LIST for i in range(len(groups) - 1): current = groups[i] _next = groups[i + 1] if (RectUtil.verticalDistance(current.bound, _next.bound) > ratio): return None if alignmentType == RectUtil.ALIGNMENT_BOTTOM: newGroups = [] newGroups.extend(groups) newGroups.sort(key=cmp_to_key(RectUtil.getLeftRightComparator())) ratio = groups[0].bound.width * self.MAX_DISTANCE_RATIO_OF_LIST for i in range(len(groups) - 1): current = groups[i] _next = groups[i + 1] if (RectUtil.horizontalDistance(current.bound, _next.bound) > ratio): return None # and all base views of each list item should have same size currentSize = -sys.maxint - 1 for listItem in groups: if (currentSize == -sys.maxint - 1): currentSize = len(listItem.baseViews) elif (currentSize != len(listItem.baseViews)): return None # same addition size currentSize = -sys.maxint - 1 for listItem in groups: if (currentSize == -sys.maxint - 1): currentSize = len(listItem.additionalViews) elif currentSize != len(listItem.additionalViews): return None # We only support more than one base view for listItem in groups: if len(listItem.baseViews) <= 1: return None # They have to be align if alignmentType == RectUtil.ALIGNMENT_RIGHT: for i in range(len(groups) - 1): current = groups[i] _next = groups[i + 1] for currentBase in current.baseViews: for nextBase in _next.baseViews: if (not RectUtil.above(currentBase, nextBase)): return None if alignmentType == RectUtil.ALIGNMENT_BOTTOM: for i in range(len(groups) - 1): current = groups[i] _next = groups[i + 1] for currentBase in current.baseViews: for nextBase in _next.baseViews: if (not RectUtil.onTheLeft(currentBase, nextBase)): return None # We only support base view is image view for now for listItem in groups: for baseView in listItem.baseViews: if (baseView.mType != RectView.VIEW_TYPE_IMAGE): return None # We already check that all additional view has same size sameLevelViews = [] for listItemMetadata in groups: additionalViewRecusive = [] for rectView in listItemMetadata.additionalViews: self.getAllLeaveViewRecusively(additionalViewRecusive, rectView, listItemMetadata.bound.x, listItemMetadata.bound.y) sameLevelViews.add(additionalViewRecusive) # make sure it all overlap and have same type if len(sameLevelViews) <= 1: return None # same recursive addition size currentSize = -sys.maxint - 1 for listItem in sameLevelViews: if (currentSize == -sys.maxint - 1): currentSize = len(listItem) elif currentSize != len(listItem): return None firstList = sameLevelViews[0] for t in firstList: t.overlapFlag = True t.relativeViews.append(t) for i in range(len(sameLevelViews)): for t in firstList: for o in sameLevelViews[i]: if (not o.overlapFlag and RectUtil.intersects(t, o) and o.mType == t.mType): o.overlapFlag = True t.relativeViews.append(o) break # Make sure all items is marked for listItem in sameLevelViews: for r in listItem: if (not r.overlapFlag): return None # Make sure we get all relative view for t in firstList: if len(t.relativeViews) != len(groups): return None return firstList
def createListItemForView(self, rectView, baseLists, defaultThresholdAlignment): # Check to see if there is a list of drawable belong to one view # then we remove this list # We only find one for now matchedBaseLists = [] removedList = [] for drawableList in baseLists: if (RectUtil.containAll(rectView, drawableList)): matchedBaseLists.append(ListWrapper(drawableList)) removedList.append(ListWrapper(drawableList)) # First remove approval list baseLists = [x for x in baseLists if x not in removedList] removedList = [] if len(matchedBaseLists) > 0: for matchedBaseList in matchedBaseLists: # System.out.prln("Found a list of: " + rectView.bound() # + ", list: " + matchedBaseList.size() + ", " # + matchedBaseList) # First make sure these are repeated icons of list items # Make sure they align either LEFT-RIGHT or TOP-BOTTOM checkValidList = False alignmentType = RectUtil.getAlignmentType( matchedBaseList._list, defaultThresholdAlignment) matchedBaseList.alignmentType = alignmentType if (alignmentType == RectUtil.ALIGNMENT_RIGHT): # System.out.prln("Align LEFT and RIGHT") # We sort them vertically matchedBaseList._list.sort( key=cmp_to_key(RectUtil.getTopBottomComparator())) if len(matchedBaseList ) >= Constants.LAYOUT_MIN_ACCEPTABLE_LIST_SIZE: distances = set() for i in range(len(matchedBaseList)): distances.add( RectUtil.verticalDistance( matchedBaseList._list[i + 1], matchedBaseList._list[i])) if len(distances) == 1: # Perfect checkValidList = True elif len(distances) >= 2: # it is okay to have more than 2 distance, but the # different cannot too much # we set here is <= half of the biggest distance satisfy = True lDistances = [] for i in range(len(lDistances) - 1): first = lDistances[i] second = lDistances[i + 1] difference = abs(first - second) if (difference >= max(first, second) / 2): satisfy = False break checkValidList = satisfy else: checkValidList = False if (alignmentType == RectUtil.ALIGNMENT_BOTTOM): # System.out.prln("Align TOP and BOTTOM") # We sort them horizontally matchedBaseList._list.sort( key=cmp_to_key(RectUtil.getLeftRightComparator())) if len(matchedBaseList ) >= Constants.LAYOUT_MIN_ACCEPTABLE_LIST_SIZE: distances = set() for i in range(len(matchedBaseList) - 1): distances.add( RectUtil.horizontalDistance( matchedBaseList._list[i + 1], matchedBaseList._list[i])) if len(distances) == 1: # Perfect checkValidList = True elif len(distances) >= 2: # it is okay to have more than 2 distance, but the # different cannot too much # we set here is <= half of the biggest distance satisfy = True lDistances = [] for i in range(lDistances) - 1: first = lDistances[i] second = lDistances[i + 1] difference = abs(first - second) if (difference >= max(first, second) / 2): satisfy = False break checkValidList = satisfy else: checkValidList = False # Now put them in a groups if (not checkValidList): removedList.append(matchedBaseList) # We only support one list for now, and only allow has the same # size # maxSize = RectUtil # .maxSizeListWrapper(matchedBaseLists) # # for ( ListWrapper list : matchedBaseLists) : # if (list.size() != maxSize) : # removedList.add(list) # # matchedBaseLists = [ x for x in matchedBaseLists if x not in removedList ] # Split list to multiple with different alignment type mapTypeList = {} for listWrapper in matchedBaseLists: ls = mapTypeList[listWrapper.alignmentType] if (ls == None): ls = [] mapTypeList[listWrapper.alignmentType] = ls ls.append(listWrapper) # We have enough base item here already # Now we try to get as much as ImageView base, as possible for entry in mapTypeList: entryKey = [x for x in entry] entryValue = [entry(x) for x in entry] maxSize = RectUtil.maxSizeListWrapper(mapTypeList[entry]) newLists = [] for listWrapper in entryValue: if len(listWrapper) == maxSize: newLists.append(listWrapper) if len(newLists) <= 1: # System.out # .prln("*We need more list here let get the list = size - 1") # We need more list here let get the list = size - 1 for listWrapper in entryValue: if len(listWrapper) == maxSize - 1: newLists.append(listWrapper) self.prepareCreateListView(rectView, newLists, entryKey)
def createListLayoutCode(self, listView, listMetadata, aditionalListViewItemData, index): if len(listMetadata.getListItemMetadatas()) == 0: return baseListItemMetadata = listMetadata.getListItemMetadatas()[0] # Document document = XmlUtil.createDocument() rootView = RectView(baseListItemMetadata.bound, None) for rectView in baseListItemMetadata.baseViews: rootView.addChild(rectView) for rectView in baseListItemMetadata.additionalViews: rootView.addChild(rectView) rootView.mChildren.sort( key=cmp_to_key(RectUtil.getTopBottomComparator())) rootView.mChildren.sort( key=cmp_to_key(RectUtil.getLeftRightComparator())) rootElement = XmlUtil.createRoot(self.mDipCalculator, self.FRAMELAYOUT_ELEMENT, rootView, self.mColorWriter) _map = {} self.addChildrenLayout(rootElement, rootView, listView.getX(), listView.getY(), _map) rectViews = RectUtil.toRects(rootView) rectViews.remove(rootView) viewIdMap = {} # For baseview for rectView in baseListItemMetadata.baseViews: elementInfo = _map[rectView] viewIdMap[rectView] = elementInfo._id # For additionview for rectViewWrapper in aditionalListViewItemData: elementInfo = _map[rectViewWrapper.view] viewIdMap[rectViewWrapper.view] = elementInfo.id # TODO: since we checked already (#getAditionalListViewItemData), all # base view should only image views resourceInfoMap = {} listItemMetadatas = listMetadata.getListItemMetadatas() for listItemMetadata in listItemMetadatas: for baseView in listItemMetadata.baseViews: resourceInfoMap[baseView] = self.getInfoResource(baseView) for rectViewWrapper in aditionalListViewItemData: for viewWrapper in rectViewWrapper.relativeViews: resourceInfoMap[viewWrapper.view] = self.getInfoResource( viewWrapper.view) listMetadata.generateCode(index, listView.getListInfo().xmlId, self.mOutProjectFolder, aditionalListViewItemData, viewIdMap, resourceInfoMap) # We need to store current x, y, w, h of element before we loss # them anotateMap = LayoutFilter.anotate(rootView) layoutFilter = RelativeLayoutFilter() layoutFilter.doFilter(rootView, anotateMap) XmlUtil.writeDocument( rootView, self.mOutProjectFolder + Constants.DEFAULT_LAYOUT_PATH + "/" + Constants.DEFAULT_LAYOUT_LIST_PREFIX + index + ".xml")