Created
June 27, 2017 17:51
-
-
Save Bakterija/5b38997be51a5e9c8c6b383a7c575058 to your computer and use it in GitHub Desktop.
RecycleView line splitting behavior exampl app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from kivy.properties import NumericProperty, ListProperty, StringProperty | |
from time import time | |
import copy | |
class LineSplitBehavior(object): | |
split_text_key = StringProperty('text') | |
split_text_indent = NumericProperty(4) | |
chars_per_line = NumericProperty(100) | |
_unsplit_data = ListProperty() | |
def __init__(self, **kwargs): | |
super(LineSplitBehavior, self).__init__(**kwargs) | |
self.fbind('chars_per_line', self.line_split_reload) | |
def set_data(self, data_full, update_unsplitted=True): | |
if update_unsplitted: | |
if data_full: | |
key = self.split_text_key | |
self._unsplit_data = [copy.copy(x) for x in data_full] | |
else: | |
self._unsplit_data = [] | |
if data_full: | |
data_full = self.get_line_split_data(data_full) | |
try: | |
super(LineSplitBehavior, self).set_data(data_full) | |
except AttributeError: | |
self.data = data_full | |
def get_line_split_data(self, data_full): | |
new_data0 = [] | |
new_data = [] | |
cpl = self.chars_per_line | |
key = self.split_text_key | |
# Do fast splitting with new line characters before doing word | |
# length calculations | |
for x in data_full: | |
split_text = x[key].splitlines() | |
if len(split_text) > 1: | |
for text in split_text: | |
new_dict = copy.copy(x) | |
new_dict[key] = text | |
new_data0.append(new_dict) | |
else: | |
new_data0.append(x) | |
for x in new_data0: | |
# If text does not fit in one line, start splitting it | |
if len(x[key]) > cpl: | |
words = x[key].split(' ') | |
new_lines = [] | |
new_line = '' | |
for word in words: | |
len_line = len(new_line) | |
len_word = len(word) | |
# When word fits in line character limit, | |
# add it to current line | |
if len_word + len_line < cpl: | |
if new_line: | |
new_line = '%s %s' % (new_line, word) | |
else: | |
new_line = word | |
# When word does not fit in line character limit | |
# append current line and start a new line | |
else: | |
new_lines.append(new_line) | |
new_line = '' | |
# When word fits in the new empty line, add it | |
if len_word < cpl: | |
if new_line: | |
new_line = '%s %s' % (new_line, word) | |
else: | |
new_line = word | |
# When word is longer then character limit, | |
# split it and add multiple lines | |
else: | |
# Calculate line count | |
split_parts = float(len_word) / float(cpl) | |
split_remain = split_parts % int(split_parts) | |
if split_remain: | |
split_parts = int(split_parts) + 1 | |
else: | |
split_parts = int(split_parts) | |
# Split word into calculated line count | |
word_split = [ | |
word[cpl*i:cpl*(i+1)] for i in range( | |
split_parts) | |
] | |
# Add parts of split word to new_lines | |
if split_remain: | |
for word in word_split[:-1]: | |
new_lines.append(word) | |
new_line = word | |
else: | |
for word in word_split: | |
new_lines.append(word) | |
# Add any remaining text | |
if new_line: | |
new_lines.append(new_line) | |
# Make data copies and put in text for each line | |
for new_line in new_lines: | |
new_dict = copy.copy(x) | |
new_dict[key] = new_line | |
new_data.append(new_dict) | |
else: | |
# Skip splitting for short text and append the data | |
new_data.append(x) | |
return new_data | |
def line_split_reload(self, _, chars_per_line): | |
self.set_data(self._unsplit_data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from kivy.uix.recycleview import RecycleView | |
from kivy.uix.floatlayout import FloatLayout | |
from kivy.properties import NumericProperty | |
from line_split import LineSplitBehavior | |
from kivy.app import runTouchApp | |
from kivy.lang import Builder | |
from kivy.clock import Clock | |
from kivy.logger import Logger | |
from random import randrange | |
from kivy.metrics import cm | |
from time import time | |
randata = '''Resources exquisite set arranging moonlight cuddle him household had. Months had too ham cousin remove far spirit. She procuring the why performed continual improving. Civil songs so large shade in cause. Lady an mr here must neat sold. Children greatest ye extended delicate of. No elderly passage earnest as in removed winding or. | |
Shot what able cold new the see hold. Friendly as an betrayed formerly he. Morning because as to society behaved moments. Put ladies design mrs sister was. Play on hill felt john no gate. Am passed figure to marked in. Prosperous middletons is ye inhabiting as assistance me especially. For looking two cousins regular amongst. | |
Carriage quitting securing be appetite it declared. High eyes kept so busy feel call in. Would day nor ask walls known. But preserved advantage are but and certainty earnestly enjoyment. Passage weather as up am exposed. And natural related man subject. Eagerness get situation his was delighted. | |
Compliment interested discretion estimating on stimulated apartments oh. Dear so sing when in find read of call. As distrusts behaviour abilities defective is. Never at water me might. On formed merits hunted unable merely by mr whence or. Possession the unpleasing simplicity her uncommonly. | |
Sportsman delighted improving dashwoods gay instantly happiness six. Ham now amounted absolute not mistaken way pleasant whatever. At an these still no dried folly stood thing. Rapid it on hours hills it seven years. If polite he active county in spirit an. Mrs ham intention promotion engrossed assurance defective. Confined so graceful building opinions whatever trifling in. Insisted out differed ham man endeavor expenses. At on he total their he songs. Related compact effects is on settled do. | |
Pasture he invited mr company shyness. But when shot real her. Chamber her observe visited removal six sending himself boy. At exquisite existence if an oh dependent excellent. Are gay head need down draw. Misery wonder enable mutual get set oppose the uneasy. End why melancholy estimating her had indulgence middletons. Say ferrars demands besides her address. Blind going you merit few fancy their. | |
Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling. | |
Now for manners use has company believe parlors. Least nor party who wrote while did. Excuse formed as is agreed admire so on result parish. Put use set uncommonly announcing and travelling. Allowance sweetness direction to as necessary. Principle oh explained excellent do my suspected conveying in. Excellent you did therefore perfectly supposing described. | |
Little afraid its eat looked now. Very ye lady girl them good me make. It hardly cousin me always. An shortly village is raising we shewing replied. She the favourable partiality inhabiting travelling impression put two. His six are entreaties instrument acceptance unsatiable her. Amongst as or on herself chapter entered carried no. Sold old ten are quit lose deal his sent. You correct how cuddle several far distant believe journey parties. We shyness enquire uncivil affixed it carried to. | |
Style never met and those among great. At no or september sportsmen he perfectly happiness attending. Depending listening delivered off new she procuring satisfied cuddle existence. Person plenty answer to exeter it if. Law use assistance especially resolution cultivated did out sentiments unsatiable. Way necessary had intention happiness but september delighted his curiosity. Furniture furnished or on strangers neglected remainder engrossed. | |
''' | |
class RootWidget(FloatLayout): | |
font_size = NumericProperty(cm(0.4)) | |
def on_ids(self, _, value): | |
self.fbind('font_size', self.schedule_line_split_update) | |
self.fbind('width', self.schedule_line_split_update) | |
Clock.schedule_once(self.ddd, 0.5) | |
def ddd(self, *args): | |
global randata | |
rv = self.ids.rv | |
randata = randata * 10 | |
randata = randata.splitlines() | |
new_data = [] | |
for x in randata: | |
randcolor = ( | |
float(randrange(20, 255, 1)) / 255.0, | |
float(randrange(20, 255, 1)) / 255.0, | |
float(randrange(20, 255, 1)) / 255.0, | |
1) | |
new_data.append({'text': x, 'background_color': randcolor}) | |
rv.set_data(new_data) | |
def _update_chars_per_line(self, *args): | |
value = int((self.width / self.font_size)) | |
self.ids.rv.chars_per_line = value | |
Logger.info('_update_chars_per_line: %s' % (value)) | |
def schedule_line_split_update(self, *args): | |
Clock.unschedule(self._update_chars_per_line) | |
Clock.schedule_once(self._update_chars_per_line, 0.3) | |
class LnRecycleView(LineSplitBehavior, RecycleView): | |
pass | |
runTouchApp(Builder.load_string(''' | |
<TLabel@Label>: | |
size_hint: 1, None | |
height: int(cm(0.7)) | |
font_size: int(cm(0.6)) | |
font_name: 'RobotoMono-Regular.ttf' | |
text_size: self.width, None | |
padding: 10, 10 | |
background_color: 0.2, 0.2, 0.2, 1 | |
color: 1, 1, 1, 1 | |
canvas.before: | |
Color: | |
rgba: self.background_color | |
Rectangle: | |
pos: self.pos | |
size: self.size | |
RootWidget: | |
LnRecycleView: | |
id: rv | |
size_hint: None, None | |
size: root.size | |
pos: 0, 0 | |
viewclass: 'TLabel' | |
RecycleBoxLayout: | |
orientation: 'vertical' | |
size_hint_y: None | |
default_size_hint: 1, None | |
default_size: None, None | |
height: self.minimum_height | |
spacing: 2 | |
''')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment