pastebin - collaborative debugging tool
krita.kpaste.net RSS


Krita joystick plugin
Posted by Anonymous on Thu 7th Jul 2022 13:04
raw | new post

  1. # Timer Watch is a Krita plugin and it is Time Management Tool .
  2. # Copyright (C) 2020  Ricardo Jeremias.
  3. #
  4. #  krita joystick plugin also in here
  5. #  works in a hard coded way in linux.
  6. #  
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19.  
  20.  
  21. # Import Krita
  22. from krita import *
  23. from PyQt5 import QtWidgets, QtCore, QtGui, uic
  24. import os.path
  25. import time
  26. import datetime
  27. import xml
  28.  
  29. #### js
  30. import os, struct, array
  31. from fcntl import ioctl
  32.  
  33.  
  34. GLOBAL_X = 0.0
  35. GLOBAL_Y = 0.0
  36.  
  37. # Iterate over the joystick devices.
  38. print('Available devices:')
  39.  
  40. for fn in os.listdir('/dev/input'):
  41.     if fn.startswith('js'):
  42.         print('  /dev/input/%s' % (fn))
  43.  
  44. # We'll store the states here.
  45. axis_states = {}
  46. button_states = {}
  47.  
  48. # These constants were borrowed from linux/input.h
  49. axis_names = {
  50.     0x00 : 'x',
  51.     0x01 : 'y',
  52.     0x02 : 'z',
  53.     0x03 : 'rx',
  54.     0x04 : 'ry',
  55.     0x05 : 'rz',
  56.     0x06 : 'throttle',
  57.     0x07 : 'rudder',
  58.     0x08 : 'wheel',
  59.     0x09 : 'gas',
  60.     0x0a : 'brake',
  61.     0x10 : 'hat0x',
  62.     0x11 : 'hat0y',
  63.     0x12 : 'hat1x',
  64.     0x13 : 'hat1y',
  65.     0x14 : 'hat2x',
  66.     0x15 : 'hat2y',
  67.     0x16 : 'hat3x',
  68.     0x17 : 'hat3y',
  69.     0x18 : 'pressure',
  70.     0x19 : 'distance',
  71.     0x1a : 'tilt_x',
  72.     0x1b : 'tilt_y',
  73.     0x1c : 'tool_width',
  74.     0x20 : 'volume',
  75.     0x28 : 'misc',
  76. }
  77.  
  78. button_names = {
  79.     0x120 : 'trigger',
  80.     0x121 : 'thumb',
  81.     0x122 : 'thumb2',
  82.     0x123 : 'top',
  83.     0x124 : 'top2',
  84.     0x125 : 'pinkie',
  85.     0x126 : 'base',
  86.     0x127 : 'base2',
  87.     0x128 : 'base3',
  88.     0x129 : 'base4',
  89.     0x12a : 'base5',
  90.     0x12b : 'base6',
  91.     0x12f : 'dead',
  92.     0x130 : 'a',
  93.     0x131 : 'b',
  94.     0x132 : 'c',
  95.     0x133 : 'x',
  96.     0x134 : 'y',
  97.     0x135 : 'z',
  98.     0x136 : 'tl',
  99.     0x137 : 'tr',
  100.     0x138 : 'tl2',
  101.     0x139 : 'tr2',
  102.     0x13a : 'select',
  103.     0x13b : 'start',
  104.     0x13c : 'mode',
  105.     0x13d : 'thumbl',
  106.     0x13e : 'thumbr',
  107.  
  108.     0x220 : 'dpad_up',
  109.     0x221 : 'dpad_down',
  110.     0x222 : 'dpad_left',
  111.     0x223 : 'dpad_right',
  112.  
  113.     # XBox 360 controller uses these codes.
  114.     0x2c0 : 'dpad_left',
  115.     0x2c1 : 'dpad_right',
  116.     0x2c2 : 'dpad_up',
  117.     0x2c3 : 'dpad_down',
  118. }
  119.  
  120. axis_map = []
  121. button_map = []
  122.  
  123.  
  124. # Open the joystick device.
  125. fn = '/dev/input/js0'
  126. print('Opening %s...' % fn)
  127. jsdev = open(fn, 'rb')
  128.  
  129. # Get the device name.
  130. #buf = bytearray(63)
  131. buf = array.array('B', [0] * 64)
  132. ioctl(jsdev, 0x80006a13 + (0x10000 * len(buf)), buf) # JSIOCGNAME(len)
  133. js_name = buf.tobytes().rstrip(b'\x00').decode('utf-8')
  134. print('Device name: %s' % js_name)
  135.  
  136. # Get number of axes and buttons.
  137. buf = array.array('B', [0])
  138. ioctl(jsdev, 0x80016a11, buf) # JSIOCGAXES
  139. num_axes = buf[0]
  140.  
  141. buf = array.array('B', [0])
  142. ioctl(jsdev, 0x80016a12, buf) # JSIOCGBUTTONS
  143. num_buttons = buf[0]
  144.  
  145. # Get the axis map.
  146. buf = array.array('B', [0] * 0x40)
  147. ioctl(jsdev, 0x80406a32, buf) # JSIOCGAXMAP
  148.  
  149. for axis in buf[:num_axes]:
  150.     axis_name = axis_names.get(axis, 'unknown(0x%02x)' % axis)
  151.     axis_map.append(axis_name)
  152.     axis_states[axis_name] = 0.0
  153.  
  154. # Get the button map.
  155. buf = array.array('H', [0] * 200)
  156. ioctl(jsdev, 0x80406a34, buf) # JSIOCGBTNMAP
  157.  
  158. for btn in buf[:num_buttons]:
  159.     btn_name = button_names.get(btn, 'unknown(0x%03x)' % btn)
  160.     button_map.append(btn_name)
  161.     button_states[btn_name] = 0
  162.  
  163. print('%d axes found: %s' % (num_axes, ', '.join(axis_map)))
  164. print('%d buttons found: %s' % (num_buttons, ', '.join(button_map)))
  165.  
  166. import fcntl
  167. fl = fcntl.fcntl(jsdev, fcntl.F_GETFL)
  168. fcntl.fcntl(jsdev, fcntl.F_SETFL, fl | os.O_NONBLOCK)
  169.  
  170. def map_range(value, fromLow, fromHigh, toLow, toHigh):
  171.     fromRange = fromHigh - fromLow
  172.     toRange = toHigh - toLow
  173.     scaleFactor = toRange / fromRange
  174.     tmpValue = value - fromLow
  175.     tmpValue *= scaleFactor
  176.     return tmpValue + toLow
  177.  
  178.  
  179. #### js
  180.  
  181.  
  182.  
  183.  
  184. # Set Window Title Name
  185. DOCKER_NAME = 'Timer Watch'
  186. # Alarm QMessageBox
  187. message = "Time is Over"
  188.  
  189. # Docker Class
  190. class TimerWatchDocker(DockWidget):
  191.     """Control amount of work time spent working"""
  192.  
  193.     def __init__(self):
  194.         super(TimerWatchDocker, self).__init__()
  195.  
  196.         # Window Title
  197.         self.setWindowTitle(DOCKER_NAME)
  198.         # Widget
  199.         self.window = QWidget()
  200.         self.layout = uic.loadUi(os.path.dirname(os.path.realpath(__file__)) + '/timer_watch.ui', self.window)
  201.         self.setWidget(self.window)
  202.  
  203.         # Timer
  204.         self.timer_hm = QtCore.QTimer(self)
  205.         self.timer_hm.timeout.connect(self.HM_Display)
  206.         self.timer_hm.timeout.connect(self.Info_Display)
  207.         self.timer_hm.start(10)
  208.  
  209.         self.timer_sw = QtCore.QTimer(self)
  210.         self.timer_sw.timeout.connect(self.SW_Display)
  211.         self.timer_sw.start(1000)
  212.  
  213.         # Inictialize Variables
  214.         self.counter = 0
  215.         self.switch = 0  # 0=Pause, 1=Play
  216.         self.isreset = True
  217.  
  218.         # Start up Connections
  219.         self.Connect()
  220.  
  221.     # Connect Funtions to Buttons
  222.     def Connect(self):
  223.         # Clean First Start
  224.         self.SW_Reset()
  225.  
  226.         # Stopwatch buttons
  227.         self.layout.pushButton_startpause.clicked.connect(self.SW_StartPause)
  228.         self.layout.pushButton_reset.clicked.connect(self.SW_Reset)
  229.  
  230.         # Combobox Connection
  231.         self.layout.menu_timer.currentTextChanged.connect(self.Menu_Timer)
  232.  
  233.         # Default Start UP Tab Display
  234.         self.Menu_Timer()
  235.  
  236.     # Functions
  237.     def Menu_Timer(self):
  238.         self.menu_timer = self.layout.menu_timer.currentText()
  239.         if self.menu_timer == "Clock":
  240.             self.layout.tab_clock.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)
  241.             self.layout.tab_stopwatch.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  242.             self.layout.tab_info.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  243.         if self.menu_timer == "Stopwatch":
  244.             self.layout.tab_clock.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  245.             self.layout.tab_stopwatch.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)
  246.             self.layout.tab_info.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  247.         if self.menu_timer == "Information":
  248.             self.layout.tab_clock.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  249.             self.layout.tab_stopwatch.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
  250.             self.layout.tab_info.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)
  251.  
  252.     def HM_Display(self):
  253.         self.currentTime = QtCore.QTime.currentTime()
  254.         self.layout.lcdNumber_1.setDigitCount(5)  # 5=hh:mm 8=hh:mm:ss
  255.         self.strCurrentTime = self.currentTime.toString('hh:mm')  # 'hh:mm' 'hh:mm:ss'
  256.         self.layout.lcdNumber_1.display(self.strCurrentTime)
  257.         #print("tick")
  258.  
  259. #### js
  260.         evbuf = jsdev.read(8) # this blocks if there is no data to be read.
  261.         if evbuf:
  262.             time, value, type, number = struct.unpack('IhBB', evbuf)
  263.  
  264.             if type & 0x80:
  265.                 print("(initial)", end="")
  266.  
  267.             if type & 0x01:
  268.                 button = button_map[number]
  269.                 if button:
  270.                     button_states[button] = value
  271.                     if value:
  272.                         print("%s pressed" % (button))
  273.                     else:
  274.                         print("%s released" % (button))
  275.  
  276.             if type & 0x02:
  277.                 axis = axis_map[number]
  278.                 if axis:
  279.                     fvalue = value / 32767.0
  280.                     axis_states[axis] = fvalue
  281.                     #print("%s: %.3f" % (axis, fvalue))
  282.                     if axis == "x":
  283.                         GLOBAL_X = fvalue
  284.                        
  285.                     if axis == "y":
  286.                         GLOBAL_Y = fvalue
  287.                         pass
  288.             try:
  289.                 canvas = Krita.instance().activeWindow().activeView().canvas()
  290.                 where_to_rotate=map_range(GLOBAL_X, -1.0, 1.0, 1, 359)
  291.                
  292.                
  293.                 #canvas.setRotation(45)
  294.                 canvas.setRotation(where_to_rotate)
  295.                
  296.                
  297.             except:
  298.                 print("no canvas")
  299.  
  300.  
  301.             try:
  302.                 flow_set = map_range(GLOBAL_Y,-1.0,1.0,0,1)
  303.                 currentView = Krita.instance().activeWindow().activeView()
  304.                 #currentView.setPaintingFlow(flow_set) # 0-1
  305.                 currentView.setPaintingOpacity(flow_set) # 0-1
  306.  
  307.             except:
  308.                 print("no view")
  309.            
  310.  
  311.  
  312. #### js
  313.  
  314.  
  315.     def SW_Display(self):
  316.         self.counter += 1
  317.         self.SW_Tick(self.counter)
  318.  
  319.     def SW_Tick(self, counter):
  320.         self.layout.lcdNumber_2.setDigitCount(8)
  321.         self.strProgressTime = time.strftime('%H:%M:%S', time.gmtime(self.counter))
  322.         if not self.isreset:
  323.             self.layout.lcdNumber_2.display(self.strProgressTime)
  324.             self.layout.progressBar_1.setValue(self.counter)
  325.             self.layout.progressBar_2.setValue(self.counter)
  326.             if (self.layout.pushButton_alarm.isChecked() == True and self.counter >= self.maximum and self.maximum != 0):
  327.                 self.SW_Alarm()
  328.         else:
  329.             self.layout.lcdNumber_2.display('00:00:00')
  330.  
  331.     def SW_Time(self):
  332.         # Convert Input Time
  333.         hh = self.layout.timeEdit.time().hour()
  334.         mm = self.layout.timeEdit.time().minute()
  335.         ss = self.layout.timeEdit.time().second()
  336.         conv = datetime.timedelta(hours=hh, minutes=mm)
  337.         tsec = conv.total_seconds() + ss
  338.         return tsec
  339.  
  340.     def SW_StartPause(self):
  341.         # Select Operation
  342.         if self.switch == 0:
  343.             self.SW_Start()  # 0=Pause change to Start
  344.         elif self.switch == 1:
  345.             self.SW_Pause()  # 1=Start change to Pause
  346.         else:
  347.             self.SW_Reset()
  348.  
  349.     def SW_Start(self):
  350.         # Start Ready
  351.         self.maximum = self.SW_Time()
  352.         self.layout.progressBar_1.setMaximum(self.maximum)
  353.         self.layout.progressBar_2.setMaximum(self.maximum)
  354.         # Commands
  355.         self.timer_sw.start()
  356.         # UI
  357.         self.switch = 1
  358.         self.isreset = False
  359.         if self.maximum == 0:  # if User time == Zero
  360.             self.layout.pushButton_startpause.setText("Pause:Zero")
  361.             self.layout.timeEdit.setEnabled(False)
  362.             self.layout.progressBar_1.setEnabled(False)
  363.             self.layout.progressBar_2.setEnabled(False)
  364.         else:  # if User time is NOT Zero
  365.             self.layout.pushButton_startpause.setText("Pause")
  366.             self.layout.timeEdit.setEnabled(False)
  367.             self.layout.progressBar_1.setEnabled(True)
  368.             self.layout.progressBar_2.setEnabled(True)
  369.  
  370.     def SW_Pause(self):
  371.         # Commands
  372.         self.timer_sw.stop()
  373.         # UI
  374.         self.switch = 0
  375.         self.isreset = False
  376.         self.layout.pushButton_startpause.setText("Start")
  377.         self.layout.timeEdit.setEnabled(False)
  378.         self.layout.progressBar_1.setEnabled(True)
  379.         self.layout.progressBar_2.setEnabled(True)
  380.  
  381.     def SW_Reset(self):
  382.         # Variables
  383.         self.counter = 0
  384.         # Commands
  385.         self.timer_sw.stop()
  386.         self.SW_Tick(self.counter)
  387.         # UI
  388.         self.switch = 0
  389.         self.isreset = True
  390.         self.layout.pushButton_startpause.setText("Start")
  391.         self.layout.timeEdit.setEnabled(True)
  392.         self.layout.progressBar_1.setEnabled(True)
  393.         self.layout.progressBar_2.setEnabled(True)
  394.         self.layout.progressBar_1.setValue(0)
  395.         self.layout.progressBar_2.setValue(0)
  396.  
  397.     def SW_Alarm(self):
  398.         QMessageBox.information(QWidget(), i18n("Warnning"), i18n(message))
  399.         self.SW_Pause()
  400.         self.SW_Reset()
  401.  
  402.     def Info_Display(self):
  403.         # Active Document
  404.         ki = Krita.instance()
  405.         ad = ki.activeDocument()
  406.         if ad is None:  # No Document is Active
  407.             self.layout.label_00_title.setText("Title")
  408.             self.layout.label_05_initial_creator.setText("Initial Creator")
  409.             self.layout.label_11_12_first_last_name.setText("Creator Name")
  410.             self.layout.label_10_nick_name.setText("Nickname")
  411.             self.layout.label_17_contact_type.setText("Contact Type")
  412.             self.layout.label_09_creation_date.setText("Creation Date")
  413.             self.layout.label_09_date_delta.setText("Date Delta")
  414.             self.layout.label_07_editing_time.setText("Editing Time")
  415.             self.layout.label_07_active_time.setText("Active Time")
  416.             self.layout.label_06_editing_cycles.setText("Editing Cycles")
  417.         else:  # Requesto to active Document
  418.             self.Info_Document()
  419.  
  420.     def Info_Document(self):
  421.         # Active Document
  422.         ki = Krita.instance()
  423.         ad = ki.activeDocument()
  424.         text = ad.documentInfo()
  425.         ET = xml.etree.ElementTree
  426.         root = ET.fromstring(text)
  427.  
  428.         # Call XML items with Error Check
  429.         try:    title              = root[0][0].text  # title
  430.         except: title              = "Title"
  431.         # try:    description        = root[0][1].text  # description
  432.         # except: description        = "Description"
  433.         # try:    subject            = root[0][2].text  # subject
  434.         # except: subject            = "Subject"
  435.         # try:    abstract           = root[0][3].text  # abstract
  436.         # except: abstract           = "Abstract"
  437.         # try:    keyword            = root[0][4].text  # keyword
  438.         # except: keyword            = "Keyword"
  439.         try:    initial_creator    = root[0][5].text  # initial-creator
  440.         except: initial_creator    = "Initial Creator"
  441.         try:    editing_cycles     = root[0][6].text  # editing-cycles
  442.         except: editing_cycles     = "Editing Cycles"
  443.         try:    editing_time       = root[0][7].text  # editing-time
  444.         except: editing_time       = "Editing Time"
  445.         try:    date               = root[0][8].text  # date
  446.         except: date               = "Date"
  447.         try:    creation_date      = root[0][9].text  # creation-date
  448.         except: creation_date      = "Creation Date"
  449.         # try:    language           = root[0][10].text  # language
  450.         # except: language           = "Language"
  451.         # try:    license            = root[0][11].text  # license
  452.         # except: license            = "License"
  453.         try:    nick_name          = root[1][0].text  # full-name
  454.         except: nick_name          = "Nickname"
  455.         try:    creator_first_name = root[1][1].text  # creator-first-name
  456.         except: creator_first_name = "Fname"
  457.         try:    creator_last_name  = root[1][2].text  # creator-last-name
  458.         except: creator_last_name  = "Lname"
  459.         # try:    initial            = root[1][3].text  # initial
  460.         # except: initial            = "Initial"
  461.         # try:    author_title       = root[1][4].text  # author-title
  462.         # except: author_title       = "Author Title"
  463.         # try:    position           = root[1][5].text  # position
  464.         # except: position           = "Position"
  465.         # try:    company            = root[1][6].text  # company
  466.         # except: company            = "Company"
  467.         try:    contact_type       = root[1][7].text  # contact type
  468.         except: contact_type       = "Contact Type"
  469.  
  470.         # Date Edits
  471.         creator_first_last_name = str(creator_first_name)+" "+str(creator_last_name)
  472.  
  473.         cd2 = list(creation_date)
  474.         cd2[10] = ' '
  475.         cd3 = "".join(cd2)
  476.  
  477.         date1 = list(creation_date)
  478.         year1 = int("".join(date1[0:4]))
  479.         month1 = int("".join(date1[5:7]))
  480.         day1 = int("".join(date1[8:10]))
  481.         hour1 = int("".join(date1[11:13]))
  482.         minute1 = int("".join(date1[14:16]))
  483.         second1 = int("".join(date1[17:19]))
  484.  
  485.         date2 = list(date)
  486.         year2 = int("".join(date2[0:4]))
  487.         month2 = int("".join(date2[5:7]))
  488.         day2 = int("".join(date2[8:10]))
  489.         hour2 = int("".join(date2[11:13]))
  490.         minute2 = int("".join(date2[14:16]))
  491.         second2 = int("".join(date2[17:19]))
  492.  
  493.         date_start = datetime.datetime(year1, month1, day1, hour1, minute1, second1)
  494.         date_now = datetime.datetime(year2, month2, day2, hour2, minute2, second2)
  495.         delta = (date_now - date_start).days
  496.  
  497.         yearHH = int(delta) // 365
  498.         yearTT = int(delta) - (yearHH * 365)
  499.         monthHH = yearTT // 30
  500.         monthTT = yearTT - (monthHH * 30)
  501.         dayHH = monthTT
  502.  
  503.         date_delta = str(yearHH)+"y "+str(monthHH)+"m "+str(dayHH)+"d since creation"
  504.  
  505.         if editing_time == "Editing Time" or editing_time is None:
  506.             editing_time = "Unaware"
  507.             active_time = "Unaware"
  508.         else:
  509.             yearNN = int(editing_time) // 31557600  #year
  510.             yearRR = int(editing_time) - (yearNN * 31557600)
  511.             monthNN = yearRR // 2629800  # month
  512.             monthRR = yearRR - (monthNN * 2629800)
  513.             dayNN = monthRR // 86400  # day
  514.             dayRR = monthRR - (dayNN * 86400)
  515.             hourNN = dayRR // 3600
  516.             hourRR = dayRR - (hourNN * 3600)
  517.             minuteNN = hourRR // 60
  518.             minuteRR = hourRR - (minuteNN * 60)
  519.             secondNN = minuteRR
  520.             active_time = str(yearNN)+"y "+str(monthNN)+"m "+str(dayNN)+"d . "+str(hourNN)+"h "+str(minuteNN)+"m "+str(secondNN)+"s of active work"
  521.  
  522.         # Deplay XML items on the tab
  523.         self.layout.label_00_title.setText(title)
  524.         self.layout.label_05_initial_creator.setText(initial_creator)
  525.         self.layout.label_11_12_first_last_name.setText(creator_first_last_name)
  526.         self.layout.label_10_nick_name.setText(nick_name)
  527.         self.layout.label_17_contact_type.setText(contact_type)
  528.         self.layout.label_09_creation_date.setText(cd3)
  529.         self.layout.label_09_date_delta.setText(date_delta)
  530.         self.layout.label_07_editing_time.setText(editing_time)
  531.         self.layout.label_07_active_time.setText(active_time)
  532.         self.layout.label_06_editing_cycles.setText(editing_cycles)
  533.  
  534.     # Change the Canvas
  535.     def canvasChanged(self, canvas):
  536.         pass

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at