Skip to content

Commit 415de3b

Browse files
author
Matteljay
committed
button improvements enter key supported
1 parent 0e5fb97 commit 415de3b

File tree

3 files changed

+66
-22
lines changed

3 files changed

+66
-22
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
## Getting started
1616

1717
LabelPush is a lightweight label printing application written in Python.
18+
It is built to be fast and simple to use. The CUPS printing system is
19+
used. So make sure the printer is correctly installed with all default
20+
settings such as label size. This link should take you to your local
21+
settings: [CUPS-localhost](http://localhost:631/printers/)
22+
23+
## Installation
24+
1825
Two libraries, the Kivy cross-platform GUI and Pillow imaging library
1926
are required for LabelPush. Arch Linux (Manjaro) is very up-to-date,
2027
installation will be very quick. This will be briefly explained below.

labelpush.py

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525
# SOFTWARE.
2626
#
27-
# Release version: 2018.11.17
2827
# Donate if you find this app useful, educational or you like to motivate more projects like this.
2928
#
3029
# XMR: 4B6YQvbL9jqY3r1cD3ZvrDgGrRpKvifuLVb5cQnYZtapWUNovde7K5rc1LVGw3HhmTiijX21zHKSqjQtwxesBEe6FhufRGS
@@ -42,14 +41,15 @@
4241
from kivy.lang import Builder
4342
from kivy.config import Config
4443
from kivy.uix.behaviors import ButtonBehavior
44+
from kivy.uix.textinput import TextInput
4545
from kivy.uix.image import Image
4646
from kivy.properties import ConfigParser
4747
# Python Imaging Library
4848
from kivy.core.image import Image as CoreImage
4949
from PIL import Image as pilImage
5050
from PIL import ImageDraw, ImageFont, PILLOW_VERSION
5151
# Threading
52-
from kivy.clock import mainthread
52+
from kivy.clock import mainthread, Clock
5353
from threading import Thread, Event
5454
from time import sleep
5555
import datetime
@@ -63,6 +63,7 @@
6363
import shutil
6464

6565
name = 'labelpush'
66+
version = '2018.11.26'
6667
def_iconfiles = [
6768
os.path.join(sys.prefix, 'local/share/pixmaps/labelpush.png'),
6869
os.path.join(sys.prefix, 'share/pixmaps/labelpush.png'),
@@ -98,7 +99,8 @@
9899
{ "type": "bool", "title": "More image cycle modi", "desc": "When clicking the image, you get 4 print choices instead of 2",
99100
"section": "settings", "key": "multimod" },
100101
{ "type": "numeric", "title": "Font height correction", "desc": "For adjusting the vertical offset, use caps when in doubt",
101-
"section": "settings", "key": "focorr" }
102+
"section": "settings", "key": "focorr" },
103+
{ "type": "title", "title": "Release version: ''' + version + ''' - Matteljay" }
102104
]'''
103105
Builder.load_string('''
104106
<RootWidget>:
@@ -115,18 +117,15 @@
115117
padding: 30
116118
spacing: 30
117119
orientation: 'vertical'
118-
TextInput:
120+
TextInput_multi_retsel:
119121
id: id_textbox
120122
text: ''
121-
multiline: True
122123
font_size: 20
123124
focus: True
124-
unfocus_on_touch: False
125-
text_validate_unfocus: False
126-
input_filter: root.textbox_filter
125+
on_text_validate: root.press_btn_PRINT()
127126
ImageButton:
128127
id: id_beeld
129-
on_press: root.btn_IMG()
128+
on_press: root.btn_IMG(self)
130129
allow_stretch: True
131130
keep_ratio: True
132131
canvas.before:
@@ -150,6 +149,7 @@
150149
on_press: root.press_btn_PRINT()
151150
text: 'PRINT'
152151
font_size: 20
152+
background_down: self.background_normal
153153
''')
154154

155155
class GLO(): # global variables: status and config
@@ -160,6 +160,9 @@ class GLO(): # global variables: status and config
160160
confpath = '' # will hold the system path to the user's config file
161161
font_pool = {} # used as a dict and will be populated with fontname/fontpath pairs
162162
immode = 0
163+
processed_immode = 0
164+
processed_text = ''
165+
dispatch_printaction = False
163166
defaultcfg = def_defaultcfg
164167
jsondata = def_jsondata
165168

@@ -171,26 +174,54 @@ def fatal_lockdown(txt):
171174
class ImageButton(ButtonBehavior, Image):
172175
pass
173176

174-
class RootWidget(BoxLayout):
175-
imbytes = ''
176-
def textbox_filter(self, substring, from_undo):
177+
class TextInput_multi_retsel(TextInput):
178+
multiline = True
179+
unfocus_on_touch = False
180+
text_validate_unfocus = False
181+
def keyboard_on_key_down(self, window, keycode, text, modifiers):
182+
if keycode[0] in (9, 10, 11, 12): # hor tab, line feed, vert tab, form feed
183+
keycode = (None, None)
184+
elif keycode[0] == 13:
185+
keycode = (None, None)
186+
self.dispatch('on_text_validate')
187+
return super(type(self), self).keyboard_on_key_down(window, keycode, text, modifiers)
188+
def insert_text(self, substring, from_undo=False):
177189
ret = substring
178190
if len(substring) == 1: # probably key press or single paste
179-
if substring in '\t\n\r\f\v':
191+
if substring in '\t\r\v\f\n':
180192
ret = ''
181193
else: # probably paste from clipboard
182-
ret = re.sub(r'[\t\n\r\f\v]', '', substring)
183-
return ret
184-
def press_btn_PRINT(self):
194+
ret = re.sub(r'[\t\r\v\f\n]', '', substring)
195+
return super(type(self), self).insert_text(ret, from_undo)
196+
197+
class RootWidget(BoxLayout):
198+
imbytes = ''
199+
def execute_print(self):
185200
self.textbox.select_all()
186201
lpname = ConfigParser.get_configparser('app').get('settings', 'lpname')
187-
if not lpname or lpname == 'default': #hasattr(CONF, 'lpname')
202+
if not lpname or lpname == 'default':
188203
p = Popen(['lp'], stdin=PIPE)
189204
else:
190205
p = Popen(['lp', '-d', lpname], stdin=PIPE)
191206
p.stdin.write(self.imbytes)
192207
p.stdin.close()
193-
def btn_IMG(self):
208+
def press_btn_PRINT(self):
209+
btn = self.btn_PRINT
210+
# spam control: alternative to Kivy's min_state_time button
211+
if btn.background_color[1] == 2: return
212+
btn.background_color[1] = 2
213+
def greenback(dt): btn.background_color[1] = 1
214+
Clock.schedule_once(greenback, 0.5)
215+
# spam control: check if finished drawing
216+
if GLO.processed_text != btn.text:
217+
GLO.dispatch_printaction = True
218+
return
219+
self.execute_print()
220+
def btn_IMG(self, btn):
221+
# spam control: wait for cycle to get drawn
222+
if GLO.processed_immode != GLO.immode:
223+
return
224+
# cycle image
194225
GLO.immode += 1
195226
config = ConfigParser.get_configparser('app')
196227
multimod = int(config.get('settings', 'multimod'))
@@ -216,6 +247,12 @@ def update_elements(self, im):
216247
self.statuslabel.text = 'First time run, welcome! Wrote config {} ---> press F1 to see the settings page'.format(GLO.confpath)
217248
else:
218249
self.statuslabel.text = 'Ready to print, click the image to cycle'
250+
# allow button to work instantly
251+
GLO.processed_immode = GLO.immode
252+
GLO.processed_text = self.textbox.text
253+
if GLO.dispatch_printaction:
254+
GLO.dispatch_printaction = False
255+
self.execute_print()
219256
def canvas_drawtext(self, canvas_img, maxw, maxh, txt):
220257
# read config settings
221258
# alternative: config = App.get_running_app().config
@@ -276,7 +313,7 @@ def clock_thread(self):
276313
# super(RightClickTextInput,self).on_touch_down(touch)
277314
# if touch.button == 'right':
278315
#def __init__(self, **kwargs):
279-
# super(RootWidget, self).__init__(**kwargs)
316+
# super(type(self), self).__init__(**kwargs)
280317
# self.textbox.text = 'example'
281318
# self.textbox.select_all()
282319
# Thread(target=self.clock_thread).start()
@@ -357,7 +394,7 @@ def populate_fonts(self):
357394
self.config.set('settings', 'font', list(GLO.font_pool.keys())[0])
358395
self.config.write()
359396
def get_application_config(self):
360-
confpath = super(LabelPushApp, self).get_application_config('~/.config/%(appname)s.ini')
397+
confpath = super(type(self), self).get_application_config('~/.config/%(appname)s.ini')
361398
GLO.confpath = confpath
362399
if os.access(confpath, os.R_OK):
363400
GLO.firstrun = False
@@ -382,7 +419,7 @@ def build_config(self, config):
382419
#config.setdefaults('settings', {}) # read newly created config into memory
383420
config.setdefaults('settings', GLO.defaultcfg)
384421
def close_settings(self, *largs):
385-
ret = super(LabelPushApp, self).close_settings(*largs)
422+
ret = super(type(self), self).close_settings(*largs)
386423
GLO.firstrun = False # config window was opened, no more need for this
387424
self.root.textbox.focus = True
388425
self.root.textbox.select_all()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
with open(mainscript) as fh:
2020
for line in fh:
21-
out = re.search(r'Release version: (.+?)$', line)
21+
out = re.search(r'version = \u0027(.+?)\u0027$', line)
2222
if out:
2323
extracted_version = out.group(1)
2424
break

0 commit comments

Comments
 (0)