├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitlab-ci.yml ├── .pylint-rc ├── README.md ├── custom_kivy └── clipboard_winctypes.py ├── data ├── object_infox3.png ├── object_infox4.png ├── object_infox5.png └── theme-1.png ├── docs ├── Makefile ├── calibration.rst ├── changelog.rst ├── conf.py ├── images │ ├── calib_1.png │ ├── calib_1_bis.png │ ├── calib_2.png │ ├── calib_3.png │ ├── calib_4.png │ ├── calib_5.png │ ├── calib_warning.png │ ├── candidates.png │ ├── capture_full_legend.png │ ├── capture_license.png │ ├── capture_settings.png │ ├── load_1.png │ ├── load_2.png │ ├── save_1.png │ ├── save_2.png │ ├── save_3.png │ ├── source │ │ └── capture_full.svg │ ├── zones_corner.png │ ├── zones_create.png │ ├── zones_created.png │ ├── zones_delete.png │ ├── zones_lock.png │ └── zones_locked.png ├── index.rst ├── installation.rst ├── installation_linux.rst ├── installation_osx.rst ├── interface.rst ├── objectviz.sty ├── profiles.rst ├── requirements.txt ├── settings.rst ├── usage.rst └── zones.rst ├── messages.pot ├── packaging ├── Makefile ├── blacklist.txt ├── bundle_kv.py ├── convert_otf_ttf.sh ├── create_icon.sh ├── create_osx_icon.sh ├── fix_osx_package.sh ├── hooks │ ├── fix_factory.py │ └── hook-kivy.py ├── objectviz.desktop ├── objectviz.spec ├── pep8checker │ ├── pep8.py │ ├── pep8base.html │ ├── pep8kivy.py │ ├── pre-commit.githook │ └── sample_for_pep8.py ├── project.iss ├── project.spec ├── requirements_linux.txt ├── requirements_moving.txt ├── requirements_osx.txt ├── requirements_windows.txt ├── setup.py └── whitelist.txt ├── pylintrc ├── src ├── application.kv ├── application.py ├── config_patch.py ├── custom_kivy │ ├── __init__.py │ ├── clipboard_winctypes.py │ ├── retaintouch.py │ └── touchfilter.py ├── data │ ├── CORBEL.TTF │ ├── SourceHanSerifTC-Regular.otf │ ├── credits.txt │ ├── font.ttf │ ├── icons │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── icon1024.png │ │ ├── icon_64.ico │ │ ├── icon_64.png │ │ ├── logo.svg │ │ └── logo_watermark.png │ ├── keys │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 28.png │ │ ├── 29.png │ │ ├── 3.png │ │ ├── 30.png │ │ ├── 31.png │ │ ├── 32.png │ │ ├── 33.png │ │ ├── 34.png │ │ ├── 35.png │ │ ├── 36.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ ├── 9.png │ │ └── background.png │ ├── locales │ │ ├── en │ │ │ └── LC_MESSAGES │ │ │ │ └── app.mo │ │ ├── fr │ │ │ └── LC_MESSAGES │ │ │ │ └── app.mo │ │ └── zh │ │ │ └── LC_MESSAGES │ │ │ └── app.mo │ ├── menu │ │ ├── menu_load - new_gradient.png │ │ ├── menu_object calibration_gradient.png │ │ ├── menu_object info_gradient.png │ │ ├── menu_save_gradient.png │ │ ├── menu_settings_gradient.png │ │ ├── menu_use_gradient.png │ │ └── menu_zones_gradient.png │ ├── mone │ │ ├── glow_gray.png │ │ ├── glow_lost.png │ │ ├── object_lost.png │ │ └── object_lost_light_hard.png │ ├── parts │ │ ├── background_radar.png │ │ ├── bg_piece.png │ │ ├── credits_window.png │ │ ├── credits_window_notext.png │ │ ├── graduations.png │ │ ├── hand.png │ │ ├── info.png │ │ ├── info_panel.png │ │ ├── info_window.png │ │ ├── lock_close.png │ │ ├── lock_open.png │ │ ├── mods_window.png │ │ ├── moving_parts.png │ │ ├── nb_points.png │ │ ├── object_ID_angle_info.png │ │ ├── object_infox3.png │ │ ├── object_infox4.png │ │ ├── object_infox5.png │ │ ├── object_recognised.png │ │ ├── object_recognised_light_hard.png │ │ ├── radar.png │ │ ├── resize_down_left.png │ │ ├── resize_down_right.png │ │ ├── resize_up_left.png │ │ ├── resize_up_right.png │ │ ├── title_window.png │ │ └── user_instructions_window.png │ ├── po │ │ ├── en.mo │ │ ├── en.po │ │ ├── fr.mo │ │ └── fr.po │ ├── theme-0.png │ ├── theme-1.png │ └── theme.atlas ├── data_override │ ├── cn │ │ ├── credits.txt │ │ ├── font.otf │ │ ├── icons │ │ │ ├── icon.ico │ │ │ ├── icon.png │ │ │ ├── icon1024.png │ │ │ ├── icon_64.ico │ │ │ ├── icon_64.png │ │ │ └── logo_watermark.png │ │ ├── locales │ │ │ └── zh │ │ │ │ └── LC_MESSAGES │ │ │ │ └── app.mo │ │ ├── po │ │ │ ├── zh.mo │ │ │ └── zh.po │ │ ├── theme-0.png │ │ ├── theme-1.png │ │ └── theme.atlas │ ├── cn_2 │ │ ├── credits.txt │ │ ├── font.otf │ │ ├── icons │ │ │ ├── icon.ico │ │ │ ├── icon.png │ │ │ ├── icon1024.png │ │ │ ├── icon_64.ico │ │ │ ├── icon_64.png │ │ │ └── logo_watermark.png │ │ ├── locales │ │ │ └── zh │ │ │ │ └── LC_MESSAGES │ │ │ │ └── app.mo │ │ ├── po │ │ │ ├── zh.mo │ │ │ └── zh.po │ │ ├── theme-0.png │ │ ├── theme-1.png │ │ └── theme.atlas │ └── no-logo │ │ ├── icons │ │ └── logo_watermark.png │ │ └── parts │ │ ├── credits_window.png │ │ └── credits_window_notext.png ├── ddpro.h ├── lang.py ├── layouts │ ├── __init__.py │ ├── letterbox_view.kv │ └── letterbox_view.py ├── libdpwin64.a ├── main.py ├── settings.json ├── utils │ ├── __init__.py │ └── math.pyx └── widgets │ ├── __init__.py │ ├── normalized_view.kv │ ├── normalized_view.py │ ├── settings_patch.kv │ ├── settings_patch.py │ ├── sparsegraph.kv │ └── sparsegraph.py └── version.txt /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | workflow_dispatch: 9 | 10 | 11 | env: 12 | KIVY_GL_BACKEND: 'angle_sdl2' 13 | 14 | jobs: 15 | build: 16 | runs-on: windows-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: actions/setup-python@v1 21 | with: 22 | python-version: '3.10' 23 | 24 | #- name: Install Mesa 25 | # shell: cmd 26 | # run: | 27 | # curl.exe -L --output mesa.7z --url https://github.com/pal1000/mesa-dist-win/releases/download/20.3.2/mesa3d-20.3.2-release-msvc.7z 28 | # "C:\Program Files\7-Zip\7z.exe" x mesa.7z 29 | # mklink opengl32.dll "x64\opengl32.dll" 30 | # mklink libglapi.dll "x64\libglapi.dll" 31 | 32 | - name: build 33 | run: | 34 | set WITH_NAME=ObjectViz 35 | make -f packaging/Makefile all 36 | 37 | - name: Upload installer 38 | uses: actions/upload-artifact@v2 39 | with: 40 | name: installer 41 | path: dist/ObjectViz-setup.exe 42 | - name: Upload dist 43 | uses: actions/upload-artifact@v2 44 | with: 45 | name: dist 46 | path: dist/ObjectViz 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swi 2 | *.swo 3 | *.swp 4 | *.swl 5 | *.swm 6 | *.swn 7 | *.un~ 8 | *.ini 9 | *.profile 10 | *.pyc 11 | *.pyo 12 | *.pyd 13 | *.c 14 | *.so 15 | *.key 16 | _main.py 17 | dist/ 18 | build/ 19 | docs/_build 20 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | windows: 2 | tags: 3 | - docker 4 | image: 5 | name: tshirtman/kpmwine 6 | entrypoint: [""] 7 | script: 8 | - set WITH_SENTRY_URL="https://0ab5a92a56284f938ee66ba0c309e2c9@sentry.tdl.io//2" 9 | 10 | - export PIP_CONFIG_FILE=/tmp/.pip/pip.conf 11 | - export WITH_NAME=V-Table 12 | - cp -rv src/data_override/cn_2/* src/data/ 13 | - rm -rf src/data_override 14 | - /entrypoint.sh make -f packaging/Makefile 15 | - rename 's/setup.exe/no-contacts-setup.exe/' dist/V-Table* 16 | - git clean -dfx src 17 | 18 | - export WITH_CONTACT_MAIL="'fuyonggang@vplus.studio'" 19 | - export WITH_CONTACT_PHONE="'156-5078-1618'" 20 | - cp -rv src/data_override/cn/* src/data/ 21 | - rm -rf src/data_override 22 | - /entrypoint.sh make -f packaging/Makefile 23 | - git clean -dfx src 24 | 25 | - export WITH_NAME=ObjectViz 26 | - export WITH_CONTACT_MAIL="'contact@tangibledisplay.com'" 27 | - export WITH_CONTACT_PHONE="" 28 | - cp -rv src/data_override/no-logo/* src/data/ 29 | - rm -rf src/data_override 30 | - /entrypoint.sh make -f packaging/Makefile Atlas BundleKV Prepare Templates Cythonize Package Installer Restore 31 | - rename 's/ObjectViz-setup.exe/no-logo-setup.exe/' dist/* 32 | - git clean -dfx src 33 | 34 | - export WITH_NAME=ObjectViz 35 | - export WITH_CONTACT_MAIL="'contact@tangibledisplay.com'" 36 | - export WITH_CONTACT_PHONE="" 37 | - rm -rf src/data_override 38 | - /entrypoint.sh make -f packaging/Makefile 39 | 40 | - git clean -dfx src 41 | - git checkout src 42 | - export WITH_DEBUG=true 43 | - rm -rf src/data_override 44 | - python packaging/setup.py build_ext --inplace 45 | - cp version.txt dist/$WITH_NAME/version.txt 46 | - pyinstaller packaging/project.spec --clean -y 47 | - wine 'C:\Program Files (x86)\Inno Setup 5\ISCC.exe' packaging/project.iss 48 | 49 | artifacts: 50 | paths: 51 | - dist/*.exe 52 | 53 | .linux: 54 | tags: 55 | - linux 56 | script: 57 | # - export WITH_SENTRY_URL=https://256da746f98b40588c6194d7db04e8f5:f25fb8e3e35b419e962ab9f13404768b@sentry.tdl.io//2 58 | - make 59 | - cd docs 60 | - make latexpdf 61 | - cd .. 62 | 63 | artifacts: 64 | paths: 65 | - dist/*.tar.bz2 66 | - docs/_build/latex/*.pdf 67 | 68 | .osx: 69 | tags: 70 | - osx 71 | script: 72 | # - export WITH_SENTRY_URL=https://256da746f98b40588c6194d7db04e8f5:f25fb8e3e35b419e962ab9f13404768b@sentry.tdl.io//2 73 | - source ~/dev/kivy/venv2-kivy/bin/activate 74 | - make 75 | artifacts: 76 | paths: 77 | - dist/*.dmg 78 | 79 | promote: 80 | stage: deploy 81 | tags: 82 | - linux 83 | 84 | dependencies: 85 | - windows 86 | # - osx 87 | # - linux 88 | 89 | when: manual 90 | 91 | script: 92 | - cp -r dist $CI_BUILD_ID-$CI_BUILD_REF 93 | - cp docs/_build/latex/ObjectViz.pdf $CI_BUILD_ID-$CI_BUILD_REF/ 94 | - cd $CI_BUILD_ID-$CI_BUILD_REF 95 | - mkdir windows osx linux 96 | - mv *.exe windows || echo "no windows upload!" 97 | # - mv *.dmg osx || echo "no osx upload!" 98 | # - mv *.tar.bz2 linux || echo "no linux upload!" 99 | - cd .. 100 | - scp -r -C $CI_BUILD_ID-$CI_BUILD_REF jenkins@cdn.tdl.io:/var/www/html/ObjectViz-$CI_BUILD_ID-$CI_BUILD_REF 101 | - ssh jenkins@cdn.tdl.io rm /var/www/html/dl/ObjectViz 102 | - ssh jenkins@cdn.tdl.io ln -sf /var/www/html/ObjectViz-$CI_BUILD_ID-$CI_BUILD_REF /var/www/html/dl/ObjectViz 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ObjectViz 2 | ========= 3 | 4 | ObjectViz is a multitouch object detection solution, enabling you to create 5 | physical markers out of any reliable multitouch solution. 6 | 7 | It's easily configurable and pluggable, using TUIO as a communication protocol 8 | with client applications. 9 | 10 | 11 | Documentation 12 | ------------- 13 | 14 | To build the documentation (on ubuntu) you need 15 | - texlive-base 16 | - texlive-fonts-extra 17 | 18 | go to the docs directory and run `make latexpdf` 19 | 20 | 21 | Build & Package 22 | --------------- 23 | 24 | A makefile in `packaging` is used for the various operations: 25 | 26 | to install the dependencies, ensure python3.6 or newer is installed then: 27 | 28 | ``` 29 | make -f packaging/Makefile Deps 30 | ``` 31 | 32 | To run without packaging 33 | 34 | ``` 35 | python src/main.py 36 | ``` 37 | 38 | To package the application as an installer for your current platform (though mostly tested on Windows) 39 | 40 | ``` 41 | make -f packaging/Makefile all 42 | ``` 43 | 44 | /!\ Make sure you don't have any uncommited change before running this, as it'll make a lot of local changes you'll want to revert later. 45 | -------------------------------------------------------------------------------- /custom_kivy/clipboard_winctypes.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Clipboard windows: an implementation of the Clipboard using ctypes. 3 | ''' 4 | 5 | __all__ = ('ClipboardWindows', ) 6 | 7 | from kivy.utils import platform 8 | from kivy.core.clipboard import ClipboardBase 9 | 10 | if platform != 'win': 11 | raise SystemError('unsupported platform for Windows clipboard') 12 | 13 | import ctypes 14 | from ctypes import wintypes 15 | user32 = ctypes.windll.user32 16 | kernel32 = ctypes.windll.kernel32 17 | msvcrt = ctypes.cdll.msvcrt 18 | c_char_p = ctypes.c_char_p 19 | c_wchar_p = ctypes.c_wchar_p 20 | 21 | 22 | class ClipboardWindows(ClipboardBase): 23 | 24 | def get(self, mimetype='text/plain'): 25 | GetClipboardData = user32.GetClipboardData 26 | GetClipboardData.argtypes = [wintypes.UINT] 27 | GetClipboardData.restype = wintypes.HANDLE 28 | 29 | user32.OpenClipboard(user32.GetActiveWindow()) 30 | # 1 is CF_TEXT 31 | pcontents = GetClipboardData(13) 32 | if not pcontents: 33 | return '' 34 | data = c_wchar_p(pcontents).value.encode(self._encoding) 35 | user32.CloseClipboard() 36 | return data 37 | 38 | def put(self, text, mimetype='text/plain'): 39 | text = text.decode(self._encoding) # auto converted later 40 | text += u'\x00' 41 | 42 | SetClipboardData = user32.SetClipboardData 43 | SetClipboardData.argtypes = [wintypes.UINT, wintypes.HANDLE] 44 | SetClipboardData.restype = wintypes.HANDLE 45 | 46 | GlobalAlloc = kernel32.GlobalAlloc 47 | GlobalAlloc.argtypes = [wintypes.UINT, ctypes.c_size_t] 48 | GlobalAlloc.restype = wintypes.HGLOBAL 49 | 50 | CF_UNICODETEXT = 13 51 | 52 | user32.OpenClipboard(user32.GetActiveWindow()) 53 | user32.EmptyClipboard() 54 | hCd = GlobalAlloc(0, len(text) * ctypes.sizeof(ctypes.c_wchar)) 55 | msvcrt.wcscpy_s(c_wchar_p(hCd), len(text), c_wchar_p(text[:-1])) 56 | SetClipboardData(CF_UNICODETEXT, hCd) 57 | user32.CloseClipboard() 58 | 59 | def get_types(self): 60 | return ['text/plain'] 61 | -------------------------------------------------------------------------------- /data/object_infox3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/data/object_infox3.png -------------------------------------------------------------------------------- /data/object_infox4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/data/object_infox4.png -------------------------------------------------------------------------------- /data/object_infox5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/data/object_infox5.png -------------------------------------------------------------------------------- /data/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/data/theme-1.png -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python -m sphinx 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | # ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | # $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | # endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ObjectViz.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ObjectViz.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/ObjectViz" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ObjectViz" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/calibration.rst: -------------------------------------------------------------------------------- 1 | Calibration 2 | =========== 3 | 4 | To use ObjectViz, you must train it to recognize your objects: 5 | 6 | - Put a phymark on the table, in the detection zone, so that your object is 7 | oriented upward, after calibration, the current position will indicate an 8 | angle of 0. 9 | 10 | .. Figure:: images/calib_1.png 11 | :scale: 50% 12 | 13 | Object's touches (here represented by red dots) must be in the calibration 14 | zone. Touches status will indicate 3 available touches. 15 | 16 | - The detection zone cursor should position itself to the object id selector, 17 | as soon as exactly 3 free touches (see touch status zone in the interface 18 | description) are detected in the calibration zone, you can select an 19 | available ID here. 20 | 21 | .. Figure:: images/calib_1_bis.png 22 | :scale: 50% 23 | 24 | Status zone will indicate that you can select an identifier. 25 | 26 | 27 | .. Figure:: images/calib_2.png 28 | :scale: 50% 29 | 30 | Select an identifier 31 | 32 | .. Figure:: images/calib_3.png 33 | 34 | This identifier is now assigned to the phymark. 35 | 36 | - Once a ID is selected, the object's position and orientation is 37 | indicated on the screen, under the phymark, in yellow. 38 | 39 | .. Figure:: images/calib_4.png 40 | :scale: 50% 41 | 42 | This object needs some slow motions to improve ObjectViz knowledges about it. 43 | 44 | - Rotate the phymark slowly until the display under it turns blue. 45 | 46 | - The object is now known, and will be recognized every time it's put in 47 | the detection zone. 48 | 49 | .. Figure:: images/calib_5.png 50 | :scale: 50% 51 | 52 | This object has completed its calibration process. 53 | 54 | - You may get a message at the top of the screen advising about adjusting 55 | tolerance parameters. This indicate that the values collected during the 56 | calibration varied more than the current tolerance parameters account for, 57 | the advised value correspond to two standard deviations from the collected 58 | data set. If the object was moved too fast during calibration, the value may 59 | be way more than what you need, so be sure to do the calibration in a gentle 60 | way. These values can be adjusted in the `settings` screen. 61 | 62 | .. Figure:: images/calib_warning.png 63 | :scale: 50% 64 | 65 | Either the frame is not precise enough for the current values, or the calibration step was done slightly too fast. 66 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | 2.0 2 | == 3 | 4 | - Now work with 4K displays and more 5 | - Now up to 36 different IDs 6 | - usage metrics 7 | - Fixed timezone issue on Windows (for license) 8 | - Detection analytics tools 9 | - Window opacity management (windows only), allows to use ObjectViz with wm_touch with compatible software 10 | - Various optimisations for faster detection 11 | - Better default settings 12 | - Prevent updates from removing user settings 13 | - Allow to select input provider, and to allow mouse usage or not 14 | - Error reporting 15 | - Corrected TUIO implementation, now compatible with all correct providers 16 | - Dynamic screen size, use primary screen resolution 17 | - Optimisation in use mode 18 | - Optional touch and potential objects scores displays 19 | - Support OS clipboard to copy license ID 20 | - Allow drag and drop installation of licences (on the application's window) 21 | - Various retain touch fixes 22 | - Prevent some mis detections (perfect score on surface OR angles) 23 | - Prevent a new touch to be used in two different new objects 24 | - Add information about calibration 25 | - Add option to confirm exit 26 | - Prevent user from using Unicode in save/load to avoid issues for now 27 | - Move licence and configuration to an user writable directory 28 | - Allow to start ObjectViz minimized 29 | - Allow sending TUIO events to multiple ports, user configurable 30 | - Add demo mode, for people without licenses 31 | - Technical user documentation 32 | - Correct position and angle calculation 33 | 34 | 1.0 35 | == 36 | 37 | Initial Release 38 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # ObjectViz documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Feb 13 20:24:17 2016. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 32 | 'sphinx.ext.todo', 33 | 'sphinx.ext.ifconfig', 34 | ] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates'] 38 | 39 | # The suffix of source filenames. 40 | source_suffix = '.rst' 41 | 42 | # The encoding of source files. 43 | #source_encoding = 'utf-8-sig' 44 | 45 | # The master toctree document. 46 | master_doc = 'index' 47 | 48 | # General information about the project. 49 | project = u'ObjectViz' 50 | copyright = u'2016, Tangible Display' 51 | 52 | # The version info for the project you're documenting, acts as replacement for 53 | # |version| and |release|, also used in various other places throughout the 54 | # built documents. 55 | # 56 | # The short X.Y version. 57 | version = '2.0' 58 | # The full version, including alpha/beta/rc tags. 59 | release = '2.0' 60 | 61 | # The language for content autogenerated by Sphinx. Refer to documentation 62 | # for a list of supported languages. 63 | #language = None 64 | 65 | # There are two options for replacing |today|: either, you set today to some 66 | # non-false value, then it is used: 67 | #today = '' 68 | # Else, today_fmt is used as the format for a strftime call. 69 | #today_fmt = '%B %d, %Y' 70 | 71 | # List of patterns, relative to source directory, that match files and 72 | # directories to ignore when looking for source files. 73 | exclude_patterns = ['_build'] 74 | 75 | # The reST default role (used for this markup: `text`) to use for all 76 | # documents. 77 | #default_role = None 78 | 79 | # If true, '()' will be appended to :func: etc. cross-reference text. 80 | #add_function_parentheses = True 81 | 82 | # If true, the current module name will be prepended to all description 83 | # unit titles (such as .. function::). 84 | #add_module_names = True 85 | 86 | # If true, sectionauthor and moduleauthor directives will be shown in the 87 | # output. They are ignored by default. 88 | #show_authors = False 89 | 90 | # The name of the Pygments (syntax highlighting) style to use. 91 | pygments_style = 'sphinx' 92 | 93 | # A list of ignored prefixes for module index sorting. 94 | #modindex_common_prefix = [] 95 | 96 | # If true, keep warnings as "system message" paragraphs in the built documents. 97 | #keep_warnings = False 98 | 99 | 100 | # -- Options for HTML output ---------------------------------------------- 101 | 102 | # The theme to use for HTML and HTML Help pages. See the documentation for 103 | # a list of builtin themes. 104 | html_theme = 'default' 105 | 106 | # Theme options are theme-specific and customize the look and feel of a theme 107 | # further. For a list of options available for each theme, see the 108 | # documentation. 109 | #html_theme_options = {} 110 | 111 | # Add any paths that contain custom themes here, relative to this directory. 112 | #html_theme_path = [] 113 | 114 | # The name for this set of Sphinx documents. If None, it defaults to 115 | # " v documentation". 116 | #html_title = None 117 | 118 | # A shorter title for the navigation bar. Default is the same as html_title. 119 | #html_short_title = None 120 | 121 | # The name of an image file (relative to this directory) to place at the top 122 | # of the sidebar. 123 | #html_logo = None 124 | 125 | # The name of an image file (within the static path) to use as favicon of the 126 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 127 | # pixels large. 128 | #html_favicon = None 129 | 130 | # Add any paths that contain custom static files (such as style sheets) here, 131 | # relative to this directory. They are copied after the builtin static files, 132 | # so a file named "default.css" will overwrite the builtin "default.css". 133 | html_static_path = ['_static'] 134 | 135 | # Add any extra paths that contain custom files (such as robots.txt or 136 | # .htaccess) here, relative to this directory. These files are copied 137 | # directly to the root of the documentation. 138 | #html_extra_path = [] 139 | 140 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 141 | # using the given strftime format. 142 | #html_last_updated_fmt = '%b %d, %Y' 143 | 144 | # If true, SmartyPants will be used to convert quotes and dashes to 145 | # typographically correct entities. 146 | #html_use_smartypants = True 147 | 148 | # Custom sidebar templates, maps document names to template names. 149 | #html_sidebars = {} 150 | 151 | # Additional templates that should be rendered to pages, maps page names to 152 | # template names. 153 | #html_additional_pages = {} 154 | 155 | # If false, no module index is generated. 156 | #html_domain_indices = True 157 | 158 | # If false, no index is generated. 159 | #html_use_index = True 160 | 161 | # If true, the index is split into individual pages for each letter. 162 | #html_split_index = False 163 | 164 | # If true, links to the reST sources are added to the pages. 165 | #html_show_sourcelink = True 166 | 167 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 168 | #html_show_sphinx = True 169 | 170 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 171 | #html_show_copyright = True 172 | 173 | # If true, an OpenSearch description file will be output, and all pages will 174 | # contain a tag referring to it. The value of this option must be the 175 | # base URL from which the finished HTML is served. 176 | #html_use_opensearch = '' 177 | 178 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 179 | #html_file_suffix = None 180 | 181 | # Output file base name for HTML help builder. 182 | htmlhelp_basename = 'ObjectVizdoc' 183 | 184 | 185 | # -- Options for LaTeX output --------------------------------------------- 186 | 187 | latex_elements = { 188 | # The paper size ('letterpaper' or 'a4paper'). 189 | #'papersize': 'letterpaper', 190 | 191 | # The font size ('10pt', '11pt' or '12pt'). 192 | #'pointsize': '10pt', 193 | 194 | # Additional stuff for the LaTeX preamble. 195 | #'preamble': '', 196 | 'classoptions': ',openany,oneside', 197 | 'babel': '\\usepackage[english]{babel}', 198 | 'fontpkg': r'\usepackage{mathpazo}', 199 | 'papersize': 'a4paper', 200 | 'pointsize': '10pt', 201 | 'preamble': r'\usepackage{objectviz}', 202 | 'figure_align': 'H', 203 | } 204 | 205 | # Grouping the document tree into LaTeX files. List of tuples 206 | # (source start file, target name, title, 207 | # author, documentclass [howto, manual, or own class]). 208 | latex_documents = [ 209 | ('index', 'ObjectViz.tex', u'ObjectViz Documentation', 210 | u'Tangible Display', 'manual'), 211 | ] 212 | 213 | # The name of an image file (relative to this directory) to place at the top of 214 | # the title page. 215 | #latex_logo = None 216 | 217 | # For "manual" documents, if this is true, then toplevel headings are parts, 218 | # not chapters. 219 | #latex_use_parts = False 220 | 221 | # If true, show page references after internal links. 222 | #latex_show_pagerefs = False 223 | 224 | # If true, show URL addresses after external links. 225 | #latex_show_urls = False 226 | 227 | # Documents to append as an appendix to all manuals. 228 | #latex_appendices = [] 229 | 230 | # If false, no module index is generated. 231 | #latex_domain_indices = True 232 | 233 | latex_additional_files = ['objectviz.sty', '../data/icon1024.png'] 234 | 235 | # -- Options for manual page output --------------------------------------- 236 | 237 | # One entry per manual page. List of tuples 238 | # (source start file, name, description, authors, manual section). 239 | man_pages = [ 240 | ('index', 'objectviz', u'ObjectViz Documentation', 241 | [u'Tangible Display'], 1) 242 | ] 243 | 244 | # If true, show URL addresses after external links. 245 | #man_show_urls = False 246 | 247 | 248 | # -- Options for Texinfo output ------------------------------------------- 249 | 250 | # Grouping the document tree into Texinfo files. List of tuples 251 | # (source start file, target name, title, author, 252 | # dir menu entry, description, category) 253 | texinfo_documents = [ 254 | ('index', 'ObjectViz', u'ObjectViz Documentation', 255 | u'Tangible Display', 'ObjectViz', 'One line description of project.', 256 | 'Miscellaneous'), 257 | ] 258 | 259 | # Documents to append as an appendix to all manuals. 260 | #texinfo_appendices = [] 261 | 262 | # If false, no module index is generated. 263 | #texinfo_domain_indices = True 264 | 265 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 266 | #texinfo_show_urls = 'footnote' 267 | 268 | # If true, do not generate a @detailmenu in the "Top" node's menu. 269 | #texinfo_no_detailmenu = False 270 | -------------------------------------------------------------------------------- /docs/images/calib_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_1.png -------------------------------------------------------------------------------- /docs/images/calib_1_bis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_1_bis.png -------------------------------------------------------------------------------- /docs/images/calib_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_2.png -------------------------------------------------------------------------------- /docs/images/calib_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_3.png -------------------------------------------------------------------------------- /docs/images/calib_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_4.png -------------------------------------------------------------------------------- /docs/images/calib_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_5.png -------------------------------------------------------------------------------- /docs/images/calib_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/calib_warning.png -------------------------------------------------------------------------------- /docs/images/candidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/candidates.png -------------------------------------------------------------------------------- /docs/images/capture_full_legend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/capture_full_legend.png -------------------------------------------------------------------------------- /docs/images/capture_license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/capture_license.png -------------------------------------------------------------------------------- /docs/images/capture_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/capture_settings.png -------------------------------------------------------------------------------- /docs/images/load_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/load_1.png -------------------------------------------------------------------------------- /docs/images/load_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/load_2.png -------------------------------------------------------------------------------- /docs/images/save_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/save_1.png -------------------------------------------------------------------------------- /docs/images/save_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/save_2.png -------------------------------------------------------------------------------- /docs/images/save_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/save_3.png -------------------------------------------------------------------------------- /docs/images/zones_corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_corner.png -------------------------------------------------------------------------------- /docs/images/zones_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_create.png -------------------------------------------------------------------------------- /docs/images/zones_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_created.png -------------------------------------------------------------------------------- /docs/images/zones_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_delete.png -------------------------------------------------------------------------------- /docs/images/zones_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_lock.png -------------------------------------------------------------------------------- /docs/images/zones_locked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/images/zones_locked.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. ObjectViz documentation master file, created by 2 | sphinx-quickstart on Sat Feb 13 20:24:17 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to ObjectViz's documentation! 7 | ===================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | installation 15 | interface 16 | calibration 17 | profiles 18 | usage 19 | zones 20 | settings 21 | 22 | 23 | .. ifconfig:: format == 'html' 24 | 25 | * :ref:`search` 26 | 27 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Windows 5 | +++++++ 6 | 7 | To install ObjectViz on Windows. 8 | 9 | Download the latest version on: 10 | http://cdn.tdl.io/dl/ObjectViz/windows/ 11 | 12 | Start the installer and follow the instructions. 13 | 14 | OS X 15 | ++++ 16 | 17 | To install ObjectViz on mac OS X. 18 | 19 | Download the latest version on: 20 | http://cdn.tdl.io/dl/ObjectViz/osx/ 21 | 22 | Start the installer and follow the instructions. 23 | 24 | Linux 25 | +++++ 26 | 27 | To install ObjectViz on Linux. 28 | 29 | Download the latest version on: 30 | http://cdn.tdl.io/dl/ObjectViz/linux/ 31 | 32 | Extract the archive to the desired location (avoid paths with unicode in them). 33 | You can then start the ObjectViz executable in this directory. An 34 | ObjectViz.desktop launcher is provided, but assumes being run from the same 35 | directory, you'll want to adapt its target if you run it from elsewhere. 36 | -------------------------------------------------------------------------------- /docs/installation_linux.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/installation_linux.rst -------------------------------------------------------------------------------- /docs/installation_osx.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/docs/installation_osx.rst -------------------------------------------------------------------------------- /docs/interface.rst: -------------------------------------------------------------------------------- 1 | Description of the interface 2 | ============================ 3 | 4 | .. figure:: images/capture_full_legend.png 5 | 6 | Capture of the interface in calibration mode 7 | 8 | 1. the exit button: 9 | 10 | Allows to exit the application when you are in calibration mode, when you 11 | are in use or zone mode, allows to go back to calibration mode. 12 | 13 | When in zone or use modes, exiting requires a long press followed by 14 | pressing each of the buttons that appears out of it. This is important to 15 | avoid accidental exits in production. 16 | 17 | 2. menu: 18 | 19 | - object calibration, toggle visibility of the identifier zone (3) 20 | - object info, toggle visibility of the object statistics 21 | - zones, allow to enter the `zone` mode 22 | - load/new, load a different saved set of objects, or create a new empty set 23 | - save, save the current set of objects to an existing or a new configuration 24 | - use, enter the `use` mode 25 | - settings, to open the settings screen (described in the `settings` chapter) 26 | 27 | 3. object identifiers 28 | 29 | These buttons can be used to assign identifiers to new objects, when pushed, 30 | they become larger and darker to indicate that they are associated with an 31 | object. You can reconfigure an identifier by tapping it and selecting 32 | "forget". 33 | 34 | 4. detection zone 35 | 36 | The zone that detects objects, when in calibration mode, it only covers 37 | part of the screen to give access to other parts of the interface, you can 38 | displace the zone by using the handle (10), double tap the handle (10) to 39 | replace it automatically to the default position. 40 | 41 | 5. object statistics zone 42 | 43 | Show statistics about the currently detected objects, namely: 44 | 45 | - the number of collected samples during calibration's second phase 46 | - the maximum, minimum and mean of measured values for surface and biggest angle of the object 47 | 48 | 6. status zone 49 | 50 | Indicates if you can currently configure a new object, depending on the 51 | number of available points. 52 | 53 | 7. touch status zone 54 | 55 | Indicates the number of touch currently detected, and the number of 56 | available touches (not attached to any object). 57 | 58 | e.g: 59 | 60 | .. epigraph:: 61 | 62 | 5:2 63 | 64 | indicates that 5 touches are currently detected, and 3 of them are part of 65 | an object, the two remaining ones are considered as finger touches. 66 | 67 | 8. title zone 68 | 69 | Display the current set's name. 70 | 71 | 9. About and credits 72 | 73 | This button unfold the credit menu to display information about your version 74 | of the software (to communicate to support), and its copyright information. 75 | 76 | 10. Detection zone moving handle 77 | 78 | This handle displaces the detection zone when dragged, double tap the handle to 79 | replace it automatically to the default position. 80 | 81 | -------------------------------------------------------------------------------- /docs/objectviz.sty: -------------------------------------------------------------------------------- 1 | 2 | \definecolor{TitleColor}{rgb}{0,0,0} 3 | % Make links the same color as links on the website 4 | \definecolor{InnerLinkColor}{rgb}{0.875,0.392,0.133} 5 | \definecolor{OuterLinkColor}{rgb}{0.875,0.392,0.133} 6 | 7 | % TODO Find a way not to have this active when printing the file 8 | %\definecolor{bgcolor}{rgb}{0.98,0.98,0.945} 9 | %\pagecolor{bgcolor} 10 | 11 | % Color for warning boxes 12 | \definecolor{warningcolor}{rgb}{0.78,0.18,0} 13 | 14 | % This could be used to add a tiled background: 15 | %\usepackage{wallpaper} 16 | %\ThisTileSquareWallPaper{10}{background.png} 17 | 18 | % Code background color 19 | \definecolor{VerbatimColor}{rgb}{0.925,0.918,0.882} 20 | 21 | % Palatino needs more leading (space between lines) 22 | \linespread{1.05} 23 | 24 | % allow deeper nesting than the default 3 25 | \usepackage{enumitem} 26 | \setlistdepth{999} 27 | 28 | 29 | % Override default commands below for custom style: 30 | 31 | \renewcommand{\maketitle}{% 32 | \begin{titlepage}%1 33 | \let\footnotesize\small 34 | \let\footnoterule\relax 35 | \ifsphinxpdfoutput 36 | \begingroup 37 | % This \def is required to deal with multi-line authors; it 38 | % changes \\ to ', ' (comma-space), making it pass muster for 39 | % generating document info in the PDF file. 40 | \def\\{, } 41 | \pdfinfo{ 42 | /Author (\@author) 43 | /Title (\@title) 44 | } 45 | \endgroup 46 | \fi 47 | \begin{flushright}% 48 | %\sphinxlogo% 49 | {\center 50 | \vspace*{3cm} 51 | \includegraphics[scale=.25]{icon1024.png} 52 | \vspace{3cm} 53 | \par 54 | {\rm\Huge \@title \par}% 55 | {\em\LARGE \py@release\releaseinfo \par} 56 | % Small hack to get the URL onto the first page 57 | {\small tangibledisplay.com} 58 | {\large 59 | %\@date \par 60 | \py@authoraddress \par 61 | } 62 | } 63 | \end{flushright}%\par 64 | \@thanks 65 | \end{titlepage}% 66 | \cleardoublepage% 67 | \setcounter{footnote}{0}% 68 | \let\thanks\relax\let\maketitle\relax 69 | %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} 70 | } 71 | 72 | \fancypagestyle{normal}{ 73 | \fancyhf{} 74 | \fancyfoot[LE,RO]{{\thepage}} 75 | \fancyfoot[LO]{{\nouppercase{\rightmark}}} 76 | \fancyfoot[RE]{{\nouppercase{\leftmark}}} 77 | \fancyhead[LE,RO]{{ \@title, \py@release}} 78 | \renewcommand{\headrulewidth}{0.4pt} 79 | \renewcommand{\footrulewidth}{0.4pt} 80 | } 81 | 82 | \fancypagestyle{plain}{ 83 | \fancyhf{} 84 | \fancyfoot[LE,RO]{{\thepage}} 85 | \renewcommand{\headrulewidth}{0pt} 86 | \renewcommand{\footrulewidth}{0.4pt} 87 | } 88 | 89 | \titleformat{\section}{\Large}% 90 | {\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor} 91 | \titleformat{\subsection}{\large}% 92 | {\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} 93 | \titleformat{\subsubsection}{}% 94 | {\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} 95 | \titleformat{\paragraph}{\large}% 96 | {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor} 97 | 98 | \ChNameVar{\raggedleft\normalsize} 99 | \ChNumVar{\raggedleft \bfseries\Large} 100 | \ChTitleVar{\raggedleft \rm\Huge} 101 | 102 | \renewcommand\thepart{\@Roman\c@part} 103 | \renewcommand\part{% 104 | \pagestyle{plain} 105 | \if@noskipsec \leavevmode \fi 106 | \cleardoublepage 107 | \vspace*{6cm}% 108 | \@afterindentfalse 109 | \secdef\@part\@spart} 110 | 111 | \def\@part[#1]#2{% 112 | \ifnum \c@secnumdepth >\m@ne 113 | \refstepcounter{part}% 114 | \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% 115 | \else 116 | \addcontentsline{toc}{part}{#1}% 117 | \fi 118 | {\parindent \z@ %\center 119 | \interlinepenalty \@M 120 | \normalfont 121 | \ifnum \c@secnumdepth >\m@ne 122 | \rm\Large \partname~\thepart 123 | \par\nobreak 124 | \fi 125 | \MakeUppercase{\rm\Huge #2}% 126 | \markboth{}{}\par}% 127 | \nobreak 128 | \vskip 8ex 129 | \@afterheading} 130 | \def\@spart#1{% 131 | {\parindent \z@ %\center 132 | \interlinepenalty \@M 133 | \normalfont 134 | \huge \bfseries #1\par}% 135 | \nobreak 136 | \vskip 3ex 137 | \@afterheading} 138 | 139 | % We want colored warning boxes 140 | %\renewcommand{\py@heavybox}{ 141 | % \setlength{\fboxrule}{1pt} 142 | % \setlength{\fboxsep}{6pt} 143 | % \setlength{\py@noticelength}{\linewidth} 144 | % \addtolength{\py@noticelength}{-2\fboxsep} 145 | % \addtolength{\py@noticelength}{-2\fboxrule} 146 | % %\setlength{\shadowsize}{3pt} 147 | % \color{warningcolor} 148 | % \Sbox 149 | % \minipage{\py@noticelength} 150 | % % After drawing the box, reset to black 151 | % \color{black} 152 | %} 153 | 154 | 155 | % Font used for code snippets 156 | \usepackage{beramono} 157 | \usepackage{float} 158 | 159 | 160 | % XXX find a solution for this 161 | % fix single quotes, for inconsolata. (does not work) 162 | %%\usepackage{textcomp} 163 | %%\begingroup 164 | %% \catcode`'=\active 165 | %% \g@addto@macro\@noligs{\let'\textsinglequote} 166 | %% \endgroup 167 | %%\endinput 168 | -------------------------------------------------------------------------------- /docs/profiles.rst: -------------------------------------------------------------------------------- 1 | Profiles 2 | ======== 3 | 4 | Multiple profiles (object and zone calibrations) can be saved separately, 5 | allowing to use with multiple sets of objects/applications. 6 | 7 | Saving 8 | ------ 9 | 10 | To save the current configuration, touch the `save` button in the menu. The 11 | dialog that opens allow to either select an existing profile, or to create one 12 | by typing a different name. 13 | 14 | .. Figure:: images/save_1.png 15 | :scale: 50% 16 | 17 | A default profile already exists. 18 | 19 | 20 | .. Figure:: images/save_2.png 21 | :scale: 50% 22 | 23 | Create a new profile by typing a new name. 24 | 25 | .. Figure:: images/save_3.png 26 | :scale: 50% 27 | 28 | A new profile has been created. 29 | 30 | 31 | Loading 32 | ------- 33 | 34 | Loading works mostly the same as saving, the `load` button opens a dialog to 35 | select an existing profile, you can also type a new name, to create a new, 36 | empty profile. 37 | 38 | .. Figure:: images/load_1.png 39 | :scale: 50% 40 | 41 | current profile is selected by default for save and load. 42 | 43 | .. Figure:: images/load_2.png 44 | :scale: 50% 45 | 46 | Select a different profile and hit "load" to use it. 47 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | 3 | -------------------------------------------------------------------------------- /docs/settings.rst: -------------------------------------------------------------------------------- 1 | Settings 2 | ======== 3 | 4 | A number of settings can be used to alter the behavior of ObjectViz, they are 5 | organised in the following sections. 6 | 7 | General 8 | ------- 9 | 10 | Here are a few options about general behavior of ObjectViz as an application, 11 | saving, exiting, mode to start into… 12 | 13 | 14 | Auto use 15 | ++++++++ 16 | 17 | Will trigger the "use" mode at the startup of the application, which is 18 | important if the software and client applications are set to start themselves 19 | unattended, usually at OS startup. This option will not work if the license is 20 | not present or is expired, as the software will first ask for a license, and 21 | allow for the time-limited demo, to be activated manually. 22 | 23 | 24 | Start minimized (windows only) 25 | ++++++++++++++++++++++++++++++ 26 | 27 | If this option is activated, ObjectViz will hide itself in the taskbar on 28 | startup, leaving the screen unobstructed. Since ObjectViz works with TUIO 29 | input, it doesn't need to be visible to work, so this option allow for easier 30 | integration, you probably want to activate the "auto use" option if you 31 | activate this one. 32 | 33 | 34 | Hide ObjectViz in use mode (windows only) 35 | +++++++++++++++++++++++++++++++++++++++++ 36 | 37 | This option makes ObjectViz practically invisible in use mode, allowing to let 38 | it full screen, on top of other applications, this allows to use ObjectViz when 39 | only HID/wm_touch/native touch is available (instead of TUIO) on windows, since 40 | the ObjectViz needs to be on top to receive touch events in this situation, 41 | this allow to see the client application despite this requirement. 42 | 43 | .. note:: 44 | Not all applications may allow or react well to being "masked" in this way, 45 | if your client application/framework requires to be fullscreen, or stop 46 | refreshing parts of the screen supposedly hidden, you may be unable to use 47 | this option, and have to use TUIO instead. 48 | 49 | .. warning:: 50 | This setting will cause a flickering of the application at startup or first 51 | activation, this doesn't cause any other issue, aside being graphically 52 | unpleasant, we appologize for the inconvenience. 53 | 54 | Auto save 55 | +++++++++ 56 | 57 | Save objects configuration when exiting application. This avoids losing 58 | confirmation when exiting the application without saving, usually useful while 59 | developing your setup, you may want to deactivate it in production, to avoid 60 | bad manipulation to permanently modify your setup. 61 | 62 | 63 | Confirm exit 64 | ++++++++++++ 65 | 66 | This option allows to ask for confirmation before exiting, and will display 67 | a message indicating if saving will automatically occur when doing so. 68 | 69 | 70 | TUIO 71 | ---- 72 | 73 | Allow to configure how to send TUIO events. 74 | 75 | 76 | Tuio events ip 77 | ++++++++++++++ 78 | 79 | 80 | All the tuio events will be sent to this ip, if your application is running on 81 | the same computer, you can let the default "localhost" or "127.0.0.1", if you 82 | have name resolution, you can use it. 83 | 84 | 85 | Tuio events port 86 | ++++++++++++++++ 87 | 88 | The port your client application listen for events on, you can give a list of 89 | ports, separated by commas, or a range, begin and end ports separated by 90 | dashes, or even list of ranges and values. 91 | 92 | examples: 93 | 94 | 3337 95 | 96 | 3337,4444 97 | 98 | 3334-3340 99 | 100 | 3334-3338,3350-3360,5000 101 | 102 | .. warning:: 103 | - Avoid putting unnecessary values, however, as it may slow down the 104 | program. 105 | - Don't try to send to port 3333, which is the one ObjectViz listens on, 106 | that would cause an infinite feedback loop. 107 | 108 | 109 | TUIO flush interval 110 | +++++++++++++++++++ 111 | 112 | For performance reasons, events are queued and sent to clients at regular 113 | intervals, the default interval between two events being `0.05` second, this 114 | value can be tweaked to lower delay between physical interactions and result in 115 | client program. The value is in seconds. 116 | 117 | 118 | Detection 119 | --------- 120 | 121 | These settings allow to tweak detection and reaction to various events about 122 | the lifetime of objects. 123 | 124 | 125 | Screen width and Screen height 126 | ++++++++++++++++++++++++++++++ 127 | 128 | These options are here to allow correctly detecting objects on screens with 129 | a different ratio than the default 16/9, because in such configuration objects 130 | appear differently depending on their orientation, as long as your screen ratio 131 | is 16/9, you shouldn't need to change these values, but if needed, please give 132 | the physical properties of your screen. 133 | 134 | 135 | Surface tolerance/Angle tolerance 136 | +++++++++++++++++++++++++++++++++ 137 | 138 | These two options allow to tweak the difficulty of recognizing objects, 139 | depending on your hardware/drivers/setup, the multitouch points may be more or 140 | less precise, the more precise, the less you need these values to be large for 141 | reliable detection, allowing for more objects to be recognized. On the other 142 | hand, if there are big variations in reading of the touches, you'll need to 143 | increase these values to get more reliable detections of objects, but it will 144 | also increase the risk of mis detection, i.e, the wrong object being detected, 145 | rather than no object. 146 | 147 | 148 | Point box size 149 | ++++++++++++++ 150 | 151 | This value allows to set a limit to the size of objects being searched for, any 152 | potential combination of points that has two points further apart than this 153 | value will be dismissed, and even a known object will be dismissed if its 154 | points drift further apart. This value will grow automatically when you 155 | configure new objects, but may require to be tweaked if you lose objects when 156 | moving them too fast, or if you configured unrealistically big objects, and 157 | ObjectViz now tries to detect them and look for very large combinations. 158 | 159 | 160 | Number of samples for calibration 161 | +++++++++++++++++++++++++++++++++ 162 | 163 | The calibration routine allows to know more about the variation of values 164 | detected for an object, depending on the quality of your setup, you may want to 165 | increase the default value to try to get more representative variations of 166 | objects, but it'll increase the time the user has to spend moving the object in 167 | the calibration routine. 168 | 169 | 170 | Display touches 171 | +++++++++++++++ 172 | 173 | This option simply display all the existing touches using a simple circle 174 | representation, allowing to understand if an object is not detected because 175 | some of its point are simply not detected by the screen, or if the observed 176 | position is different than the actual position. Additionally, touch identifiers 177 | are displayed besides them, which allows to see when they change (lost 178 | touches). 179 | 180 | 181 | Display candidates matching score 182 | +++++++++++++++++++++++++++++++++ 183 | 184 | When a set of points is considered a potential object, this option will display 185 | its score values against known objects, to allow user to understand the cause 186 | of a mismatch or failure to detect. 187 | 188 | The set of points in a candidate are linked together using lines of the same 189 | color (uniquely determined by the set of points), and a box contains the 190 | scores, ordered from better to worse. 191 | 192 | The first line indicates the current surface, and angles (min, max) for the 193 | object, until it matches against an object, at this point the values ceases to 194 | be updated. 195 | 196 | - The first value is the id the score matches against. 197 | - The second value is the score, the lower, the better (inf indicates an 198 | impossible match, for example, if the object has already been detected 199 | elsewhere, or the values falls outside of the tolerance values). 200 | - The third value is the surface difference with the matched object. 201 | - The fourth and fifth values indicates the differences between the matched 202 | angles of the matched object. 203 | 204 | .. Figure:: images/candidates.png 205 | :scale: 50% 206 | 207 | No candidate matched this particular set of points, if we expected it to 208 | match object 5, we may need to increase surface (to more than 157) or angle 209 | (to more than 4.7) tolerance. 210 | 211 | 212 | When multiple matched objects fall within the tolerance values, the best match 213 | will be selected. 214 | If no object match, the potential object will keep being updated until a match 215 | is found. 216 | 217 | If you find that your object are consistently not detected, these values will 218 | indicate by how much you will want to adjust the surface and angle tolerance to 219 | improve your matching, the lower scores will indicate up to how much you can 220 | increase without risking a false positive with them. 221 | 222 | 223 | Keep missing touches 224 | ++++++++++++++++++++ 225 | 226 | When a touch is lost by the frame, ObjectViz can keep its last position, until 227 | it's found again, to improve its position/rotation values. You may try to 228 | disable this option and see if the results suits you more, if you favor 229 | reactivity to movement over precision, for example. 230 | 231 | 232 | Keep angle when object is incomplete 233 | ++++++++++++++++++++++++++++++++++++ 234 | 235 | When set, this option prevents any angle change while an object is incomplete, 236 | this gives more stability to observed object in a noisy environment (weak 237 | detection solution or too many objects near of each others). 238 | 239 | 240 | Lost objects timeout 241 | ++++++++++++++++++++ 242 | 243 | If all of the touches of an object disappear, the object will be removed after 244 | this time, this time gives a possibility to detect the object again, without 245 | sending any event to the application, which won't see the object was 246 | temporarily lost. 247 | 248 | Base detection interval 249 | +++++++++++++++++++++++ 250 | 251 | The delay between each object detection is dynamic, to limit slowdown in 252 | situations with numerous combinations of touches in close proximity, most of 253 | the time, however, the base delay will be applied, you can tweak this value, if 254 | you want to detect new objects faster. The default value is `0.1` second. 255 | 256 | 257 | Retain touch 258 | ------------ 259 | 260 | When touches are lost, and new touches appears near of them in a short time 261 | after, they can be considered to be the same touch, this allows for more 262 | reliability in noisy environments, when the lost objects timeout and keep 263 | missing touches options are not enough. 264 | 265 | 266 | Retain distance 267 | +++++++++++++++ 268 | 269 | Maximum distance between the lost touch and the new touch to consider them the 270 | same (in pixel). 271 | 272 | 273 | Retain time 274 | +++++++++++ 275 | 276 | Maximum time to consider a potential match for new touch before discarding it 277 | (in milli seconds). 278 | 279 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | Entering use mode 5 | ------------------ 6 | 7 | To use ObjectViz with another software, you must switch to `use` mode, 8 | by touching the button labeled `use`. 9 | 10 | This makes the Detection zone full screen, and allow detection on every 11 | part of the screen. If you enabled the `hide window in use mode` option, 12 | the window will turn invisible until you exit `use` mode. 13 | 14 | 15 | Exiting use mode 16 | ---------------- 17 | 18 | To exit use mode, you can use the button at the top-left button 19 | of the screen, to avoid accidental exit while using another application, 20 | the button requires a long touch, then to touch the buttons that appear 21 | temporarily. Alternatively, you can press the `escape` key on the 22 | computer's keyboard. 23 | 24 | 25 | About TUIO 26 | ---------- 27 | 28 | ObjectViz uses TUIO as a way to communicate Object events to client 29 | applications. TUIO is a simple yet powerful network protocol used to send touch 30 | and objects events for multitouch and tangible applications. A specification of 31 | the format can be found at http://tuio.org/?specification. Most programming 32 | environment have a TUIO implementation, if yours doesn't have one, an OSC 33 | (https://en.wikipedia.org/wiki/Open_Sound_Control) implementation (even 34 | more common) should give you most of what's needed to implement TUIO server (to 35 | parse events from ObjectViz) quickly. 36 | -------------------------------------------------------------------------------- /docs/zones.rst: -------------------------------------------------------------------------------- 1 | Zone mode 2 | ========= 3 | 4 | ObjectViz can limit object detection to specific zones, you can use the `zones` 5 | mode (from the menu) to configure them. If no zone is configured, objects will 6 | be recognized in all parts of the screen in `use` mode. 7 | 8 | 9 | Creating zones 10 | -------------- 11 | 12 | Any long touch on the detection zone in `zones` mode, will create a new zone, 13 | centered around the touch. 14 | 15 | .. figure:: images/zones_create.png 16 | :scale: 50% 17 | 18 | Waiting time to avoid accidentaly creating zones when touching the screen. 19 | 20 | .. figure:: images/zones_created.png 21 | :scale: 50% 22 | 23 | Our newly created zone 24 | 25 | Modifying zones 26 | --------------- 27 | 28 | You can move a zone by grabbing it from inside, you can resize a zone by 29 | dragging any of its corners. 30 | 31 | .. figure:: images/zones_corner.png 32 | :scale: 50% 33 | 34 | A corner allowing to resize the zone 35 | 36 | Locking zones 37 | ------------- 38 | 39 | The `lock` button inside a zone will prevent any change to the zone when 40 | pushed, until it's pushed again. 41 | 42 | .. figure:: images/zones_lock.png 43 | :scale: 50% 44 | 45 | The lock button 46 | 47 | .. figure:: images/zones_locked.png 48 | :scale: 50% 49 | 50 | A locked zone 51 | 52 | Deleting zones 53 | -------------- 54 | 55 | Zones can be deleted by touching the delete button. 56 | 57 | .. figure:: images/zones_delete.png 58 | :scale: 50% 59 | 60 | The delete button 61 | -------------------------------------------------------------------------------- /messages.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2021-11-29 01:57-0300\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: src/application.py:406 21 | msgid "surface" 22 | msgstr "" 23 | 24 | #: src/application.py:407 25 | msgid "angle" 26 | msgstr "" 27 | 28 | #: src/application.py:411 29 | msgid "{} updated to {}" 30 | msgstr "" 31 | 32 | #: src/application.py:420 33 | msgid "retry" 34 | msgstr "" 35 | 36 | #: src/application.py:421 37 | msgid "do nothing" 38 | msgstr "" 39 | 40 | #: src/application.py:425 41 | msgid "increase" 42 | msgstr "" 43 | 44 | #: src/application.py:428 45 | msgid "" 46 | "Mesures were often over current {} limit, you can retry\n" 47 | " calibration more slowly{} or do nothing." 48 | msgstr "" 49 | 50 | #: src/application.py:432 51 | msgid ", increase {} to {} (but risk more misdetections)" 52 | msgstr "" 53 | 54 | #: src/application.py:2643 55 | #, python-format 56 | msgid "Please put the license dongle back to continue (exit in %ss)" 57 | msgstr "" 58 | 59 | #: src/settings_tmp.py:1 60 | msgid "General" 61 | msgstr "" 62 | 63 | #: src/settings_tmp.py:2 64 | msgid "language" 65 | msgstr "" 66 | 67 | #: src/settings_tmp.py:3 68 | msgid "language to display the application in" 69 | msgstr "" 70 | 71 | #: src/settings_tmp.py:4 72 | msgid "auto use" 73 | msgstr "" 74 | 75 | #: src/settings_tmp.py:5 76 | msgid "automatically start in 'use' mode" 77 | msgstr "" 78 | 79 | #: src/settings_tmp.py:6 80 | msgid "start minimized" 81 | msgstr "" 82 | 83 | #: src/settings_tmp.py:7 84 | msgid "the app minimizes itself at start" 85 | msgstr "" 86 | 87 | #: src/settings_tmp.py:8 88 | msgid "hide window in use mode" 89 | msgstr "" 90 | 91 | #: src/settings_tmp.py:9 92 | #, python-brace-format 93 | msgid "" 94 | "{NAME} hides itself in use mode, so it's possible to keep it at the top, " 95 | "[color=FF0000FF]please see the full documentation for the use case and " 96 | "effects of this setting[/color]" 97 | msgstr "" 98 | 99 | #: src/settings_tmp.py:10 100 | msgid "auto save" 101 | msgstr "" 102 | 103 | #: src/settings_tmp.py:11 104 | msgid "automatically save current profile on exit" 105 | msgstr "" 106 | 107 | #: src/settings_tmp.py:12 108 | msgid "Confirm exit" 109 | msgstr "" 110 | 111 | #: src/settings_tmp.py:13 112 | msgid "Ask for confirmation before exiting" 113 | msgstr "" 114 | 115 | #: src/settings_tmp.py:14 116 | msgid "screen mode" 117 | msgstr "" 118 | 119 | #: src/settings_tmp.py:15 120 | msgid "" 121 | "'primary' will display the window fullscreen on the primary display, 'all' " 122 | "will extend to cover all the available screens automatically, this assumes " 123 | "all your displayed are covered by your touch provider, make sure to adjust " 124 | "'screen width' and 'screen height' values in the 'Detection' section when " 125 | "using 'all'" 126 | msgstr "" 127 | 128 | #: src/settings_tmp.py:16 129 | msgid "TUIO" 130 | msgstr "" 131 | 132 | #: src/settings_tmp.py:17 133 | msgid "send TUIO touch moves" 134 | msgstr "" 135 | 136 | #: src/settings_tmp.py:18 137 | msgid "verbose tuio send updates about moving touches" 138 | msgstr "" 139 | 140 | #: src/settings_tmp.py:19 141 | msgid "TUIO events ip" 142 | msgstr "" 143 | 144 | #: src/settings_tmp.py:20 145 | msgid "destination ip to send tuio events to" 146 | msgstr "" 147 | 148 | #: src/settings_tmp.py:21 149 | msgid "TUIO events port" 150 | msgstr "" 151 | 152 | #: src/settings_tmp.py:22 153 | msgid "" 154 | "destination port to send tuio events to, you can use multiple values, " 155 | "separated by commas (e.g: 3337,3338), or express a range, using a minus sign " 156 | "(e.g 3337-3340), or mix both (e.g: 3337-3350,3389), unparsable values will " 157 | "be reset to default" 158 | msgstr "" 159 | 160 | #: src/settings_tmp.py:23 161 | msgid "TUIO flush interval" 162 | msgstr "" 163 | 164 | #: src/settings_tmp.py:24 165 | msgid "" 166 | "How often to flush the queue of tuio events, (in ms between two flush event)" 167 | msgstr "" 168 | 169 | #: src/settings_tmp.py:25 170 | msgid "Detection" 171 | msgstr "" 172 | 173 | #: src/settings_tmp.py:26 174 | msgid "Screen width" 175 | msgstr "" 176 | 177 | #: src/settings_tmp.py:27 178 | msgid "width of the capture screen" 179 | msgstr "" 180 | 181 | #: src/settings_tmp.py:28 182 | msgid "Screen height" 183 | msgstr "" 184 | 185 | #: src/settings_tmp.py:29 186 | msgid "height of the capture screen" 187 | msgstr "" 188 | 189 | #: src/settings_tmp.py:30 190 | msgid "Surface tolerance" 191 | msgstr "" 192 | 193 | #: src/settings_tmp.py:31 194 | msgid "surface that is tolerated as a difference from calibration" 195 | msgstr "" 196 | 197 | #: src/settings_tmp.py:32 198 | msgid "Angle tolerance" 199 | msgstr "" 200 | 201 | #: src/settings_tmp.py:33 202 | msgid "angle that is tolerated as a difference from calibration" 203 | msgstr "" 204 | 205 | #: src/settings_tmp.py:34 206 | msgid "Number of samples for calibration" 207 | msgstr "" 208 | 209 | #: src/settings_tmp.py:35 210 | msgid "number of different values to use for the post-calibration average" 211 | msgstr "" 212 | 213 | #: src/settings_tmp.py:36 214 | msgid "Display touches" 215 | msgstr "" 216 | 217 | #: src/settings_tmp.py:37 218 | msgid "Display currently detected touches" 219 | msgstr "" 220 | 221 | #: src/settings_tmp.py:38 222 | msgid "Display candidates matching score" 223 | msgstr "" 224 | 225 | #: src/settings_tmp.py:39 226 | msgid "Show matching scores for combinations of touches" 227 | msgstr "" 228 | 229 | #: src/settings_tmp.py:40 230 | msgid "Hide candidates matched objects" 231 | msgstr "" 232 | 233 | #: src/settings_tmp.py:41 234 | msgid "" 235 | "Remove matching scores of matched objects, disable to see why an object was " 236 | "matched to the set of points" 237 | msgstr "" 238 | 239 | #: src/settings_tmp.py:42 240 | msgid "undetect object leaving zones" 241 | msgstr "" 242 | 243 | #: src/settings_tmp.py:43 244 | msgid "when a detected object goes outside of the zones, undetect it" 245 | msgstr "" 246 | 247 | #: src/settings_tmp.py:44 248 | msgid "Keep missing touches" 249 | msgstr "" 250 | 251 | #: src/settings_tmp.py:45 252 | msgid "Keep missing touches in center/angle computations" 253 | msgstr "" 254 | 255 | #: src/settings_tmp.py:46 256 | msgid "Keep angle when object is incomplete" 257 | msgstr "" 258 | 259 | #: src/settings_tmp.py:47 260 | msgid "" 261 | "If the object has lost one or more touches, and is not yet fixed, only " 262 | "update position, not angle" 263 | msgstr "" 264 | 265 | #: src/settings_tmp.py:48 266 | msgid "Lost objects timeout" 267 | msgstr "" 268 | 269 | #: src/settings_tmp.py:49 270 | msgid "" 271 | "Keep lost objects for this number of milli-seconds, allowing the software to " 272 | "find them again without lost/find events" 273 | msgstr "" 274 | 275 | #: src/settings_tmp.py:50 276 | msgid "Number of trials for training" 277 | msgstr "" 278 | 279 | #: src/settings_tmp.py:51 280 | msgid "The number of tests one have to do for a training" 281 | msgstr "" 282 | 283 | #: src/settings_tmp.py:52 284 | msgid "Base detection interval" 285 | msgstr "" 286 | 287 | #: src/settings_tmp.py:53 288 | msgid "" 289 | "Interval betwen detection of object is dynamic, this is the smallest " 290 | "interval between two detections." 291 | msgstr "" 292 | 293 | #: src/settings_tmp.py:54 294 | msgid "behavior" 295 | msgstr "" 296 | 297 | #: src/settings_tmp.py:55 298 | msgid "Do angle filtering (experimental)" 299 | msgstr "" 300 | 301 | #: src/settings_tmp.py:56 302 | #, python-brace-format 303 | msgid "" 304 | "When enabled, {NAME} will try to prevent sudden angle changes, that may come " 305 | "from misdetection" 306 | msgstr "" 307 | 308 | #: src/settings_tmp.py:57 309 | msgid "Angle threshold" 310 | msgstr "" 311 | 312 | #: src/settings_tmp.py:58 313 | msgid "ignore sudden rotations bigger than this threshold value" 314 | msgstr "" 315 | 316 | #: src/settings_tmp.py:59 317 | msgid "Retain touch" 318 | msgstr "" 319 | 320 | #: src/settings_tmp.py:60 321 | msgid "Retain time" 322 | msgstr "" 323 | 324 | #: src/settings_tmp.py:61 325 | msgid "time to retain the touch for" 326 | msgstr "" 327 | 328 | #: src/settings_tmp.py:62 329 | msgid "Retain distance" 330 | msgstr "" 331 | 332 | #: src/settings_tmp.py:63 333 | msgid "max distance to consider new touch is the old one" 334 | msgstr "" 335 | 336 | #: src/settings_tmp.py:64 337 | msgid "Filter touches (experimental)" 338 | msgstr "" 339 | 340 | #: src/settings_tmp.py:65 341 | msgid "Use touch filter (requires restart)" 342 | msgstr "" 343 | 344 | #: src/settings_tmp.py:66 345 | msgid "minimum duration of a touch before considering it" 346 | msgstr "" 347 | 348 | #: src/settings_tmp.py:67 349 | msgid "" 350 | "wait for this time before propagating new touch events, introduce this delay " 351 | "in all touches" 352 | msgstr "" 353 | 354 | #: src/settings_tmp.py:68 355 | msgid "maximum speed of a new touch befored discarding it" 356 | msgstr "" 357 | 358 | #: src/settings_tmp.py:69 359 | msgid "" 360 | "while a touch being checked for duration, if its speed goes over this limit, " 361 | "discard it" 362 | msgstr "" 363 | 364 | #: src/application.kv:178 365 | msgid "Put your device on the calibration zone" 366 | msgstr "" 367 | 368 | #: src/application.kv:179 369 | msgid "Select an id to assign" 370 | msgstr "" 371 | 372 | #: src/application.kv:180 373 | msgid "id configured" 374 | msgstr "" 375 | 376 | #: src/application.kv:181 377 | msgid "too many devices" 378 | msgstr "" 379 | 380 | #: src/application.kv:201 381 | msgid "object calibration" 382 | msgstr "" 383 | 384 | #: src/application.kv:206 385 | msgid "object info" 386 | msgstr "" 387 | 388 | #: src/application.kv:214 389 | msgid "zones" 390 | msgstr "" 391 | 392 | #: src/application.kv:219 393 | msgid "load/new" 394 | msgstr "" 395 | 396 | #: src/application.kv:225 397 | msgid "save" 398 | msgstr "" 399 | 400 | #: src/application.kv:231 401 | msgid "use" 402 | msgstr "" 403 | 404 | #: src/application.kv:236 405 | msgid "settings" 406 | msgstr "" 407 | 408 | #: src/application.kv:560 409 | msgid "Demo" 410 | msgstr "" 411 | 412 | #: src/application.kv:600 413 | msgid "successes" 414 | msgstr "" 415 | 416 | #: src/application.kv:605 417 | msgid "direct successes" 418 | msgstr "" 419 | 420 | #: src/application.kv:610 421 | msgid "failures" 422 | msgstr "" 423 | 424 | #: src/application.kv:615 425 | msgid "errors" 426 | msgstr "" 427 | 428 | #: src/application.kv:620 429 | msgid "average failure surface difference" 430 | msgstr "" 431 | 432 | #: src/application.kv:625 433 | msgid "average failure angle difference" 434 | msgstr "" 435 | 436 | #: src/application.kv:630 437 | msgid "average surface difference" 438 | msgstr "" 439 | 440 | #: src/application.kv:635 441 | msgid "average angle difference" 442 | msgstr "" 443 | 444 | #: src/application.kv:640 445 | msgid "total samples collected" 446 | msgstr "" 447 | 448 | #: src/application.kv:645 449 | msgid "average samples per candidate" 450 | msgstr "" 451 | 452 | #: src/application.kv:650 453 | msgid "repartition of matches (figure)" 454 | msgstr "" 455 | 456 | #: src/application.kv:653 457 | msgid "variations of points positions (figure)" 458 | msgstr "" 459 | 460 | #: src/application.kv:799 461 | msgid "rotate me slowly to complete calibration" 462 | msgstr "" 463 | 464 | #: src/application.kv:894 465 | msgid "Exit?" 466 | msgstr "" 467 | 468 | #: src/application.kv:900 469 | msgid "config will be saved" 470 | msgstr "" 471 | 472 | #: src/application.kv:900 473 | msgid "configuration won't be saved" 474 | msgstr "" 475 | 476 | #: src/application.kv:905 477 | msgid "Cancel" 478 | msgstr "" 479 | 480 | #: src/application.kv:908 481 | msgid "Ok" 482 | msgstr "" 483 | 484 | #: src/application.kv:913 485 | #, python-format 486 | msgid "Select a profile to save to: %s" 487 | msgstr "" 488 | 489 | #: src/application.kv:938 src/application.kv:1223 490 | msgid "ok" 491 | msgstr "" 492 | 493 | #: src/application.kv:944 494 | msgid "delete" 495 | msgstr "" 496 | 497 | #: src/application.kv:949 498 | msgid "cancel" 499 | msgstr "" 500 | 501 | #: src/application.kv:954 502 | #, python-format 503 | msgid "Select a profile to load %s" 504 | msgstr "" 505 | 506 | #: src/application.kv:970 507 | msgid "forget" 508 | msgstr "" 509 | 510 | #: src/application.kv:1029 511 | msgid "avg" 512 | msgstr "" 513 | 514 | #: src/application.kv:1039 515 | msgid "len" 516 | msgstr "" 517 | 518 | #: src/application.kv:1049 519 | msgid "min" 520 | msgstr "" 521 | 522 | #: src/application.kv:1058 523 | msgid "max" 524 | msgstr "" 525 | 526 | #: src/application.kv:1175 527 | msgid "close" 528 | msgstr "" 529 | 530 | #: src/application.kv:1217 531 | msgid "Demonstration finished, the program will now exit" 532 | msgstr "" 533 | 534 | #: src/application.kv:1277 535 | msgid "Contact us at: " 536 | msgstr "" 537 | 538 | #: src/application.kv:1284 539 | msgid "machine identification: " 540 | msgstr "" 541 | 542 | #: src/application.kv:1285 543 | #, python-brace-format 544 | msgid "License Ok, you can now run {name}." 545 | msgstr "" 546 | 547 | #: src/application.kv:1354 548 | msgid "copy to clipboard" 549 | msgstr "" 550 | 551 | #: src/application.kv:1357 552 | msgid "copied!" 553 | msgstr "" 554 | 555 | #: src/application.kv:1376 556 | msgid "start demo" 557 | msgstr "" 558 | 559 | #: src/application.kv:1392 560 | msgid "exit" 561 | msgstr "" 562 | 563 | #: src/application.kv:1401 564 | msgid "run" 565 | msgstr "" 566 | -------------------------------------------------------------------------------- /packaging/Makefile: -------------------------------------------------------------------------------- 1 | NAME=ObjectViz 2 | 3 | ifdef WITH_NAME 4 | NAME=$(WITH_NAME) 5 | endif 6 | 7 | ifdef ComSpec 8 | RM=cmd /C del /F /Q 9 | RMDIR=cmd /C rd /S /Q 10 | MV=cmd /C move 11 | condiment=python -m condiment 12 | installer="C:\\Program Files (x86)\Inno Setup 6\iscc.exe" packaging/project.iss 13 | SEP=$(strip '\\') 14 | requirements=packaging$(SEP)requirements_windows.txt 15 | SET=$(set) 16 | python=python 17 | pyinstaller=$(python) -m PyInstaller 18 | else 19 | UNAME_S = $(shell uname -s) 20 | RM=rm -f 21 | RMDIR=rm -rf 22 | MV=mv 23 | installer=tar -C dist -caf dist/$(NAME).tar.bz2 $(NAME) --warning=no-file-changed || true 24 | make_icon=packaging/create_icon.sh 25 | python=python 26 | pyinstaller=$(python) -m PyInstaller 27 | condiment=$(python) -m condiment 28 | requirements=requirements_linux.txt 29 | ifeq ($(UNAME_S), Darwin) 30 | requirements=requirements_osx.txt 31 | installer=packaging/fix_osx_package.sh; hdiutil create dist/$(NAME).dmg -srcfolder dist/$(NAME).app -ov 32 | make_icon=packaging/create_osx_icon.sh data/icons/icon1024.png 33 | python=python 34 | condiment=/usr/local/bin/condiment 35 | pyinstaller=pyinstaller 36 | endif 37 | SET=$(export) 38 | SEP='/' 39 | endif 40 | 41 | all: Deps BundleKV Prepare Cythonize Package Installer 42 | 43 | Atlas: 44 | $(RM) src/data/theme-*.png 45 | $(python) -m kivy.atlas src/data/theme 4096 src/data/*.png src/data/menu/menu_*.png src/data/keys/*.png src/data/icons/*.png src/data/mone/*.png src/data/parts/*.png 46 | 47 | BundleKV: 48 | $(python) packaging/bundle_kv.py 49 | 50 | Deps: 51 | $(python) -m pip install -r $(requirements) | tee 52 | $(python) -m pip install -U -r packaging$(SEP)requirements_moving.txt | tee 53 | 54 | Prepare: 55 | # main 56 | -$(MV) src$(SEP)main.py src$(SEP)_main.py 57 | $(condiment) src$(SEP)_main.py -o src$(SEP)main.py 58 | # config_patch 59 | -$(MV) src$(SEP)config_patch.py src$(SEP)_config_patch.py 60 | $(condiment) src$(SEP)_config_patch.py -o src$(SEP)config_patch.py 61 | -$(RM) src$(SEP)_config_patch.py src$(SEP)_main.py src$(SEP)_contact.py 62 | -$(RMDIR) src/data/menu src/data/keys src/data/parts src/data/mone/ src/data/icons/logo.svg 63 | set VERSION=$(git describe --always) 64 | echo $(VERSION) > version.txt 65 | 66 | Cythonize: 67 | $(python) packaging$(SEP)setup.py build_ext --inplace 68 | 69 | Dev: 70 | env WITH_DEV=True $(python) packaging$(SEP)setup.py build_ext --inplace 71 | 72 | Package: 73 | -$(RMDIR) build 74 | -$(RMDIR) dist/$(NAME) 75 | $(pyinstaller) packaging$(SEP)project.spec -y --clean 76 | git describe --always > dist/$(NAME)$(SEP)version.txt 77 | 78 | Installer: 79 | set NAME=$(NAME) 80 | set VERSION=$(git describe --always) 81 | echo "AppVersion=$(VERSION)}" > packaging/version.iss 82 | $(installer) 83 | 84 | Icon: 85 | $(make_icon) 86 | 87 | lint: 88 | pylint --rcfile .pylint-rc main.py 89 | 90 | hook: 91 | # Install pre-commit git hook to check your changes for styleguide 92 | # consistency. 93 | # Thanks again, Kivy <3 -- Cheaterman 94 | cp tools/pep8checker/pre-commit.githook .git/hooks/pre-commit 95 | chmod +x .git/hooks/pre-commit 96 | 97 | 98 | po: 99 | grep -e '^ *"\(tr_title\|tr_desc\)"' src/settings.json |\ 100 | sed -s 's/^ *[^:]*: \(.*\),*$$/tr._(\1)/' |\ 101 | sed -s 's/,)$$/)/' \ 102 | > src/settings_tmp.py 103 | # 104 | xgettext -Lpython --from-code utf-8 --output=messages.pot **/*.py **/*.kv 105 | rm src/settings_tmp.py 106 | mkdir -p src/data/po/ 107 | -msgmerge --update --no-fuzzy-matching --backup=off src/data/po/fr.po messages.pot 108 | -msgmerge --update --no-fuzzy-matching --backup=off src/data/po/en.po messages.pot 109 | -msgmerge --update --no-fuzzy-matching --backup=off src/data_override/cn/po/zh.po messages.pot 110 | -msgmerge --update --no-fuzzy-matching --backup=off src/data_override/cn_2/po/zh.po messages.pot 111 | 112 | mo: 113 | mkdir -p src/data/locales/fr/LC_MESSAGES 114 | mkdir -p src/data/locales/en/LC_MESSAGES 115 | mkdir -p src/data_override/cn/locales/zh/LC_MESSAGES 116 | mkdir -p src/data_override/cn_2/locales/zh/LC_MESSAGES 117 | msgfmt -c -o src/data/locales/fr/LC_MESSAGES/app.mo src/data/po/fr.po 118 | msgfmt -c -o src/data/locales/en/LC_MESSAGES/app.mo src/data/po/en.po 119 | msgfmt -c -o src/data_override/cn/locales/zh/LC_MESSAGES/app.mo src/data_override/cn/po/zh.po 120 | msgfmt -c -o src/data_override/cn_2/locales/zh/LC_MESSAGES/app.mo src/data_override/cn_2/po/zh.po 121 | -------------------------------------------------------------------------------- /packaging/blacklist.txt: -------------------------------------------------------------------------------- 1 | *.c 2 | *.iss 3 | *.key 4 | *.pem 5 | *.pxd 6 | *.pyc 7 | *.pyo 8 | *.pyx 9 | *.spec 10 | *.swn 11 | *.swo 12 | *.swp 13 | .git 14 | .gitignore 15 | .pylint-rc 16 | Include 17 | Makefile 18 | _*.py 19 | _main.py 20 | blacklist.txt 21 | build 22 | collectorclient.py 23 | custom_kivy/touchfilter.py 24 | dist 25 | docs 26 | docutils 27 | eggs 28 | include 29 | installer 30 | layouts/letterbox_view.py 31 | layouts/letterbox_view.pyo 32 | lib 33 | license_creator.py 34 | license_creator.so 35 | main.py 36 | math.py 37 | pygments 38 | pylintrc 39 | requirements_linux.txt 40 | requirements_osx.txt 41 | requirements_windows.txt 42 | requirements_moving.txt 43 | setup.c 44 | setup.py 45 | site-packages/ 46 | src 47 | test_objectviz.py 48 | test_objectviz.pyo 49 | tests 50 | tools 51 | utils/math.py 52 | utils/math.pyo 53 | whitelist.txt 54 | widgets/normalized_view.py 55 | widgets/sparsegraph.py 56 | application.py 57 | application.pyc 58 | application.pyo 59 | config_patch.py 60 | config_patch.pyc 61 | config_patch.pyo 62 | widgets/normalized_view.py 63 | widgets/normalized_view.pyc 64 | widgets/normalized_view.pyo 65 | widgets/sparsegraph.py 66 | widgets/sparsegraph.pyc 67 | widgets/sparsegraph.pyo 68 | widgets/letterbox_view.py 69 | widgets/letterbox_view.pyc 70 | widgets/letterbox_view.pyo 71 | custom_kivy/retaintouch.py 72 | custom_kivy/retaintouch.pyc 73 | custom_kivy/retaintouch.pyo 74 | custom_kivy/touchfilter.py 75 | custom_kivy/touchfilter.pyc 76 | custom_kivy/touchfilter.pyo 77 | custom_kivy/clipboard_winctypes.py 78 | custom_kivy/clipboard_winctypes.pyc 79 | custom_kivy/clipboard_winctypes.pyo 80 | .gitlab-ci.yml 81 | -------------------------------------------------------------------------------- /packaging/bundle_kv.py: -------------------------------------------------------------------------------- 1 | from tempfile import mkstemp 2 | from os.path import join 3 | from os import walk, unlink, close, write 4 | from shutil import move 5 | 6 | 7 | def get_kv_source(fn): 8 | kv = fn[:-2] + 'kv' 9 | with open(kv, encoding='utf8') as f: 10 | source = f.read() 11 | res = source.replace('\\', r'\\') 12 | unlink(kv) 13 | return res 14 | 15 | 16 | for root, dirnames, filenames in walk('src'): 17 | for f in filenames: 18 | fn = join(root, f) 19 | if f.endswith('.py'): 20 | tmp, tmpname = mkstemp() 21 | with open(fn, encoding='utf8') as source: 22 | found = False 23 | for line in source: 24 | if line.endswith('load_kv()\n'): 25 | found = True 26 | line = line.replace('load_kv()', '{}') 27 | write(tmp, b'from kivy.lang.builder import Builder\n') 28 | write(tmp, line.format('Builder.load_string("""').encode('utf8')) 29 | write(tmp, get_kv_source(fn).encode('utf8')) 30 | write(tmp, b'""")') 31 | else: 32 | write(tmp, line.encode('utf8')) 33 | close(tmp) 34 | if found: 35 | unlink(fn) 36 | move(tmpname, fn) 37 | print(f"replaced {fn}") 38 | else: 39 | unlink(tmpname) 40 | print(f"skipped {fn}") 41 | -------------------------------------------------------------------------------- /packaging/convert_otf_ttf.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/fontforge 2 | # Quick and dirty hack: converts a font to truetype (.ttf) 3 | Print("Opening "+$1); 4 | Open($1); 5 | Print("Saving "+$1:r+".ttf"); 6 | Generate($1:r+".ttf"); 7 | Quit(0); 8 | 9 | -------------------------------------------------------------------------------- /packaging/create_icon.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | convert data/icons/icon.png \ 4 | \( -clone 0 -resize 16x16 \) \ 5 | \( -clone 0 -resize 32x32 \) \ 6 | \( -clone 0 -resize 48x48 \) \ 7 | \( -clone 0 -resize 64x64 \) \ 8 | \( -clone 0 -resize 128x128 \) \ 9 | \( -clone 0 -resize 256x256 \) \ 10 | -delete 0 -colors 256 data/icons/icon.ico 11 | -------------------------------------------------------------------------------- /packaging/create_osx_icon.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # http://stackoverflow.com/a/20703594/1209937 3 | NAME=$(basename $1 .png); DIR="$NAME.iconset" 4 | mkdir -pv $DIR 5 | for m r in 'n' '' '((n+1))' '@2x'; do 6 | for n in $(seq 4 9 | grep -v 6); do 7 | p=$((2**$m)); q=$((2**$n)) 8 | OUT="$DIR/icon_${q}x${q}${r}.png" 9 | sips -z $p $p $1 --out $OUT 10 | done 11 | done 12 | iconutil -c icns $DIR 13 | rm -frv $DIR 14 | -------------------------------------------------------------------------------- /packaging/fix_osx_package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | DIR=dist/ObjectViz.app/Contents/MacOS/ 3 | 4 | cp $(python -c "import cStringIO; print(cStringIO.__file__)") $DIR 5 | cp -r $(python -c "import importlib, os.path; print(os.path.dirname(importlib.__file__))") $DIR 6 | 7 | cat << EOF > $DIR/ObjectViz.sh 8 | #!/usr/bin/env sh 9 | cd "\$(dirname "\${BASH_SOURCE[0]}")" 10 | ./ObjectViz 11 | EOF 12 | 13 | chmod +x $DIR/ObjectViz.sh 14 | -------------------------------------------------------------------------------- /packaging/hooks/fix_factory.py: -------------------------------------------------------------------------------- 1 | from importlib import import_module 2 | from kivy.factory import Factory, FactoryException 3 | 4 | Factory.unregister('RecycleViewBehavior') 5 | Factory.unregister('RecycleView') 6 | Factory.register('RecycleViewBehavior', module='kivy.uix.recycleview') 7 | Factory.register('RecycleView', module='kivy.uix.recycleview') 8 | 9 | 10 | def __getattr__(name): 11 | classes = Factory.classes 12 | if name not in classes: 13 | if name[0] == name[0].lower(): 14 | # if trying to access attributes like checking for `bind` 15 | # then raise AttributeError 16 | raise AttributeError 17 | raise FactoryException('Unknown class <%s>' % name) 18 | 19 | item = classes[name] 20 | cls = item['cls'] 21 | 22 | # No class to return, import the module 23 | if cls is None: 24 | if item['module']: 25 | module = import_module(item['module'], package='.') 26 | if not hasattr(module, name): 27 | raise FactoryException( 28 | 'No class named <%s> in module <%s>' % ( 29 | name, item['module'])) 30 | cls = item['cls'] = getattr(module, name) 31 | 32 | elif item['baseclasses']: 33 | rootwidgets = [] 34 | for basecls in item['baseclasses'].split('+'): 35 | rootwidgets.append(Factory.get(basecls)) 36 | cls = item['cls'] = type(str(name), tuple(rootwidgets), {}) 37 | 38 | else: 39 | raise FactoryException('No information to create the class') 40 | 41 | return cls 42 | 43 | Factory.__getattr__ = Factory.get = __getattr__ 44 | -------------------------------------------------------------------------------- /packaging/hooks/hook-kivy.py: -------------------------------------------------------------------------------- 1 | from os.path import join, basename 2 | from kivy import kivy_modules_dir, kivy_data_dir 3 | from kivy.utils import platform 4 | from kivy.tools.packaging.pyinstaller_hooks import ( 5 | add_dep_paths, get_factory_modules, kivy_modules) 6 | 7 | add_dep_paths() 8 | 9 | hiddenimports = [] # get_deps_all()['hiddenimports'] 10 | hiddenimports = list(set( 11 | get_factory_modules() + kivy_modules + hiddenimports)) 12 | 13 | 14 | hiddenimports += [ 15 | 'kivy.core', 16 | 'kivy.core.clipboard', 17 | 'kivy.core.clipboard._clipboard_ext', 18 | 'kivy.core.clipboard._clipboard_sdl2', 19 | 'kivy.core.clipboard.clipboard_dbusklipper', 20 | 'kivy.core.clipboard.clipboard_gtk3', 21 | 'kivy.core.clipboard.clipboard_sdl2', 22 | 'kivy.core.clipboard.clipboard_winctypes', 23 | 'kivy.core.clipboard.clipboard_xclip', 24 | 'kivy.core.clipboard.clipboard_xsel', 25 | 'kivy.core.gl', 26 | 'kivy.core.image', 27 | 'kivy.core.image.img_sdl2', 28 | 'kivy.core.image._img_sdl2', 29 | 'kivy.core.image.img_gif', 30 | 'kivy.core.image.img_pil', 31 | 'kivy.core.text', 32 | 'kivy.core.text.text_sdl2', 33 | 'kivy.core.text._text_sdl2', 34 | 'kivy.core.text.markup', 35 | 'kivy.core.text.text_layout', 36 | 'kivy.core.text.text_sdl2', 37 | 'kivy.core.window', 38 | 'kivy.core.window._window_sdl2', 39 | 'kivy.core.window.window_sdl2', 40 | 'kivy.core.window.window_info', 41 | 'kivy.graphics', 42 | 'kivy.graphics.buffer', 43 | 'kivy.graphics.cgl', 44 | 'kivy.graphics.cgl_backend', 45 | 'kivy.graphics.cgl_backend.cgl_debug', 46 | 'kivy.graphics.cgl_backend.cgl_gl', 47 | 'kivy.graphics.cgl_backend.cgl_glew', 48 | 'kivy.graphics.cgl_backend.cgl_mock', 49 | 'kivy.graphics.cgl_backend.cgl_sdl2', 50 | 'kivy.graphics.compiler', 51 | 'kivy.graphics.context', 52 | 'kivy.graphics.context_instructions', 53 | 'kivy.graphics.fbo', 54 | 'kivy.graphics.gl_instructions', 55 | 'kivy.graphics.instructions', 56 | 'kivy.graphics.opengl', 57 | 'kivy.graphics.opengl_utils', 58 | 'kivy.graphics.scissor_instructions', 59 | 'kivy.graphics.shader', 60 | 'kivy.graphics.stencil_instructions', 61 | 'kivy.graphics.texture', 62 | 'kivy.graphics.transformation', 63 | 'kivy.graphics.vbo', 64 | 'kivy.graphics.vertex', 65 | 'kivy.graphics.vertex_instructions', 66 | ] 67 | 68 | hiddenimports.extend( 69 | [ 70 | 'Cryptodome', 71 | 'Cryptodome.Hash.SHA', 72 | 'Cryptodome.Hash.SHA256', 73 | 'Cryptodome.PublicKey', 74 | 'Cryptodome.PublicKey.RSA', 75 | 'Cryptodome.Signature', 76 | 'Cryptodome.Signature.PKCS1_v1_5', 77 | 'Queue', 78 | 'kivy.network.urlrequest', 79 | 'numpy.core.multiarray', 80 | 'ssl', 81 | 'utils', 82 | 'utils.math', 83 | 'win32com', 84 | 'win32gui', 85 | 'win32timezone', 86 | 'wmi', 87 | 'screeninfo', 88 | 'oscpy', 89 | ] 90 | ) 91 | 92 | datas = [ 93 | (kivy_data_dir, join('kivy_install', basename(kivy_data_dir))), 94 | (kivy_modules_dir, join('kivy_install', basename(kivy_modules_dir))) 95 | ] 96 | 97 | print("used patched hooks") 98 | -------------------------------------------------------------------------------- /packaging/objectviz.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=VTable 3 | Comment=Start ObjectViz multitouch object detection 4 | Exec=./VTable 5 | Icon= data/icon.png 6 | Type=Application 7 | Categories=Utility; 8 | StartupNotify=true 9 | Keywords=Run; 10 | Actions=New 11 | -------------------------------------------------------------------------------- /packaging/objectviz.spec: -------------------------------------------------------------------------------- 1 | NAME = 'VTable' 2 | import os 3 | from os.path import join 4 | import kivy 5 | from kivy.utils import platform 6 | 7 | if platform == 'win': 8 | from kivy.deps import sdl2, glew 9 | else: 10 | glew = sdl2 = None 11 | 12 | 13 | IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' 14 | if IS_LINUX: 15 | from PyInstaller.depend import dylib 16 | dylib._unix_excludes.update({ 17 | r'.*nvidia.*': 1, 18 | r'.*libdrm.*': 1, 19 | r'.*hashlib.*': 1, 20 | }) 21 | 22 | dylib.exclude_list = dylib.ExcludeList() 23 | 24 | binexcludes = [ 25 | 'gobject', 'gio', 'gtk', 'gi', 'wx', 'twisted', 'curses', 26 | 'gstreamer', 'libffi', 'libglib', 'libmikmod', 'libflac', 'libvorbis', 27 | 'libgstreamer', 'libvorbisfile', 'include', 'libstdc++.so.6', 28 | 'gst_plugins', 'liblapack', 'pygame', 'lib/', 'include', 'kivy_install/modules', 29 | ] 30 | 31 | hookspath = os.path.join(os.path.abspath(os.path.dirname('.')), 'packaging', 'hooks') 32 | 33 | a = Analysis( 34 | ['../src/main.py'], 35 | pathex=['src'], 36 | hookspath=[hookspath], 37 | runtime_hooks=[ 38 | os.path.sep.join( 39 | ( 40 | os.path.dirname(kivy.__file__), 'tools', 'packaging', 41 | 'pyinstaller_hooks', 'pyi_rth_kivy.py' 42 | ) 43 | ), 44 | os.path.sep.join((hookspath, 'fix_factory.py')) 45 | ], 46 | excludes=binexcludes 47 | ) 48 | 49 | pyz = PYZ(a.pure) 50 | 51 | name = '%s%s' % (NAME, '.exe' if os.name == 'nt' else '') 52 | 53 | def not_in(x, binexcludes): 54 | return not any(y in x.lower() for y in binexcludes) 55 | 56 | a.binaries = [ 57 | x for x in a.binaries 58 | if not_in(x[0], binexcludes) 59 | ] 60 | 61 | exe = EXE(pyz, 62 | a.scripts, 63 | exclude_binaries=True, 64 | name=name, 65 | debug=False, 66 | strip=None, 67 | upx=True, 68 | console=False, 69 | icon=join('src', 'data', 'icons', 'icon.ico')) 70 | 71 | with open('packaging/blacklist.txt') as f: 72 | excludes = [x.strip() for x in f.readlines()] 73 | 74 | coll = COLLECT(exe, 75 | Tree('src', excludes=excludes), 76 | a.binaries, 77 | a.zipfiles, 78 | a.datas, 79 | *([Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)] if sdl2 else []), 80 | strip=None, 81 | upx=True, 82 | name=NAME) 83 | 84 | app = BUNDLE(coll, 85 | name='{}.app'.format(NAME), 86 | icon='icon.icns', 87 | bundle_identifier='com.tangibledisplay.{}'.format(NAME), 88 | info_plist={ 89 | 'CFBundleExecutable': 'MacOs/{}.sh'.format(NAME) 90 | }) 91 | -------------------------------------------------------------------------------- /packaging/pep8checker/pep8kivy.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from os import walk 3 | from os.path import isdir, join, abspath, dirname 4 | import pep8 5 | import time 6 | 7 | htmlmode = False 8 | 9 | pep8_ignores = ( 10 | 'E125', # continuation line does not 11 | # distinguish itself from next logical line 12 | 'E126', # continuation line over-indented for hanging indent 13 | 'E127', # continuation line over-indented for visual indent 14 | 'E128') # continuation line under-indented for visual indent 15 | 16 | class KivyStyleChecker(pep8.Checker): 17 | 18 | def __init__(self, filename): 19 | pep8.Checker.__init__(self, filename, ignore=pep8_ignores) 20 | 21 | def report_error(self, line_number, offset, text, check): 22 | if htmlmode is False: 23 | return pep8.Checker.report_error(self, 24 | line_number, offset, text, check) 25 | 26 | # html generation 27 | print('{0}{1}'.format(line_number, text)) 28 | 29 | 30 | if __name__ == '__main__': 31 | 32 | def usage(): 33 | print('Usage: python pep8kivy.py [-html] *') 34 | print('Folders will be checked recursively.') 35 | sys.exit(1) 36 | 37 | if len(sys.argv) < 2: 38 | usage() 39 | if sys.argv[1] == '-html': 40 | if len(sys.argv) < 3: 41 | usage() 42 | else: 43 | htmlmode = True 44 | targets = sys.argv[-1].split() 45 | elif sys.argv == 2: 46 | targets = sys.argv[-1] 47 | else: 48 | targets = sys.argv[-1].split() 49 | 50 | def check(fn): 51 | try: 52 | checker = KivyStyleChecker(fn) 53 | except IOError: 54 | # File couldn't be opened, so was deleted apparently. 55 | # Don't check deleted files. 56 | return 0 57 | return checker.check_all() 58 | 59 | errors = 0 60 | exclude_dirs = ['/lib', '/coverage', '/pep8', '/doc'] 61 | exclude_files = ['kivy/gesture.py', 'osx/build.py', 'win32/build.py', 62 | 'kivy/tools/stub-gl-debug.py', 63 | 'kivy/modules/webdebugger.py', 64 | 'kivy/modules/_webdebugger.py'] 65 | for target in targets: 66 | if isdir(target): 67 | if htmlmode: 68 | path = join(dirname(abspath(__file__)), 'pep8base.html') 69 | print(open(path, 'r').read()) 70 | print('''

Generated: %s

''' % (time.strftime('%c'))) 71 | 72 | for dirpath, dirnames, filenames in walk(target): 73 | cont = False 74 | for pat in exclude_dirs: 75 | if pat in dirpath: 76 | cont = True 77 | break 78 | if cont: 79 | continue 80 | for filename in filenames: 81 | if not filename.endswith('.py'): 82 | continue 83 | cont = False 84 | complete_filename = join(dirpath, filename) 85 | for pat in exclude_files: 86 | if complete_filename.endswith(pat): 87 | cont = True 88 | if cont: 89 | continue 90 | 91 | if htmlmode: 92 | print('' \ 93 | % complete_filename) 94 | errors += check(complete_filename) 95 | 96 | if htmlmode: 97 | print('
%s
') 98 | 99 | else: 100 | # Got a single file to check 101 | for pat in exclude_dirs + exclude_files: 102 | if pat in target: 103 | break 104 | else: 105 | if target.endswith('.py'): 106 | errors += check(target) 107 | 108 | # If errors is 0 we return with 0. That's just fine. 109 | sys.exit(errors) 110 | -------------------------------------------------------------------------------- /packaging/pep8checker/pre-commit.githook: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Kivy Git Pre-Commit Hook to Enforce Styleguide 5 | ============================================== 6 | 7 | This script is not supposed to be run directly. 8 | Instead, copy it to your kivy/.git/hooks/ directory, call it 'pre-commit' 9 | and make it executable. 10 | 11 | If you attempt to commit, git will run this script, which in turn will run 12 | the styleguide checker over your code and abort the commit if there are any 13 | errors. If that happens, please fix & retry. 14 | 15 | To install:: 16 | 17 | cp kivy/tools/pep8checker/pre-commit.githook .git/hooks/pre-commit 18 | chmod +x .git/hooks/pre-commit 19 | ''' 20 | 21 | import sys, os 22 | from os.path import dirname, abspath, sep, join 23 | from subprocess import call, Popen, PIPE 24 | 25 | curdir = dirname(abspath(__file__)) 26 | srcdir = sep.join(curdir.split(sep)[:-2]) 27 | script = join(srcdir, 'tools', 'pep8checker', 'pep8kivy.py') 28 | try: 29 | with open(script): pass 30 | except IOError: 31 | # if this not the kivy project, find the script file in the kivy project 32 | os.environ['KIVY_NO_CONSOLELOG'] = '1' 33 | import kivy 34 | script = join(dirname(kivy.__file__), 'tools', 'pep8checker', 'pep8kivy.py') 35 | srcdir = '' 36 | 37 | # Only check the files that were staged 38 | #proc = Popen(['git', 'diff', '--cached', '--name-only', 'HEAD'], stdout=PIPE) 39 | #targets = [join(kivydir, target) for target in proc.stdout] 40 | 41 | # Correction: only check the files that were staged, but do not include 42 | # deleted files. 43 | proc = Popen(['git', 'diff', '--cached', '--name-status', 'HEAD'], stdout=PIPE) 44 | proc.wait() 45 | 46 | # This gives output like the following: 47 | # 48 | # A examples/widgets/lists/list_simple_in_kv.py 49 | # A examples/widgets/lists/list_simple_in_kv_2.py 50 | # D kivy/uix/observerview.py 51 | # 52 | # So check for D entries and remove them from targets. 53 | # 54 | targets = [] 55 | for target in proc.stdout: 56 | parts = [p.strip() for p in target.split()] 57 | if parts[0] != 'D': 58 | targets.append(join(srcdir, target.decode(encoding='UTF-8'))) 59 | 60 | # Untested possibility: After making the changes above for removing deleted 61 | # files from targets, saw also where the git diff call could be: 62 | # 63 | # git diff --cached --name-only --diff-filter=ACM 64 | # (leaving off D) 65 | # 66 | # and we could then remove the special handling in python for targets above. 67 | 68 | call(['git', 'stash', 'save', '--keep-index', '--quiet']) 69 | retval = call([sys.executable, script, srcdir] + targets) 70 | call(['git', 'stash', 'pop', '--quiet']) 71 | 72 | if retval: 73 | # There are styleguide violations 74 | print("Error:", retval, "styleguide violation(s) encountered!") 75 | print("Your commit has been aborted. Please fix the violations and retry.") 76 | sys.exit(retval) 77 | 78 | -------------------------------------------------------------------------------- /packaging/pep8checker/sample_for_pep8.py: -------------------------------------------------------------------------------- 1 | """ A docstring only file. With double spaces. 2 | """ 3 | pass 4 | """ Another comment. With single spaces. OK. """ 5 | pass 6 | """ Another comment. With double spaces. And triple. """ 7 | pass 8 | """ A mulitline one with initials C.C.M. 9 | And a double space in the middle. Here. 10 | But not on the third. Line. """ 11 | pass 12 | if True: 13 | " Single quotes. Same issue. With indent. " 14 | pass 15 | else: 16 | """ 17 | 18 | A multiline. 19 | 20 | 21 | 22 | On the third line. 23 | With odd indents. Here. 24 | """ 25 | 26 | """ One with. 1 number doesn't count. lowercase doesn't. Four doesn't. """ 27 | pass 28 | """ No we have commas, with too many spaces. a lower case sentence. 29 | then more: issues, and, then; another issue """ 30 | pass 31 | """ And then lots of blank lines. """ 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /packaging/project.iss: -------------------------------------------------------------------------------- 1 | [Setup] 2 | appName=ObjectViz 3 | #include "version.iss" 4 | OutputBaseFilename=ObjectViz-setup 5 | DefaultDirName={pf}\ObjectViz 6 | DisableProgramGroupPage=yes 7 | UninstallDisplayIcon={app}\ObjectViz.exe 8 | OutputDir=..\dist 9 | 10 | [Tasks] 11 | Name: "autostart"; Description: "Start ObjectViz on session startup"; Flags: unchecked 12 | 13 | [Files] 14 | Source: "..\dist\ObjectViz\*"; DestDir: "{app}"; Flags: recursesubdirs 15 | 16 | [Icons] 17 | Name: "{commonprograms}\ObjectViz"; Filename: "{app}\ObjectViz.exe" 18 | Name: "{commondesktop}\ObjectViz"; Filename: "{app}\ObjectViz.exe" 19 | Name: "{userstartup}\ObjectViz"; Filename: "{app}\ObjectViz.exe"; Tasks: autostart 20 | -------------------------------------------------------------------------------- /packaging/project.spec: -------------------------------------------------------------------------------- 1 | import os 2 | NAME = os.getenv("NAME", "ObjectViz") 3 | DEBUG = os.getenv("DEBUG", "") 4 | from os.path import join 5 | import kivy 6 | from kivy.utils import platform 7 | 8 | if platform == 'win': 9 | from kivy_deps import sdl2, glew 10 | else: 11 | glew = sdl2 = None 12 | 13 | 14 | IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' 15 | if IS_LINUX: 16 | from PyInstaller.depend import dylib 17 | dylib._unix_excludes.update({ 18 | r'.*nvidia.*': 1, 19 | r'.*libdrm.*': 1, 20 | r'.*hashlib.*': 1, 21 | }) 22 | 23 | dylib.exclude_list = dylib.ExcludeList() 24 | 25 | binexcludes = [ 26 | 'gobject', 'gio', 'gtk', 'gi', 'wx', 'twisted', 'curses', 27 | 'gstreamer', 'libffi', 'libglib', 'libmikmod', 'libflac', 'libvorbis', 28 | 'libgstreamer', 'libvorbisfile', 'include', 'libstdc++.so.6', 29 | 'gst_plugins', 'liblapack', 'pygame', 'lib/', 'include', 'kivy_install/modules', 30 | ] 31 | 32 | hookspath = os.path.join(os.path.abspath(os.path.dirname('.')), 'packaging', 'hooks') 33 | 34 | a = Analysis( 35 | ['../src/main.py'], 36 | pathex=['src'], 37 | hookspath=[hookspath], 38 | runtime_hooks=[ 39 | os.path.sep.join( 40 | ( 41 | os.path.dirname(kivy.__file__), 'tools', 'packaging', 42 | 'pyinstaller_hooks', 'pyi_rth_kivy.py' 43 | ) 44 | ), 45 | os.path.sep.join((hookspath, 'fix_factory.py')) 46 | ], 47 | excludes=binexcludes 48 | ) 49 | 50 | pyz = PYZ(a.pure) 51 | 52 | name = '%s%s' % (NAME, '.exe' if os.name == 'nt' else '') 53 | 54 | def not_in(x, binexcludes): 55 | return not any(y in x.lower() for y in binexcludes) 56 | 57 | a.binaries = [ 58 | x for x in a.binaries 59 | if not_in(x[0], binexcludes) 60 | ] 61 | 62 | exe = EXE(pyz, 63 | a.scripts, 64 | exclude_binaries=True, 65 | name=NAME, 66 | debug=bool(DEBUG), 67 | strip=None, 68 | upx=True, 69 | console=bool(DEBUG), 70 | icon=join('..', 'src', 'data', 'icons', 'icon.ico')) 71 | 72 | with open('packaging/blacklist.txt') as f: 73 | excludes = [x.strip() for x in f.readlines()] 74 | 75 | coll = COLLECT(exe, 76 | Tree('src', excludes=excludes), 77 | a.binaries, 78 | a.zipfiles, 79 | a.datas, 80 | *([Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)] if sdl2 else []), 81 | strip=None, 82 | upx=True, 83 | name=NAME+DEBUG) 84 | 85 | app = BUNDLE(coll, 86 | name='{}.app'.format(NAME), 87 | icon='icon.icns', 88 | bundle_identifier='com.tangibledisplay.{}'.format(NAME), 89 | info_plist={ 90 | 'CFBundleExecutable': 'MacOs/{}.sh'.format(NAME) 91 | }) 92 | -------------------------------------------------------------------------------- /packaging/requirements_linux.txt: -------------------------------------------------------------------------------- 1 | # bprofile 2 | Cython 3 | pyCryptodomex 4 | raven>=5.18 5 | psutil 6 | pyinstaller 7 | sphinx 8 | screeninfo 9 | oscpy 10 | -------------------------------------------------------------------------------- /packaging/requirements_moving.txt: -------------------------------------------------------------------------------- 1 | https://github.com/tshirtman/condiment/archive/master.zip 2 | Cython 3 | kivy>=2.1.0 4 | licensing 5 | pillow 6 | -------------------------------------------------------------------------------- /packaging/requirements_osx.txt: -------------------------------------------------------------------------------- 1 | # bprofile 2 | Cython 3 | pyCryptodomex 4 | raven>=5.18 5 | https://github.com/kivy/pyobjus/archive/master.zip 6 | psutil==4.1.0 7 | screeninfo 8 | oscpy 9 | -------------------------------------------------------------------------------- /packaging/requirements_windows.txt: -------------------------------------------------------------------------------- 1 | pycryptodomex 2 | Cython 3 | kivy.deps.sdl2 4 | kivy.deps.glew 5 | pyinstaller 6 | versiontools>=1.9.1 7 | pip 8 | raven>=5.18 9 | wmi==1.4.9 10 | psutil 11 | screeninfo 12 | oscpy 13 | pywin32 14 | -------------------------------------------------------------------------------- /packaging/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | from Cython.Build import cythonize 4 | from Cython.Distutils import build_ext 5 | from glob import glob 6 | from os.path import basename, join 7 | from os import getenv, chdir, unlink 8 | from sys import platform 9 | 10 | DEV = getenv('WITH_DEV') 11 | 12 | chdir('src') 13 | 14 | targets = [ 15 | x for x in ( 16 | (glob('*.py') + glob('*/*.py') if not DEV else []) + 17 | glob('*.pyx') + glob('*/*.pyx') 18 | ) 19 | if not basename(x).startswith('_') and basename(x) != 'main.py' 20 | ] 21 | 22 | setup(ext_modules=cythonize(targets)) 23 | 24 | if not DEV: 25 | for target in targets: 26 | unlink(target) 27 | 28 | 29 | chdir('..') 30 | -------------------------------------------------------------------------------- /packaging/whitelist.txt: -------------------------------------------------------------------------------- 1 | __init__.py 2 | site-packages/Crypto/** 3 | site-packages/raven/** 4 | site-packages/pyobjus/** 5 | python2.7/_*.py 6 | -------------------------------------------------------------------------------- /src/config_patch.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | #exclude 4 | ''' 5 | # fix qa errors for condiment 6 | WITH_MOUSE = None # noqa 7 | WITH_SENTRY_URL = '' # noqa 8 | WITH_DEV = False # noqa 9 | # noqa 10 | import condiment # noqa 11 | condiment.install() # noqa 12 | ''' 13 | #endexclude 14 | ''' 15 | 16 | from sys import platform 17 | from os import environ 18 | from kivy.base import ExceptionManager, ExceptionHandler 19 | from kivy.config import Config 20 | from kivy.logger import Logger 21 | from utils import get_screen_resolution 22 | 23 | 24 | class LastStand(ExceptionHandler): 25 | def handle_exception(self, inst): 26 | from kivy.factory import Factory as F 27 | if 'space left on device' in str(inst): 28 | F.Logger.setLevel('critical') 29 | F.Message( 30 | text=( 31 | 'Your system seems to run low on disk space, please ' 32 | 'clean up' 33 | ), 34 | display_time=10).show() 35 | 36 | if WITH_SENTRY_URL: 37 | from raven import Client 38 | c = Client('WITH_SENTRY_URL') 39 | c.captureException() 40 | return ExceptionManager.PASS 41 | pass 42 | 43 | 44 | ExceptionManager.add_handler(LastStand()) 45 | 46 | screenx, screentop, screenwidth, screenheight = get_screen_resolution('primary') 47 | 48 | environ.update({ 49 | 'KIVY_WINDOW': 'sdl2,pygame', 50 | 'KIVY_TEXT': 'sdl2,pygame', 51 | 'KIVY_IMAGE': 'sdl2,pygame', 52 | 'SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS': '0', 53 | }) 54 | 55 | Config.set('graphics', 'fullscreen', False) 56 | Config.set('graphics', 'resizable', False) 57 | Config.set('graphics', 'borderless', True) 58 | 59 | Config.set('graphics', 'position', 'custom') 60 | Config.set('graphics', 'left', screenx) 61 | Config.set('graphics', 'top', screentop) 62 | Config.set('graphics', 'width', screenwidth) 63 | Config.set('graphics', 'height', screenheight) 64 | Config.set('input', 'mouse', 'mouse, disable_multitouch') 65 | 66 | if WITH_MOUSE: 67 | Config.set('input', 'mouse', 'mouse') 68 | 69 | Config.set('input', 'tuio_', 'tuio,0.0.0.0:3333') 70 | 71 | Config.set('input', 'wm_touch', 'wm_touch') 72 | Config.set('kivy', 'keyboard_mode', 'systemandmulti') 73 | -------------------------------------------------------------------------------- /src/custom_kivy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/custom_kivy/__init__.py -------------------------------------------------------------------------------- /src/custom_kivy/clipboard_winctypes.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Clipboard windows: an implementation of the Clipboard using ctypes. 3 | ''' 4 | 5 | __all__ = ('ClipboardWindows', ) 6 | 7 | from kivy.utils import platform 8 | from kivy.core.clipboard import ClipboardBase 9 | 10 | if platform != 'win': 11 | raise SystemError('unsupported platform for Windows clipboard') 12 | 13 | import ctypes 14 | from ctypes import wintypes 15 | user32 = ctypes.windll.user32 16 | kernel32 = ctypes.windll.kernel32 17 | msvcrt = ctypes.cdll.msvcrt 18 | c_char_p = ctypes.c_char_p 19 | c_wchar_p = ctypes.c_wchar_p 20 | 21 | 22 | class ClipboardWindows(ClipboardBase): 23 | 24 | def get(self, mimetype='text/plain'): 25 | GetClipboardData = user32.GetClipboardData 26 | GetClipboardData.argtypes = [wintypes.UINT] 27 | GetClipboardData.restype = wintypes.HANDLE 28 | 29 | user32.OpenClipboard(user32.GetActiveWindow()) 30 | # 1 is CF_TEXT 31 | pcontents = GetClipboardData(13) 32 | if not pcontents: 33 | return '' 34 | data = c_wchar_p(pcontents).value.encode(self._encoding) 35 | user32.CloseClipboard() 36 | return data 37 | 38 | def put(self, text, mimetype='text/plain'): 39 | text = text.decode(self._encoding) # auto converted later 40 | text += u'\x00' 41 | 42 | SetClipboardData = user32.SetClipboardData 43 | SetClipboardData.argtypes = [wintypes.UINT, wintypes.HANDLE] 44 | SetClipboardData.restype = wintypes.HANDLE 45 | 46 | GlobalAlloc = kernel32.GlobalAlloc 47 | GlobalAlloc.argtypes = [wintypes.UINT, ctypes.c_size_t] 48 | GlobalAlloc.restype = wintypes.HGLOBAL 49 | 50 | CF_UNICODETEXT = 13 51 | 52 | user32.OpenClipboard(user32.GetActiveWindow()) 53 | user32.EmptyClipboard() 54 | hCd = GlobalAlloc(0, len(text) * ctypes.sizeof(ctypes.c_wchar)) 55 | msvcrt.wcscpy_s(c_wchar_p(hCd), len(text), c_wchar_p(text[:-1])) 56 | SetClipboardData(CF_UNICODETEXT, hCd) 57 | user32.CloseClipboard() 58 | 59 | def get_types(self): 60 | return ['text/plain'] 61 | -------------------------------------------------------------------------------- /src/custom_kivy/retaintouch.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Retain Touch 3 | ============ 4 | 5 | Reuse touch to counter lost finger behavior 6 | ''' 7 | 8 | __all__ = ('InputPostprocRetainTouch', ) 9 | 10 | from kivy.vector import Vector 11 | from kivy.core.window import Window 12 | import time 13 | 14 | 15 | class InputPostprocRetainTouch(object): 16 | ''' 17 | InputPostprocRetainTouch is a post-processor to delay the 'up' event of a 18 | touch, to reuse it under certains conditions. This module is designed to 19 | prevent lost finger touches on some hardware/setups. 20 | 21 | Retain touch can be configured in the Kivy config file:: 22 | 23 | [postproc] 24 | retain_time = 100 25 | retain_distance = 50 26 | 27 | The distance parameter is in the range 0-1000 and time is in milliseconds. 28 | ''' 29 | 30 | def __init__(self, app): 31 | self._app = app 32 | self._available = [] 33 | self._links = {} 34 | 35 | def process(self, events): 36 | # check if module is disabled 37 | c = self._app.config 38 | timeout = float(c.get('retain touch', 'retain_time')) / 1000. 39 | distance = float(c.get('retain touch', 'retain_distance')) 40 | 41 | if timeout == 0: 42 | return events 43 | 44 | d = time.time() 45 | for etype, touch in events[:]: 46 | if not touch.is_touch: 47 | continue 48 | # custom 49 | if etype == 'end': 50 | if hasattr(touch, 'ud'): 51 | if 'retain_touch' not in touch.ud: 52 | continue 53 | events.remove((etype, touch)) 54 | if touch.uid in self._links: 55 | selection = self._links[touch.uid] 56 | selection.ud.__pp_retain_time__ = d 57 | self._available.append(selection) 58 | del self._links[touch.uid] 59 | else: 60 | touch.ud.__pp_retain_time__ = d 61 | self._available.append(touch) 62 | elif etype == 'update': 63 | if touch.uid in self._links: 64 | selection = self._links[touch.uid] 65 | selection.x = touch.x 66 | selection.y = touch.y 67 | selection.sx = touch.sx 68 | selection.sy = touch.sy 69 | events.remove((etype, touch)) 70 | events.append((etype, selection)) 71 | else: 72 | pass 73 | elif etype == 'begin': 74 | # new touch, found the nearest one 75 | selection = None 76 | selection_distance = float('inf') 77 | for touch2 in self._available: 78 | touch.scale_for_screen(*Window.size) 79 | touch_distance = Vector(touch2.pos).distance(touch.pos) 80 | if touch_distance > distance: 81 | continue 82 | if touch_distance < selection_distance: 83 | # eligible for continuation 84 | selection_distance = touch_distance 85 | selection = touch2 86 | if selection is None: 87 | continue 88 | 89 | self._links[touch.uid] = selection 90 | touch.ud = selection.ud 91 | self._available.remove(selection) 92 | events.remove((etype, touch)) 93 | 94 | for touch in self._available[:]: 95 | t = touch.ud.__pp_retain_time__ 96 | if d - t > timeout: 97 | self._available.remove(touch) 98 | events.append(('end', touch)) 99 | 100 | return events 101 | -------------------------------------------------------------------------------- /src/custom_kivy/touchfilter.py: -------------------------------------------------------------------------------- 1 | 2 | ''' 3 | Filter Touches 4 | ============== 5 | 6 | Don't even consider some touches 7 | ''' 8 | 9 | __all__ = ('InputPostprocFilterTouches', ) 10 | 11 | from kivy.vector import Vector 12 | from collections import deque 13 | import time 14 | 15 | 16 | class InputPostprocFilterTouches(object): 17 | ''' 18 | ''' 19 | 20 | def __init__(self, app): 21 | self.min_duration = app.config.getint('filter', 'min_duration') / 1000. 22 | self.max_speed = app.config.getint('filter', 'max_speed') / 100. 23 | self.queue = deque() 24 | self.timeouts = dict() 25 | self.blacklist = deque() 26 | 27 | def process(self, events): 28 | d = time.time() 29 | timeouts = self.timeouts 30 | q = self.queue 31 | bl = self.blacklist 32 | 33 | # release previously held events 34 | while q: 35 | event = q.pop() 36 | timeout = timeouts[event].pop() 37 | if timeout > d: 38 | q.append(event) 39 | timeouts[event].append(timeout) 40 | break 41 | events.append(event) 42 | timeouts.pop(event) 43 | 44 | for etype, touch in events[:]: 45 | if not touch.is_touch: 46 | continue 47 | # custom 48 | if etype == 'end': 49 | while (etype, touch) in self.queue: 50 | q.remove((etype, touch)) 51 | timeouts[(etype, touch)].pop() 52 | events.remove((etype, touch)) 53 | 54 | elif etype == 'update': 55 | if (etype, touch) in q: 56 | if ( 57 | Vector( 58 | touch.x - touch.ox, 59 | touch.y - touch.oy 60 | ).length() / (d - touch.time_start) > self.max_speed 61 | ): 62 | bl.append(touch) 63 | events.remove((etype, touch)) 64 | q.appendleft((etype, touch)) 65 | _timeouts = timeouts.setdefaults((etype, touch), deque()) 66 | _timeouts.appendleft(d + self.min_duration) 67 | 68 | elif etype == 'begin': 69 | # new touch, put it in queue 70 | q.appendleft((etype, touch)) 71 | _timeouts = timeouts.setdefault((etype, touch), deque()) 72 | _timeouts.appendleft(d + self.min_duration) 73 | 74 | events.remove((etype, touch)) 75 | 76 | return events 77 | -------------------------------------------------------------------------------- /src/data/CORBEL.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/CORBEL.TTF -------------------------------------------------------------------------------- /src/data/SourceHanSerifTC-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/SourceHanSerifTC-Regular.otf -------------------------------------------------------------------------------- /src/data/credits.txt: -------------------------------------------------------------------------------- 1 | ObjectViz 2 | Version {version} 3 | 4 | Created by the Tangible Display team. 5 | ©2013-{year} Tangible Display and its licensors. All rights reserved. 6 | The Tangible Display logo is a registered trademark of Tangible Display in France and/or other countries. 7 | 8 | www.tangibledisplay.com 9 | 10 | -.-- --- ..- 11 | -.-. .- -. 12 | --. . - 13 | .. - 14 | .. ..-. 15 | -.-- --- ..- 16 | .-. . .- .-.. .-.. -.-- 17 | .-- .- -. - 18 | -------------------------------------------------------------------------------- /src/data/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/font.ttf -------------------------------------------------------------------------------- /src/data/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/icon.ico -------------------------------------------------------------------------------- /src/data/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/icon.png -------------------------------------------------------------------------------- /src/data/icons/icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/icon1024.png -------------------------------------------------------------------------------- /src/data/icons/icon_64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/icon_64.ico -------------------------------------------------------------------------------- /src/data/icons/icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/icon_64.png -------------------------------------------------------------------------------- /src/data/icons/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml -------------------------------------------------------------------------------- /src/data/icons/logo_watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/icons/logo_watermark.png -------------------------------------------------------------------------------- /src/data/keys/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/1.png -------------------------------------------------------------------------------- /src/data/keys/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/10.png -------------------------------------------------------------------------------- /src/data/keys/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/11.png -------------------------------------------------------------------------------- /src/data/keys/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/12.png -------------------------------------------------------------------------------- /src/data/keys/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/13.png -------------------------------------------------------------------------------- /src/data/keys/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/14.png -------------------------------------------------------------------------------- /src/data/keys/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/15.png -------------------------------------------------------------------------------- /src/data/keys/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/16.png -------------------------------------------------------------------------------- /src/data/keys/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/17.png -------------------------------------------------------------------------------- /src/data/keys/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/18.png -------------------------------------------------------------------------------- /src/data/keys/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/19.png -------------------------------------------------------------------------------- /src/data/keys/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/2.png -------------------------------------------------------------------------------- /src/data/keys/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/20.png -------------------------------------------------------------------------------- /src/data/keys/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/21.png -------------------------------------------------------------------------------- /src/data/keys/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/22.png -------------------------------------------------------------------------------- /src/data/keys/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/23.png -------------------------------------------------------------------------------- /src/data/keys/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/24.png -------------------------------------------------------------------------------- /src/data/keys/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/25.png -------------------------------------------------------------------------------- /src/data/keys/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/26.png -------------------------------------------------------------------------------- /src/data/keys/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/27.png -------------------------------------------------------------------------------- /src/data/keys/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/28.png -------------------------------------------------------------------------------- /src/data/keys/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/29.png -------------------------------------------------------------------------------- /src/data/keys/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/3.png -------------------------------------------------------------------------------- /src/data/keys/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/30.png -------------------------------------------------------------------------------- /src/data/keys/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/31.png -------------------------------------------------------------------------------- /src/data/keys/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/32.png -------------------------------------------------------------------------------- /src/data/keys/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/33.png -------------------------------------------------------------------------------- /src/data/keys/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/34.png -------------------------------------------------------------------------------- /src/data/keys/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/35.png -------------------------------------------------------------------------------- /src/data/keys/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/36.png -------------------------------------------------------------------------------- /src/data/keys/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/4.png -------------------------------------------------------------------------------- /src/data/keys/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/5.png -------------------------------------------------------------------------------- /src/data/keys/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/6.png -------------------------------------------------------------------------------- /src/data/keys/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/7.png -------------------------------------------------------------------------------- /src/data/keys/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/8.png -------------------------------------------------------------------------------- /src/data/keys/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/9.png -------------------------------------------------------------------------------- /src/data/keys/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/keys/background.png -------------------------------------------------------------------------------- /src/data/locales/en/LC_MESSAGES/app.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/locales/en/LC_MESSAGES/app.mo -------------------------------------------------------------------------------- /src/data/locales/fr/LC_MESSAGES/app.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/locales/fr/LC_MESSAGES/app.mo -------------------------------------------------------------------------------- /src/data/locales/zh/LC_MESSAGES/app.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/locales/zh/LC_MESSAGES/app.mo -------------------------------------------------------------------------------- /src/data/menu/menu_load - new_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_load - new_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_object calibration_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_object calibration_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_object info_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_object info_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_save_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_save_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_settings_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_settings_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_use_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_use_gradient.png -------------------------------------------------------------------------------- /src/data/menu/menu_zones_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/menu/menu_zones_gradient.png -------------------------------------------------------------------------------- /src/data/mone/glow_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/mone/glow_gray.png -------------------------------------------------------------------------------- /src/data/mone/glow_lost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/mone/glow_lost.png -------------------------------------------------------------------------------- /src/data/mone/object_lost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/mone/object_lost.png -------------------------------------------------------------------------------- /src/data/mone/object_lost_light_hard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/mone/object_lost_light_hard.png -------------------------------------------------------------------------------- /src/data/parts/background_radar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/background_radar.png -------------------------------------------------------------------------------- /src/data/parts/bg_piece.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/bg_piece.png -------------------------------------------------------------------------------- /src/data/parts/credits_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/credits_window.png -------------------------------------------------------------------------------- /src/data/parts/credits_window_notext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/credits_window_notext.png -------------------------------------------------------------------------------- /src/data/parts/graduations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/graduations.png -------------------------------------------------------------------------------- /src/data/parts/hand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/hand.png -------------------------------------------------------------------------------- /src/data/parts/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/info.png -------------------------------------------------------------------------------- /src/data/parts/info_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/info_panel.png -------------------------------------------------------------------------------- /src/data/parts/info_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/info_window.png -------------------------------------------------------------------------------- /src/data/parts/lock_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/lock_close.png -------------------------------------------------------------------------------- /src/data/parts/lock_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/lock_open.png -------------------------------------------------------------------------------- /src/data/parts/mods_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/mods_window.png -------------------------------------------------------------------------------- /src/data/parts/moving_parts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/moving_parts.png -------------------------------------------------------------------------------- /src/data/parts/nb_points.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/nb_points.png -------------------------------------------------------------------------------- /src/data/parts/object_ID_angle_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_ID_angle_info.png -------------------------------------------------------------------------------- /src/data/parts/object_infox3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_infox3.png -------------------------------------------------------------------------------- /src/data/parts/object_infox4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_infox4.png -------------------------------------------------------------------------------- /src/data/parts/object_infox5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_infox5.png -------------------------------------------------------------------------------- /src/data/parts/object_recognised.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_recognised.png -------------------------------------------------------------------------------- /src/data/parts/object_recognised_light_hard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/object_recognised_light_hard.png -------------------------------------------------------------------------------- /src/data/parts/radar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/radar.png -------------------------------------------------------------------------------- /src/data/parts/resize_down_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/resize_down_left.png -------------------------------------------------------------------------------- /src/data/parts/resize_down_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/resize_down_right.png -------------------------------------------------------------------------------- /src/data/parts/resize_up_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/resize_up_left.png -------------------------------------------------------------------------------- /src/data/parts/resize_up_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/resize_up_right.png -------------------------------------------------------------------------------- /src/data/parts/title_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/title_window.png -------------------------------------------------------------------------------- /src/data/parts/user_instructions_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/parts/user_instructions_window.png -------------------------------------------------------------------------------- /src/data/po/en.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/po/en.mo -------------------------------------------------------------------------------- /src/data/po/en.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2021-11-29 01:57-0300\n" 11 | "PO-Revision-Date: 2018-04-23 22:43+0200\n" 12 | "Last-Translator: \n" 13 | "Language-Team: \n" 14 | "Language: en\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: Poedit 1.8.7.1\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | 21 | #: src/application.py:406 22 | msgid "surface" 23 | msgstr "" 24 | 25 | #: src/application.py:407 26 | msgid "angle" 27 | msgstr "" 28 | 29 | #: src/application.py:411 30 | msgid "{} updated to {}" 31 | msgstr "" 32 | 33 | #: src/application.py:420 34 | msgid "retry" 35 | msgstr "" 36 | 37 | #: src/application.py:421 38 | msgid "do nothing" 39 | msgstr "" 40 | 41 | #: src/application.py:425 42 | msgid "increase" 43 | msgstr "" 44 | 45 | #: src/application.py:428 46 | msgid "" 47 | "Mesures were often over current {} limit, you can retry\n" 48 | " calibration more slowly{} or do nothing." 49 | msgstr "" 50 | 51 | #: src/application.py:432 52 | msgid ", increase {} to {} (but risk more misdetections)" 53 | msgstr "" 54 | 55 | #: src/application.py:2643 56 | #, python-format 57 | msgid "Please put the license dongle back to continue (exit in %ss)" 58 | msgstr "" 59 | 60 | #: src/settings_tmp.py:1 61 | msgid "General" 62 | msgstr "" 63 | 64 | #: src/settings_tmp.py:2 65 | msgid "language" 66 | msgstr "" 67 | 68 | #: src/settings_tmp.py:3 69 | msgid "language to display the application in" 70 | msgstr "" 71 | 72 | #: src/settings_tmp.py:4 73 | msgid "auto use" 74 | msgstr "" 75 | 76 | #: src/settings_tmp.py:5 77 | msgid "automatically start in 'use' mode" 78 | msgstr "" 79 | 80 | #: src/settings_tmp.py:6 81 | msgid "start minimized" 82 | msgstr "" 83 | 84 | #: src/settings_tmp.py:7 85 | msgid "the app minimizes itself at start" 86 | msgstr "" 87 | 88 | #: src/settings_tmp.py:8 89 | msgid "hide window in use mode" 90 | msgstr "" 91 | 92 | #: src/settings_tmp.py:9 93 | #, python-brace-format 94 | msgid "" 95 | "{NAME} hides itself in use mode, so it's possible to keep it at the top, " 96 | "[color=FF0000FF]please see the full documentation for the use case and " 97 | "effects of this setting[/color]" 98 | msgstr "" 99 | 100 | #: src/settings_tmp.py:10 101 | msgid "auto save" 102 | msgstr "" 103 | 104 | #: src/settings_tmp.py:11 105 | msgid "automatically save current profile on exit" 106 | msgstr "" 107 | 108 | #: src/settings_tmp.py:12 109 | msgid "Confirm exit" 110 | msgstr "" 111 | 112 | #: src/settings_tmp.py:13 113 | msgid "Ask for confirmation before exiting" 114 | msgstr "" 115 | 116 | #: src/settings_tmp.py:14 117 | msgid "screen mode" 118 | msgstr "" 119 | 120 | #: src/settings_tmp.py:15 121 | msgid "" 122 | "'primary' will display the window fullscreen on the primary display, 'all' " 123 | "will extend to cover all the available screens automatically, this assumes " 124 | "all your displayed are covered by your touch provider, make sure to adjust " 125 | "'screen width' and 'screen height' values in the 'Detection' section when " 126 | "using 'all'" 127 | msgstr "" 128 | 129 | #: src/settings_tmp.py:16 130 | msgid "TUIO" 131 | msgstr "" 132 | 133 | #: src/settings_tmp.py:17 134 | msgid "send TUIO touch moves" 135 | msgstr "" 136 | 137 | #: src/settings_tmp.py:18 138 | msgid "verbose tuio send updates about moving touches" 139 | msgstr "" 140 | 141 | #: src/settings_tmp.py:19 142 | msgid "TUIO events ip" 143 | msgstr "" 144 | 145 | #: src/settings_tmp.py:20 146 | msgid "destination ip to send tuio events to" 147 | msgstr "" 148 | 149 | #: src/settings_tmp.py:21 150 | msgid "TUIO events port" 151 | msgstr "" 152 | 153 | #: src/settings_tmp.py:22 154 | msgid "" 155 | "destination port to send tuio events to, you can use multiple values, " 156 | "separated by commas (e.g: 3337,3338), or express a range, using a minus sign " 157 | "(e.g 3337-3340), or mix both (e.g: 3337-3350,3389), unparsable values will " 158 | "be reset to default" 159 | msgstr "" 160 | 161 | #: src/settings_tmp.py:23 162 | msgid "TUIO flush interval" 163 | msgstr "" 164 | 165 | #: src/settings_tmp.py:24 166 | msgid "" 167 | "How often to flush the queue of tuio events, (in ms between two flush event)" 168 | msgstr "" 169 | 170 | #: src/settings_tmp.py:25 171 | msgid "Detection" 172 | msgstr "" 173 | 174 | #: src/settings_tmp.py:26 175 | msgid "Screen width" 176 | msgstr "" 177 | 178 | #: src/settings_tmp.py:27 179 | msgid "width of the capture screen" 180 | msgstr "" 181 | 182 | #: src/settings_tmp.py:28 183 | msgid "Screen height" 184 | msgstr "" 185 | 186 | #: src/settings_tmp.py:29 187 | msgid "height of the capture screen" 188 | msgstr "" 189 | 190 | #: src/settings_tmp.py:30 191 | msgid "Surface tolerance" 192 | msgstr "" 193 | 194 | #: src/settings_tmp.py:31 195 | msgid "surface that is tolerated as a difference from calibration" 196 | msgstr "" 197 | 198 | #: src/settings_tmp.py:32 199 | msgid "Angle tolerance" 200 | msgstr "" 201 | 202 | #: src/settings_tmp.py:33 203 | msgid "angle that is tolerated as a difference from calibration" 204 | msgstr "" 205 | 206 | #: src/settings_tmp.py:34 207 | msgid "Number of samples for calibration" 208 | msgstr "" 209 | 210 | #: src/settings_tmp.py:35 211 | msgid "number of different values to use for the post-calibration average" 212 | msgstr "" 213 | 214 | #: src/settings_tmp.py:36 215 | msgid "Display touches" 216 | msgstr "" 217 | 218 | #: src/settings_tmp.py:37 219 | msgid "Display currently detected touches" 220 | msgstr "" 221 | 222 | #: src/settings_tmp.py:38 223 | msgid "Display candidates matching score" 224 | msgstr "" 225 | 226 | #: src/settings_tmp.py:39 227 | msgid "Show matching scores for combinations of touches" 228 | msgstr "" 229 | 230 | #: src/settings_tmp.py:40 231 | msgid "Hide candidates matched objects" 232 | msgstr "" 233 | 234 | #: src/settings_tmp.py:41 235 | msgid "" 236 | "Remove matching scores of matched objects, disable to see why an object was " 237 | "matched to the set of points" 238 | msgstr "" 239 | 240 | #: src/settings_tmp.py:42 241 | msgid "undetect object leaving zones" 242 | msgstr "" 243 | 244 | #: src/settings_tmp.py:43 245 | msgid "when a detected object goes outside of the zones, undetect it" 246 | msgstr "" 247 | 248 | #: src/settings_tmp.py:44 249 | msgid "Keep missing touches" 250 | msgstr "" 251 | 252 | #: src/settings_tmp.py:45 253 | msgid "Keep missing touches in center/angle computations" 254 | msgstr "" 255 | 256 | #: src/settings_tmp.py:46 257 | msgid "Keep angle when object is incomplete" 258 | msgstr "" 259 | 260 | #: src/settings_tmp.py:47 261 | msgid "" 262 | "If the object has lost one or more touches, and is not yet fixed, only " 263 | "update position, not angle" 264 | msgstr "" 265 | 266 | #: src/settings_tmp.py:48 267 | msgid "Lost objects timeout" 268 | msgstr "" 269 | 270 | #: src/settings_tmp.py:49 271 | msgid "" 272 | "Keep lost objects for this number of milli-seconds, allowing the software to " 273 | "find them again without lost/find events" 274 | msgstr "" 275 | 276 | #: src/settings_tmp.py:50 277 | msgid "Number of trials for training" 278 | msgstr "" 279 | 280 | #: src/settings_tmp.py:51 281 | msgid "The number of tests one have to do for a training" 282 | msgstr "" 283 | 284 | #: src/settings_tmp.py:52 285 | msgid "Base detection interval" 286 | msgstr "" 287 | 288 | #: src/settings_tmp.py:53 289 | msgid "" 290 | "Interval betwen detection of object is dynamic, this is the smallest " 291 | "interval between two detections." 292 | msgstr "" 293 | 294 | #: src/settings_tmp.py:54 295 | msgid "behavior" 296 | msgstr "" 297 | 298 | #: src/settings_tmp.py:55 299 | msgid "Do angle filtering (experimental)" 300 | msgstr "" 301 | 302 | #: src/settings_tmp.py:56 303 | #, python-brace-format 304 | msgid "" 305 | "When enabled, {NAME} will try to prevent sudden angle changes, that may come " 306 | "from misdetection" 307 | msgstr "" 308 | 309 | #: src/settings_tmp.py:57 310 | msgid "Angle threshold" 311 | msgstr "" 312 | 313 | #: src/settings_tmp.py:58 314 | msgid "ignore sudden rotations bigger than this threshold value" 315 | msgstr "" 316 | 317 | #: src/settings_tmp.py:59 318 | msgid "Retain touch" 319 | msgstr "" 320 | 321 | #: src/settings_tmp.py:60 322 | msgid "Retain time" 323 | msgstr "" 324 | 325 | #: src/settings_tmp.py:61 326 | msgid "time to retain the touch for" 327 | msgstr "" 328 | 329 | #: src/settings_tmp.py:62 330 | msgid "Retain distance" 331 | msgstr "" 332 | 333 | #: src/settings_tmp.py:63 334 | msgid "max distance to consider new touch is the old one" 335 | msgstr "" 336 | 337 | #: src/settings_tmp.py:64 338 | msgid "Filter touches (experimental)" 339 | msgstr "" 340 | 341 | #: src/settings_tmp.py:65 342 | msgid "Use touch filter (requires restart)" 343 | msgstr "" 344 | 345 | #: src/settings_tmp.py:66 346 | msgid "minimum duration of a touch before considering it" 347 | msgstr "" 348 | 349 | #: src/settings_tmp.py:67 350 | msgid "" 351 | "wait for this time before propagating new touch events, introduce this delay " 352 | "in all touches" 353 | msgstr "" 354 | 355 | #: src/settings_tmp.py:68 356 | msgid "maximum speed of a new touch befored discarding it" 357 | msgstr "" 358 | 359 | #: src/settings_tmp.py:69 360 | msgid "" 361 | "while a touch being checked for duration, if its speed goes over this limit, " 362 | "discard it" 363 | msgstr "" 364 | 365 | #: src/application.kv:178 366 | msgid "Put your device on the calibration zone" 367 | msgstr "" 368 | 369 | #: src/application.kv:179 370 | msgid "Select an id to assign" 371 | msgstr "" 372 | 373 | #: src/application.kv:180 374 | msgid "id configured" 375 | msgstr "" 376 | 377 | #: src/application.kv:181 378 | msgid "too many devices" 379 | msgstr "" 380 | 381 | #: src/application.kv:201 382 | msgid "object calibration" 383 | msgstr "" 384 | 385 | #: src/application.kv:206 386 | msgid "object info" 387 | msgstr "" 388 | 389 | #: src/application.kv:214 390 | msgid "zones" 391 | msgstr "" 392 | 393 | #: src/application.kv:219 394 | msgid "load/new" 395 | msgstr "" 396 | 397 | #: src/application.kv:225 398 | msgid "save" 399 | msgstr "" 400 | 401 | #: src/application.kv:231 402 | msgid "use" 403 | msgstr "" 404 | 405 | #: src/application.kv:236 406 | msgid "settings" 407 | msgstr "" 408 | 409 | #: src/application.kv:560 410 | msgid "Demo" 411 | msgstr "" 412 | 413 | #: src/application.kv:600 414 | msgid "successes" 415 | msgstr "" 416 | 417 | #: src/application.kv:605 418 | msgid "direct successes" 419 | msgstr "" 420 | 421 | #: src/application.kv:610 422 | msgid "failures" 423 | msgstr "" 424 | 425 | #: src/application.kv:615 426 | msgid "errors" 427 | msgstr "" 428 | 429 | #: src/application.kv:620 430 | msgid "average failure surface difference" 431 | msgstr "" 432 | 433 | #: src/application.kv:625 434 | msgid "average failure angle difference" 435 | msgstr "" 436 | 437 | #: src/application.kv:630 438 | msgid "average surface difference" 439 | msgstr "" 440 | 441 | #: src/application.kv:635 442 | msgid "average angle difference" 443 | msgstr "" 444 | 445 | #: src/application.kv:640 446 | msgid "total samples collected" 447 | msgstr "" 448 | 449 | #: src/application.kv:645 450 | msgid "average samples per candidate" 451 | msgstr "" 452 | 453 | #: src/application.kv:650 454 | msgid "repartition of matches (figure)" 455 | msgstr "" 456 | 457 | #: src/application.kv:653 458 | msgid "variations of points positions (figure)" 459 | msgstr "" 460 | 461 | #: src/application.kv:799 462 | msgid "rotate me slowly to complete calibration" 463 | msgstr "" 464 | 465 | #: src/application.kv:894 466 | msgid "Exit?" 467 | msgstr "" 468 | 469 | #: src/application.kv:900 470 | msgid "config will be saved" 471 | msgstr "" 472 | 473 | #: src/application.kv:900 474 | msgid "configuration won't be saved" 475 | msgstr "" 476 | 477 | #: src/application.kv:905 478 | msgid "Cancel" 479 | msgstr "" 480 | 481 | #: src/application.kv:908 482 | msgid "Ok" 483 | msgstr "" 484 | 485 | #: src/application.kv:913 486 | #, python-format 487 | msgid "Select a profile to save to: %s" 488 | msgstr "" 489 | 490 | #: src/application.kv:938 src/application.kv:1223 491 | msgid "ok" 492 | msgstr "" 493 | 494 | #: src/application.kv:944 495 | msgid "delete" 496 | msgstr "" 497 | 498 | #: src/application.kv:949 499 | msgid "cancel" 500 | msgstr "" 501 | 502 | #: src/application.kv:954 503 | #, python-format 504 | msgid "Select a profile to load %s" 505 | msgstr "" 506 | 507 | #: src/application.kv:970 508 | msgid "forget" 509 | msgstr "" 510 | 511 | #: src/application.kv:1029 512 | msgid "avg" 513 | msgstr "" 514 | 515 | #: src/application.kv:1039 516 | msgid "len" 517 | msgstr "" 518 | 519 | #: src/application.kv:1049 520 | msgid "min" 521 | msgstr "" 522 | 523 | #: src/application.kv:1058 524 | msgid "max" 525 | msgstr "" 526 | 527 | #: src/application.kv:1175 528 | msgid "close" 529 | msgstr "" 530 | 531 | #: src/application.kv:1217 532 | msgid "Demonstration finished, the program will now exit" 533 | msgstr "" 534 | 535 | #: src/application.kv:1277 536 | msgid "Contact us at: " 537 | msgstr "" 538 | 539 | #: src/application.kv:1284 540 | msgid "machine identification: " 541 | msgstr "" 542 | 543 | #: src/application.kv:1285 544 | #, python-brace-format 545 | msgid "License Ok, you can now run {name}." 546 | msgstr "" 547 | 548 | #: src/application.kv:1354 549 | msgid "copy to clipboard" 550 | msgstr "" 551 | 552 | #: src/application.kv:1357 553 | msgid "copied!" 554 | msgstr "" 555 | 556 | #: src/application.kv:1376 557 | msgid "start demo" 558 | msgstr "" 559 | 560 | #: src/application.kv:1392 561 | msgid "exit" 562 | msgstr "" 563 | 564 | #: src/application.kv:1401 565 | msgid "run" 566 | msgstr "" 567 | -------------------------------------------------------------------------------- /src/data/po/fr.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/po/fr.mo -------------------------------------------------------------------------------- /src/data/theme-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/theme-0.png -------------------------------------------------------------------------------- /src/data/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data/theme-1.png -------------------------------------------------------------------------------- /src/data/theme.atlas: -------------------------------------------------------------------------------- 1 | {"theme-0.png": {"resize_up_left": [3934, 2832, 118, 117], "info_window": [3330, 1424, 459, 114], "menu_save_gradient": [3856, 892, 226, 41], "36": [3992, 2465, 56, 47], "radar": [2, 1935, 3059, 2159], "user_instructions_window": [3063, 1962, 840, 148], "menu_settings_gradient": [3712, 1381, 162, 41], "32": [3992, 2563, 56, 47], "34": [3992, 2514, 56, 47], "icon_objectViz": [3856, 935, 149, 150], "1": [4036, 2626, 56, 47], "26": [3745, 761, 56, 47], "credits_window": [2120, 755, 637, 330], "20": [3397, 761, 56, 47], "21": [3455, 761, 56, 47], "22": [3513, 761, 56, 47], "23": [3571, 761, 56, 47], "19": [3281, 761, 56, 47], "info_panel": [3398, 879, 456, 206], "object_lost_light_hard": [600, 2, 297, 297], "28": [3861, 761, 56, 47], "29": [3919, 761, 56, 47], "lock_close": [3941, 1789, 144, 144], "mods_window": [3330, 1540, 609, 393], "menu_object calibration_gradient": [3398, 836, 357, 41], "27": [3803, 761, 56, 47], "3": [3977, 761, 56, 47], "2": [3339, 761, 56, 47], "5": [3992, 2416, 56, 47], "4": [3934, 2416, 56, 47], "7": [3992, 2367, 56, 47], "6": [3934, 2367, 56, 47], "9": [3992, 2318, 56, 47], "31": [3934, 2563, 56, 47], "icon1024": [3063, 3070, 1024, 1024], "menu_use_gradient": [3513, 1381, 197, 41], "resize_up_right": [3941, 1668, 118, 119], "11": [2817, 761, 56, 47], "bg_piece": [4007, 941, 72, 68], "menu_load - new_gradient": [3791, 1455, 258, 40], "25": [3687, 761, 56, 47], "33": [3934, 2514, 56, 47], "menu_zones_gradient": [3791, 1497, 289, 41], "background_radar": [1727, 1201, 730, 732], "object_ID_angle_info": [3330, 1365, 181, 57], "resize_down_right": [3934, 2951, 119, 117], "12": [2875, 761, 56, 47], "graduations": [2, 1087, 852, 846], "8": [3934, 2318, 56, 47], "background": [1496, 707, 622, 378], "24": [3629, 761, 56, 47], "object_recognised_light_hard": [899, 2, 297, 297], "moving_parts": [2, 301, 790, 784], "hand": [3934, 2612, 100, 61], "title_window": [2459, 1247, 420, 96], "info": [3934, 2675, 95, 88], "10": [2759, 761, 56, 47], "13": [2933, 761, 56, 47], "nb_points": [4007, 1011, 74, 74], "15": [3049, 761, 56, 47], "14": [2991, 761, 56, 47], "17": [3165, 761, 56, 47], "16": [3107, 761, 56, 47], "logo_watermark": [794, 462, 700, 623], "resize_down_left": [3941, 1547, 117, 119], "glow_gray": [2, 2, 297, 297], "30": [4035, 761, 56, 47], "object_infox5": [3063, 2112, 869, 956], "object_infox4": [856, 1157, 869, 776], "35": [3934, 2465, 56, 47], "menu_object info_gradient": [3757, 836, 314, 41], "glow_lost": [301, 2, 297, 297], "credits_window_notext": [2759, 810, 637, 275], "18": [3223, 761, 56, 47], "lock_open": [3905, 1966, 145, 144], "hand_inv": [3934, 2765, 132, 65], "object_infox3": [2459, 1345, 869, 588], "icon_objectViz_64": [4031, 2699, 64, 64]}, "theme-1.png": {"object_recognised": [358, 3644, 354, 450], "object_lost": [2, 3644, 354, 450]}} -------------------------------------------------------------------------------- /src/data_override/cn/credits.txt: -------------------------------------------------------------------------------- 1 | VTable 2 | Version {version} 3 | 4 | Created by the V+ Interactive team. 5 | ©2013-{year} V+ Interactive and its licensors. All rights reserved. 6 | The V logo is a registered trademark of V+ Interactive China. 7 | 8 | www.dcb.fun 9 | 10 | -.-- --- ..- 11 | -.-. .- -. 12 | --. . - 13 | .. - 14 | .. ..-. 15 | -.-- --- ..- 16 | .-. . .- .-.. .-.. -.-- 17 | .-- .- -. - 18 | -------------------------------------------------------------------------------- /src/data_override/cn/font.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/font.otf -------------------------------------------------------------------------------- /src/data_override/cn/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/icon.ico -------------------------------------------------------------------------------- /src/data_override/cn/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/icon.png -------------------------------------------------------------------------------- /src/data_override/cn/icons/icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/icon1024.png -------------------------------------------------------------------------------- /src/data_override/cn/icons/icon_64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/icon_64.ico -------------------------------------------------------------------------------- /src/data_override/cn/icons/icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/icon_64.png -------------------------------------------------------------------------------- /src/data_override/cn/icons/logo_watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/icons/logo_watermark.png -------------------------------------------------------------------------------- /src/data_override/cn/locales/zh/LC_MESSAGES/app.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/locales/zh/LC_MESSAGES/app.mo -------------------------------------------------------------------------------- /src/data_override/cn/po/zh.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/po/zh.mo -------------------------------------------------------------------------------- /src/data_override/cn/theme-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/theme-0.png -------------------------------------------------------------------------------- /src/data_override/cn/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn/theme-1.png -------------------------------------------------------------------------------- /src/data_override/cn/theme.atlas: -------------------------------------------------------------------------------- 1 | {"theme-0.png": {"radar": [2, 1935, 3059, 2159], "icon1024": [3063, 3070, 1024, 1024], "object_infox5": [3063, 2112, 869, 956], "graduations": [2, 1087, 852, 846], "object_infox4": [856, 1157, 869, 776], "moving_parts": [2, 301, 790, 784], "background_radar": [1727, 1201, 730, 732], "object_infox3": [2459, 1345, 869, 588], "logo_watermark": [794, 462, 700, 623], "mods_window": [3330, 1540, 609, 393], "background": [1496, 707, 622, 378], "credits_window": [2120, 755, 637, 330], "credits_window_notext": [2759, 810, 637, 275], "user_instructions_window": [3063, 1962, 840, 148], "info_panel": [3398, 879, 456, 206], "glow_gray": [2, 2, 297, 297], "glow_lost": [301, 2, 297, 297], "object_lost_light_hard": [600, 2, 297, 297], "object_recognised_light_hard": [899, 2, 297, 297], "info_window": [3330, 1424, 459, 114], "title_window": [2459, 1247, 420, 96], "icon": [3856, 935, 149, 150], "lock_open": [3905, 1966, 145, 144], "lock_close": [3941, 1789, 144, 144], "menu_object calibration_gradient": [3398, 836, 357, 41], "resize_up_right": [3941, 1668, 118, 119], "resize_down_left": [3941, 1547, 117, 119], "resize_down_right": [3934, 2951, 119, 117], "resize_up_left": [3934, 2832, 118, 117], "menu_object info_gradient": [3757, 836, 314, 41], "menu_zones_gradient": [3791, 1497, 289, 41], "menu_load - new_gradient": [3791, 1455, 258, 40], "object_ID_angle_info": [3330, 1365, 181, 57], "menu_save_gradient": [3856, 892, 226, 41], "hand_inv": [3934, 2765, 132, 65], "info": [3934, 2675, 95, 88], "menu_use_gradient": [3513, 1381, 197, 41], "menu_settings_gradient": [3712, 1381, 162, 41], "hand": [3934, 2612, 100, 61], "nb_points": [4007, 1011, 74, 74], "bg_piece": [4007, 941, 72, 68], "icon_64": [4031, 2699, 64, 64], "1": [4036, 2626, 56, 47], "10": [2759, 761, 56, 47], "11": [2817, 761, 56, 47], "12": [2875, 761, 56, 47], "13": [2933, 761, 56, 47], "14": [2991, 761, 56, 47], "15": [3049, 761, 56, 47], "16": [3107, 761, 56, 47], "17": [3165, 761, 56, 47], "18": [3223, 761, 56, 47], "19": [3281, 761, 56, 47], "2": [3339, 761, 56, 47], "20": [3397, 761, 56, 47], "21": [3455, 761, 56, 47], "22": [3513, 761, 56, 47], "23": [3571, 761, 56, 47], "24": [3629, 761, 56, 47], "25": [3687, 761, 56, 47], "26": [3745, 761, 56, 47], "27": [3803, 761, 56, 47], "28": [3861, 761, 56, 47], "29": [3919, 761, 56, 47], "3": [3977, 761, 56, 47], "30": [4035, 761, 56, 47], "31": [3934, 2563, 56, 47], "32": [3992, 2563, 56, 47], "33": [3934, 2514, 56, 47], "34": [3992, 2514, 56, 47], "35": [3934, 2465, 56, 47], "36": [3992, 2465, 56, 47], "4": [3934, 2416, 56, 47], "5": [3992, 2416, 56, 47], "6": [3934, 2367, 56, 47], "7": [3992, 2367, 56, 47], "8": [3934, 2318, 56, 47], "9": [3992, 2318, 56, 47]}, "theme-1.png": {"object_lost": [2, 3644, 354, 450], "object_recognised": [358, 3644, 354, 450]}} 2 | -------------------------------------------------------------------------------- /src/data_override/cn_2/credits.txt: -------------------------------------------------------------------------------- 1 | VTable 2 | Version {version} 3 | 4 | Created by the V+ Interactive team. 5 | 2013-{year} V+ Interactive and its licensors. All rights reserved. 6 | The V logo is a registered trademark of V+ Interactive . 7 | 8 | 9 | -.-- --- ..- 10 | -.-. .- -. 11 | --. . - 12 | .. - 13 | .. ..-. 14 | -.-- --- ..- 15 | .-. . .- .-.. .-.. -.-- 16 | .-- .- -. - 17 | -------------------------------------------------------------------------------- /src/data_override/cn_2/font.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/font.otf -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/icon.ico -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/icon.png -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/icon1024.png -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/icon_64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/icon_64.ico -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/icon_64.png -------------------------------------------------------------------------------- /src/data_override/cn_2/icons/logo_watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/icons/logo_watermark.png -------------------------------------------------------------------------------- /src/data_override/cn_2/locales/zh/LC_MESSAGES/app.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/locales/zh/LC_MESSAGES/app.mo -------------------------------------------------------------------------------- /src/data_override/cn_2/po/zh.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/po/zh.mo -------------------------------------------------------------------------------- /src/data_override/cn_2/theme-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/theme-0.png -------------------------------------------------------------------------------- /src/data_override/cn_2/theme-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/cn_2/theme-1.png -------------------------------------------------------------------------------- /src/data_override/cn_2/theme.atlas: -------------------------------------------------------------------------------- 1 | {"theme-0.png": {"radar": [2, 1935, 3059, 2159], "icon1024": [3063, 3070, 1024, 1024], "object_infox5": [3063, 2112, 869, 956], "graduations": [2, 1087, 852, 846], "object_infox4": [856, 1157, 869, 776], "moving_parts": [2, 301, 790, 784], "background_radar": [1727, 1201, 730, 732], "object_infox3": [2459, 1345, 869, 588], "logo_watermark": [794, 462, 700, 623], "mods_window": [3330, 1540, 609, 393], "background": [1496, 707, 622, 378], "credits_window": [2120, 755, 637, 330], "credits_window_notext": [2759, 810, 637, 275], "user_instructions_window": [3063, 1962, 840, 148], "info_panel": [3398, 879, 456, 206], "glow_gray": [2, 2, 297, 297], "glow_lost": [301, 2, 297, 297], "object_lost_light_hard": [600, 2, 297, 297], "object_recognised_light_hard": [899, 2, 297, 297], "info_window": [3330, 1424, 459, 114], "title_window": [2459, 1247, 420, 96], "icon": [3856, 935, 149, 150], "lock_open": [3905, 1966, 145, 144], "lock_close": [3941, 1789, 144, 144], "menu_object calibration_gradient": [3398, 836, 357, 41], "resize_up_right": [3941, 1668, 118, 119], "resize_down_left": [3941, 1547, 117, 119], "resize_down_right": [3934, 2951, 119, 117], "resize_up_left": [3934, 2832, 118, 117], "menu_object info_gradient": [3757, 836, 314, 41], "menu_zones_gradient": [3791, 1497, 289, 41], "menu_load - new_gradient": [3791, 1455, 258, 40], "object_ID_angle_info": [3330, 1365, 181, 57], "menu_save_gradient": [3856, 892, 226, 41], "hand_inv": [3934, 2765, 132, 65], "info": [3934, 2675, 95, 88], "menu_use_gradient": [3513, 1381, 197, 41], "menu_settings_gradient": [3712, 1381, 162, 41], "hand": [3934, 2612, 100, 61], "nb_points": [4007, 1011, 74, 74], "bg_piece": [4007, 941, 72, 68], "icon_64": [4031, 2699, 64, 64], "1": [4036, 2626, 56, 47], "10": [2759, 761, 56, 47], "11": [2817, 761, 56, 47], "12": [2875, 761, 56, 47], "13": [2933, 761, 56, 47], "14": [2991, 761, 56, 47], "15": [3049, 761, 56, 47], "16": [3107, 761, 56, 47], "17": [3165, 761, 56, 47], "18": [3223, 761, 56, 47], "19": [3281, 761, 56, 47], "2": [3339, 761, 56, 47], "20": [3397, 761, 56, 47], "21": [3455, 761, 56, 47], "22": [3513, 761, 56, 47], "23": [3571, 761, 56, 47], "24": [3629, 761, 56, 47], "25": [3687, 761, 56, 47], "26": [3745, 761, 56, 47], "27": [3803, 761, 56, 47], "28": [3861, 761, 56, 47], "29": [3919, 761, 56, 47], "3": [3977, 761, 56, 47], "30": [4035, 761, 56, 47], "31": [3934, 2563, 56, 47], "32": [3992, 2563, 56, 47], "33": [3934, 2514, 56, 47], "34": [3992, 2514, 56, 47], "35": [3934, 2465, 56, 47], "36": [3992, 2465, 56, 47], "4": [3934, 2416, 56, 47], "5": [3992, 2416, 56, 47], "6": [3934, 2367, 56, 47], "7": [3992, 2367, 56, 47], "8": [3934, 2318, 56, 47], "9": [3992, 2318, 56, 47]}, "theme-1.png": {"object_lost": [2, 3644, 354, 450], "object_recognised": [358, 3644, 354, 450]}} 2 | -------------------------------------------------------------------------------- /src/data_override/no-logo/icons/logo_watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/no-logo/icons/logo_watermark.png -------------------------------------------------------------------------------- /src/data_override/no-logo/parts/credits_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/no-logo/parts/credits_window.png -------------------------------------------------------------------------------- /src/data_override/no-logo/parts/credits_window_notext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/data_override/no-logo/parts/credits_window_notext.png -------------------------------------------------------------------------------- /src/ddpro.h: -------------------------------------------------------------------------------- 1 | int __stdcall DDProtCheck(void*, unsigned char*); 2 | -------------------------------------------------------------------------------- /src/lang.py: -------------------------------------------------------------------------------- 1 | from kivy.lang import Observable 2 | from os.path import join, dirname 3 | from os import getcwd 4 | import gettext 5 | 6 | 7 | class Lang(Observable): 8 | observers = [] 9 | lang = None 10 | 11 | def __init__(self, defaultlang): 12 | super(Lang, self).__init__() 13 | self.ugettext = None 14 | self.lang = defaultlang 15 | self.switch_lang(self.lang) 16 | 17 | def _(self, text): 18 | return self.ugettext(text) 19 | 20 | def fbind(self, name, func, args, **kwargs): 21 | if name == "_": 22 | self.observers.append((func, args, kwargs)) 23 | else: 24 | return super(Lang, self).fbind(name, func, *args, **kwargs) 25 | 26 | def funbind(self, name, func, args, **kwargs): 27 | if name == "_": 28 | key = (func, args, kwargs) 29 | if key in self.observers: 30 | self.observers.remove(key) 31 | else: 32 | return super(Lang, self).funbind(name, func, *args, **kwargs) 33 | 34 | def switch_lang(self, lang): 35 | # get the right locales directory, and instanciate a gettext 36 | try: 37 | d = dirname(__file__) 38 | except NameError: 39 | d = getcwd() 40 | locale_dir = join(d, 'data', 'locales') 41 | 42 | locales = gettext.translation('app', locale_dir, languages=[lang]) 43 | self.ugettext = locales.gettext 44 | 45 | # update all the kv rules attached to this text 46 | for func, largs, kwargs in self.observers: 47 | try: 48 | func(largs, None, None) 49 | except ReferenceError: 50 | pass 51 | 52 | 53 | tr = Lang('en') 54 | -------------------------------------------------------------------------------- /src/layouts/__init__.py: -------------------------------------------------------------------------------- 1 | from .letterbox_view import LetterboxView 2 | -------------------------------------------------------------------------------- /src/layouts/letterbox_view.kv: -------------------------------------------------------------------------------- 1 | : 2 | optimal_width: 100 3 | optimal_height: 100 4 | 5 | optimal_width_ratio: self.width / self.optimal_width 6 | optimal_height_ratio: self.height / self.optimal_height 7 | 8 | aspect_ratio: float(self.width) / self.height 9 | optimal_aspect_ratio: self.optimal_width / self.optimal_height 10 | 11 | size_factor: self.optimal_width_ratio if(self.aspect_ratio < self.optimal_aspect_ratio) else self.optimal_height_ratio 12 | 13 | LetterboxContainer: 14 | id: container 15 | 16 | : 17 | pos_hint: {'center_x': .5, 'center_y': .5} 18 | size: 19 | (self.parent.optimal_width * self.parent.size_factor, self.parent.optimal_height * self.parent.size_factor) \ 20 | if self.parent and self.parent.size_factor else (100, 100) 21 | size_hint: [None, None] 22 | -------------------------------------------------------------------------------- /src/layouts/letterbox_view.py: -------------------------------------------------------------------------------- 1 | from kivy.uix.relativelayout import FloatLayout 2 | from utils import load_kv 3 | 4 | 5 | class LetterboxView(FloatLayout): 6 | def add_widget(self, widget, index=0): 7 | if 'container' in self.ids: 8 | self.ids.container.add_widget(widget, index) 9 | else: 10 | super(LetterboxView, self).add_widget(widget, index) 11 | 12 | load_kv() 13 | -------------------------------------------------------------------------------- /src/libdpwin64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/libdpwin64.a -------------------------------------------------------------------------------- /src/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | #exclude 4 | ''' 5 | WITH_SENTRY_URL = None 6 | WITH_DEBUG = False 7 | WITH_NAME = '' 8 | 9 | import condiment 10 | condiment.install() 11 | ''' 12 | #endexclude 13 | ''' 14 | 15 | NAME = 'ObjectViz' 16 | 17 | 18 | if WITH_NAME: 19 | NAME = 'WITH_NAME' 20 | 21 | if __name__ in ('__main__', 'main', ''): 22 | try: 23 | from application import app 24 | app.run() 25 | except Exception as e: 26 | if WITH_DEBUG: 27 | import pudb; pudb.post_mortem() 28 | if WITH_SENTRY_URL: 29 | from raven import Client 30 | c = Client('WITH_SENTRY_URL') 31 | c.captureException() 32 | raise 33 | 34 | from kivy.utils import platform 35 | from kivy.app import App 36 | import psutil 37 | import sys 38 | if sys.platform == 'win': 39 | import winxpgui 40 | -------------------------------------------------------------------------------- /src/settings.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "tr_title", 4 | "tr_title": "General" 5 | }, 6 | { 7 | "type": "tr_langs", 8 | "tr_title": "language", 9 | "tr_desc": "language to display the application in", 10 | "section": "general", 11 | "key": "lang" 12 | }, 13 | { 14 | "type": "tr_bool", 15 | "values": ["False", "True"], 16 | "tr_title": "auto use", 17 | "tr_desc": "automatically start in 'use' mode", 18 | "section": "general", 19 | "key": "auto_use" 20 | }, 21 | { 22 | "type": "tr_bool", 23 | "values": ["False", "True"], 24 | "platform": "win", 25 | "tr_title": "start minimized", 26 | "tr_desc": "the app minimizes itself at start", 27 | "section": "general", 28 | "key": "minimized_start" 29 | }, 30 | { 31 | "type": "tr_bool", 32 | "values": ["False", "True"], 33 | "platform": "win", 34 | "tr_title": "hide window in use mode", 35 | "tr_desc": "{NAME} hides itself in use mode, so it's possible to keep it at the top, [color=FF0000FF]please see the full documentation for the use case and effects of this setting[/color]", 36 | "section": "general", 37 | "key": "hidden_use_mode" 38 | }, 39 | { 40 | "type": "tr_bool", 41 | "values": ["False", "True"], 42 | "tr_title": "auto save", 43 | "tr_desc": "automatically save current profile on exit", 44 | "section": "general", 45 | "key": "auto_save" 46 | }, 47 | { 48 | "type": "tr_bool", 49 | "values": ["False", "True"], 50 | "tr_title": "Confirm exit", 51 | "tr_desc": "Ask for confirmation before exiting", 52 | "section": "general", 53 | "key": "confirm_exit" 54 | }, 55 | { 56 | "type": "tr_options", 57 | "options": ["primary", "all"], 58 | "tr_title": "screen mode", 59 | "tr_desc": "'primary' will display the window fullscreen on the primary display, 'all' will extend to cover all the available screens automatically, this assumes all your displayed are covered by your touch provider, make sure to adjust 'screen width' and 'screen height' values in the 'Detection' section when using 'all'", 60 | "section": "general", 61 | "key": "screen_mode" 62 | }, 63 | { 64 | "type": "tr_title", 65 | "tr_title": "TUIO" 66 | }, 67 | { 68 | "type": "tr_bool", 69 | "values": ["False", "True"], 70 | "platform": "none", 71 | "tr_title": "send TUIO touch moves", 72 | "tr_desc": "verbose tuio send updates about moving touches", 73 | "section": "tuio", 74 | "key": "send_tuio_touch_send_touch_move" 75 | }, 76 | { 77 | "type": "tr_string", 78 | "tr_title": "TUIO events ip", 79 | "tr_desc": "destination ip to send tuio events to", 80 | "section": "tuio", 81 | "key": "send_tuio_ip" 82 | }, 83 | { 84 | "type": "tr_string", 85 | "tr_title": "TUIO events port", 86 | "tr_desc": "destination port to send tuio events to, you can use multiple values, separated by commas (e.g: 3337,3338), or express a range, using a minus sign (e.g 3337-3340), or mix both (e.g: 3337-3350,3389), unparsable values will be reset to default", 87 | "section": "tuio", 88 | "key": "send_tuio_port" 89 | }, 90 | { 91 | "type": "tr_numeric", 92 | "tr_title": "TUIO flush interval", 93 | "tr_desc": "How often to flush the queue of tuio events, (in ms between two flush event)", 94 | "section": "tuio", 95 | "key": "tuio_flush_interval" 96 | }, 97 | { 98 | "type": "tr_title", 99 | "tr_title": "Detection" 100 | }, 101 | { 102 | "type": "tr_numeric", 103 | "tr_title": "Screen width", 104 | "tr_desc": "width of the capture screen", 105 | "section": "tuio", 106 | "key": "screen_ratio_width" 107 | }, 108 | { 109 | "type": "tr_numeric", 110 | "tr_title": "Screen height", 111 | "tr_desc": "height of the capture screen", 112 | "section": "tuio", 113 | "key": "screen_ratio_height" 114 | }, 115 | { 116 | "type": "tr_numeric", 117 | "tr_title": "Surface tolerance", 118 | "tr_desc": "surface that is tolerated as a difference from calibration", 119 | "section": "detection", 120 | "key": "surface_tolerance" 121 | }, 122 | { 123 | "type": "tr_numeric", 124 | "tr_title": "Angle tolerance", 125 | "tr_desc": "angle that is tolerated as a difference from calibration", 126 | "section": "detection", 127 | "key": "angle_tolerance" 128 | }, 129 | { 130 | "type": "tr_numeric", 131 | "tr_title": "Number of samples for calibration", 132 | "tr_desc": "number of different values to use for the post-calibration average", 133 | "section": "detection", 134 | "key": "nb_value_average" 135 | }, 136 | { 137 | "type": "tr_bool", 138 | "values": ["False", "True"], 139 | "tr_title": "Display touches", 140 | "tr_desc": "Display currently detected touches", 141 | "section": "detection", 142 | "key": "display_touches" 143 | }, 144 | { 145 | "type": "tr_bool", 146 | "values": ["False", "True"], 147 | "tr_title": "Display candidates matching score", 148 | "tr_desc": "Show matching scores for combinations of touches", 149 | "section": "detection", 150 | "key": "display_scores" 151 | }, 152 | { 153 | "type": "tr_bool", 154 | "values": ["False", "True"], 155 | "tr_title": "Hide candidates matched objects", 156 | "tr_desc": "Remove matching scores of matched objects, disable to see why an object was matched to the set of points", 157 | "section": "detection", 158 | "key": "cleanup_matched_objects" 159 | }, 160 | { 161 | "type": "tr_bool", 162 | "values": ["False", "True"], 163 | "tr_title": "undetect object leaving zones", 164 | "tr_desc": "when a detected object goes outside of the zones, undetect it", 165 | "section": "detection", 166 | "key": "undetect_outside_zones" 167 | }, 168 | { 169 | "type": "tr_bool", 170 | "values": ["False", "True"], 171 | "tr_title": "Keep missing touches", 172 | "tr_desc": "Keep missing touches in center/angle computations", 173 | "section": "detection", 174 | "key": "keep_missing_touches" 175 | }, 176 | { 177 | "type": "tr_bool", 178 | "values": ["False", "True"], 179 | "tr_title": "Keep angle when object is incomplete", 180 | "tr_desc": "If the object has lost one or more touches, and is not yet fixed, only update position, not angle", 181 | "section": "detection", 182 | "key": "keep_angle_on_incomplete_object" 183 | }, 184 | { 185 | "type": "tr_numeric", 186 | "tr_title": "Lost objects timeout", 187 | "tr_desc": "Keep lost objects for this number of milli-seconds, allowing the software to find them again without lost/find events", 188 | "section": "detection", 189 | "key": "lost_object_timeout" 190 | }, 191 | { 192 | "type": "tr_numeric", 193 | "tr_title": "Number of trials for training", 194 | "dev_only": true, 195 | "tr_desc": "The number of tests one have to do for a training", 196 | "section": "detection", 197 | "key": "training_length" 198 | }, 199 | { 200 | "type": "tr_numeric", 201 | "tr_title": "Base detection interval", 202 | "tr_desc": "Interval betwen detection of object is dynamic, this is the smallest interval between two detections.", 203 | "section": "detection", 204 | "key": "object_detection_interval" 205 | }, 206 | { 207 | "platform": "none", 208 | "type": "tr_title", 209 | "tr_title": "behavior" 210 | }, 211 | { 212 | "type": "tr_bool", 213 | "values": ["False", "True"], 214 | "platform": "none", 215 | "tr_title": "Do angle filtering (experimental)", 216 | "tr_desc": "When enabled, {NAME} will try to prevent sudden angle changes, that may come from misdetection", 217 | "section": "behavior", 218 | "key": "do_angle_filtering" 219 | }, 220 | { 221 | "type": "tr_numeric", 222 | "platform": "none", 223 | "tr_title": "Angle threshold", 224 | "tr_desc": "ignore sudden rotations bigger than this threshold value", 225 | "section": "behavior", 226 | "key": "angle_threshold" 227 | }, 228 | { 229 | "type": "tr_title", 230 | "tr_title": "Retain touch" 231 | }, 232 | { 233 | "type": "tr_numeric", 234 | "tr_title": "Retain time", 235 | "tr_desc": "time to retain the touch for", 236 | "section": "retain touch", 237 | "key": "retain_time" 238 | }, 239 | { 240 | "type": "tr_numeric", 241 | "tr_title": "Retain distance", 242 | "tr_desc": "max distance to consider new touch is the old one", 243 | "section": "retain touch", 244 | "key": "retain_distance" 245 | }, 246 | { 247 | "type": "tr_title", 248 | "platform": "none", 249 | "tr_title": "Filter touches (experimental)" 250 | }, 251 | { 252 | "type": "tr_bool", 253 | "platform": "none", 254 | "tr_title": "Use touch filter (requires restart)", 255 | "section": "filter", 256 | "key": "do_filter_touches" 257 | }, 258 | { 259 | "type": "tr_numeric", 260 | "platform": "none", 261 | "tr_title": "minimum duration of a touch before considering it", 262 | "tr_desc": "wait for this time before propagating new touch events, introduce this delay in all touches", 263 | "section": "filter", 264 | "key": "min_duration" 265 | }, 266 | { 267 | "type": "tr_numeric", 268 | "platform": "none", 269 | "tr_title": "maximum speed of a new touch befored discarding it", 270 | "tr_desc": "while a touch being checked for duration, if its speed goes over this limit, discard it", 271 | "section": "filter", 272 | "key": "max_speed" 273 | } 274 | ] 275 | -------------------------------------------------------------------------------- /src/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from screeninfo.screeninfo import get_monitors 2 | 3 | from inspect import currentframe 4 | from os.path import exists 5 | from ast import literal_eval 6 | from subprocess import Popen 7 | 8 | from kivy.compat import string_types 9 | from kivy.lang import Builder 10 | from kivy.logger import Logger 11 | 12 | DATEFORMAT = '%Y-%m-%d_%H-%M-%S' 13 | 14 | 15 | def configbool(value): 16 | """Function used to decode ConfigParser boolean values 17 | """ 18 | if isinstance(value, string_types): 19 | return value.lower() not in ('false', 'no', '') 20 | return bool(value) 21 | 22 | 23 | def configlist(value): 24 | if isinstance(value, string_types): 25 | return literal_eval(value) 26 | 27 | 28 | def load_kv(): 29 | filename = currentframe().f_back.f_code.co_filename 30 | if '_ft_' in filename: 31 | filename = filename.replace('_ft_', '') 32 | 33 | f = filename[:-2] + 'kv' 34 | if exists(f): 35 | return Builder.load_file(f) 36 | 37 | 38 | def get_screen_resolution(mode): 39 | if mode == 'primary': 40 | screens = [get_monitors()[0]] 41 | elif mode == 'all': 42 | screens = get_monitors() 43 | else: 44 | Logger.warn( 45 | 'invalid screen mode selected: {}, defaulting to primary' 46 | .format(mode) 47 | ) 48 | screens = [get_monitors()[0]] 49 | 50 | x = min(m.x for m in screens) 51 | y = min(m.y for m in screens) 52 | width = max(m.x + m.width for m in screens) - x 53 | height = max(m.y + m.height for m in screens) - y 54 | return x, y, width, height 55 | -------------------------------------------------------------------------------- /src/utils/math.pyx: -------------------------------------------------------------------------------- 1 | from operator import mul 2 | from libc.math cimport atan2 3 | from libc.math cimport M_PI as pi 4 | 5 | INF = float('inf') 6 | NAN = float('nan') 7 | 8 | 9 | def angle_diff(a1, a2): 10 | """Reports the angular difference between two angles""" 11 | 12 | d = abs(a1 - a2 % 360) 13 | if d > 180: 14 | # this happens when the angle goes from 360 to 0 15 | d = - (min(a1, a2) + 360 - max(a1, a2)) 16 | return d if a1 < a2 else -d 17 | 18 | 19 | def get_scale_factor(points): 20 | if not points: 21 | return 1, 1 22 | 23 | mw = max(p[0] for p in points) 24 | mh = max(p[1] for p in points) 25 | 26 | return mw, mh 27 | 28 | 29 | def autoscale_points(points, scale, size, pos): 30 | mw, mh = scale 31 | width, height = size 32 | x, y = pos 33 | for p in points: 34 | yield x + p[0] * width / mw 35 | yield y + p[1] * height / mh 36 | 37 | 38 | def standard_deviation(l): 39 | mean = sum(l) / len(l) 40 | mean_sq = sum(x ** 2 for x in l) / len(l) 41 | return (mean_sq - mean ** 2) ** .5 42 | 43 | 44 | cpdef get_angle(points): 45 | """for a list of points [A, B, C], returns the angle in A. 46 | """ 47 | cdef float A, B, C, D 48 | 49 | A = points[1][0] - points[0][0] 50 | B = points[1][1] - points[0][1] 51 | C = points[2][0] - points[1][0] 52 | D = points[2][1] - points[1][1] 53 | 54 | return -(180 / pi) * atan2( 55 | C * B - D * A, 56 | C * A + D * B 57 | ) 58 | -------------------------------------------------------------------------------- /src/widgets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangibleDisplay/ObjectViz/8bf3ac8667ef59456edae457d459d1834fcec3b0/src/widgets/__init__.py -------------------------------------------------------------------------------- /src/widgets/normalized_view.kv: -------------------------------------------------------------------------------- 1 | : 2 | canvas: 3 | PushMatrix: 4 | Translate: 5 | xy: self.center 6 | Color: 7 | rgba: 1, 0, 0, 2. / app.training_length 8 | Point: 9 | points: self.r 10 | pointsize: 6 11 | source: 'data/glow_gray.png' 12 | Color: 13 | rgba: 0, 1, 0, 2. / app.training_length 14 | Point: 15 | points: self.g 16 | pointsize: 6 17 | source: 'data/glow_gray.png' 18 | Color: 19 | rgba: 0, 0, 1, 2. / app.training_length 20 | Point: 21 | points: self.b 22 | pointsize: 6 23 | source: 'data/glow_gray.png' 24 | PopMatrix: 25 | -------------------------------------------------------------------------------- /src/widgets/normalized_view.py: -------------------------------------------------------------------------------- 1 | from kivy.uix.widget import Widget 2 | from kivy.properties import ListProperty 3 | from utils import load_kv 4 | 5 | 6 | class NormalizedView(Widget): 7 | samples = ListProperty() 8 | r = ListProperty() 9 | g = ListProperty() 10 | b = ListProperty() 11 | 12 | def on_samples(self, instance, value): 13 | if not value: 14 | return 15 | 16 | r, g, b = [[] for i in range(3)] 17 | for points in value: 18 | for point in points: 19 | if point[0] > 25: 20 | b += point 21 | elif point[0] < -25: 22 | g += point 23 | else: 24 | r += point 25 | 26 | self.r, self.g, self.b = r, g, b 27 | 28 | load_kv() 29 | -------------------------------------------------------------------------------- /src/widgets/settings_patch.kv: -------------------------------------------------------------------------------- 1 | : 2 | canvas.before: 3 | Color: 4 | rgba: bgcolor 5 | Rectangle: 6 | pos: self.x, self.y + 1 7 | size: self.size 8 | 9 | : 10 | tr_title: '' 11 | tr_desc: '' 12 | title: tr._(self.tr_title).format(**app.settings_vars) 13 | desc: tr._(self.tr_desc).format(**app.settings_vars) 14 | 15 | selected_alpha: 0 16 | on_release: 17 | self.disabled = True 18 | Clock.schedule_once(lambda *x: self.setter('disabled')(self, False), .2) 19 | 20 | canvas.before: 21 | Color: 22 | rgba: bgcolor 23 | Rectangle: 24 | pos: self.x, self.y + 1 25 | size: self.size 26 | 27 | : 28 | RecycleView: 29 | viewclass: 'TrOptionsChoice' 30 | data: 31 | [ 32 | { 33 | 'text': option, 34 | 'state': 'down' if root.manager.value == option else 'normal', 35 | 'group': str(self.uid), 36 | 'manager': root.manager, 37 | 'popup': root, 38 | } 39 | for option in root.options 40 | ] 41 | 42 | RecycleBoxLayout: 43 | id: box 44 | orientation: 'vertical' 45 | size_hint_y: None 46 | height: self.minimum_height 47 | default_size_hint: 1, None 48 | default_size: 0, dp(50) 49 | 50 | : 51 | size_hint_y: None 52 | on_release: 53 | self.manager.value = self.text 54 | self.popup.dismiss() 55 | 56 | canvas.before: 57 | Color: 58 | rgba: bgcolor if self.state == 'normal' else light_bgcolor 59 | Rectangle: 60 | pos: self.x, self.y + 1 61 | size: self.size 62 | 63 | # monkey patch style of all settings 64 | : 65 | canvas.before: 66 | Color: 67 | rgba: bgcolor 68 | Rectangle: 69 | pos: self.pos 70 | size: self.size 71 | 72 | <-SettingSpacer>: 73 | -------------------------------------------------------------------------------- /src/widgets/settings_patch.py: -------------------------------------------------------------------------------- 1 | from kivy.properties import StringProperty, ListProperty, ObjectProperty 2 | from kivy.factory import Factory as F 3 | from kivy.uix.behaviors import ToggleButtonBehavior 4 | from kivy.uix.recycleview import RecycleView 5 | from kivy.uix.label import Label 6 | from kivy.uix.popup import Popup 7 | from kivy.core.window import Window 8 | from kivy.metrics import dp 9 | from kivy.resources import resource_find 10 | import kivy.uix.settings # noqa 11 | kivy.uix.settings.Popup = F.OVPopup 12 | kivy.uix.settings.TextInput = F.OVTextInput 13 | 14 | from utils import load_kv 15 | 16 | from glob import glob 17 | from os.path import splitext, basename 18 | 19 | 20 | class Tr(object): 21 | tr_title = StringProperty() 22 | tr_desc = StringProperty() 23 | 24 | 25 | class TrSettingString(Tr, F.SettingString): 26 | pass 27 | 28 | 29 | class TrSettingBoolean(Tr, F.SettingBoolean): 30 | pass 31 | 32 | 33 | class TrSettingNumeric(Tr, F.SettingNumeric): 34 | pass 35 | 36 | 37 | class TrSettingOptions(Tr, F.SettingOptions): 38 | def _create_popup(self, instance): 39 | # create th e popup 40 | popup = F.TrOptionsPopup( 41 | title=self.title, 42 | options=self.options, 43 | manager=self, 44 | ) 45 | 46 | popup.height = len(self.options) * dp(55) + dp(150) 47 | 48 | # add all the options 49 | popup.open() 50 | 51 | 52 | class TrLangs(TrSettingOptions): 53 | @property 54 | def options(self): 55 | dirname = resource_find('data/po') 56 | return [splitext(basename(x))[0] for x in glob('{}/*.mo'.format(dirname))] 57 | 58 | 59 | class TrOptionsPopup(F.OVPopup): 60 | options = ListProperty() 61 | manager = ObjectProperty() 62 | 63 | 64 | class TrOptionsChoice(ToggleButtonBehavior, Label): 65 | manager = ObjectProperty() 66 | popup = ObjectProperty() 67 | 68 | 69 | class TrSettingTitle(Tr, F.SettingTitle): 70 | pass 71 | 72 | 73 | class TrSettingPath(Tr, F.SettingPath): 74 | pass 75 | 76 | 77 | load_kv() 78 | -------------------------------------------------------------------------------- /src/widgets/sparsegraph.kv: -------------------------------------------------------------------------------- 1 | #:import log10 math.log10 2 | 3 | : 4 | values_scale_factors: list(get_scale_factor(root.successes + root.failures + root.errors)) 5 | default_scale_factors: 6 | ( 7 | max(self.values_scale_factors[0], app.surface_tolerance), 8 | max(self.values_scale_factors[1], app.angle_tolerance), 9 | ) 10 | scale_factors: self.default_scale_factors 11 | 12 | success_points: list(autoscale_points(root.successes, self.scale_factors, self.size, self.pos)) 13 | failure_points: list(autoscale_points(root.failures, self.scale_factors, self.size, self.pos)) 14 | error_points: list(autoscale_points(root.errors, self.scale_factors, self.size, self.pos)) 15 | 16 | vertical_cursor: app.angle_tolerance / self.scale_factors[1] * self.height 17 | horizontal_cursor: app.surface_tolerance / self.scale_factors[0] * self.width 18 | 19 | graduation_x: 10 ** (int(log10(app.surface_tolerance)) - 1) * self.width / self.scale_factors[0] 20 | graduation_y: 10 ** (int(log10(app.angle_tolerance)) - 1) * self.height / self.scale_factors[1] 21 | 22 | num_graduations: 100 23 | 24 | vertices_bottom: 25 | list(chain(*[[ 26 | self.x + x * 10 * root.graduation_x, 27 | self.y, 28 | 0, 0 29 | ] for x in range(self.num_graduations) 30 | ])) 31 | 32 | vertices_top: 33 | list(chain(*[[ 34 | self.x + x * 10 * root.graduation_x, 35 | self.top, 36 | 0, 0 37 | ] for x in range(self.num_graduations) 38 | ])) 39 | 40 | vertices_left: 41 | list(chain(*[[ 42 | self.x, 43 | self.y + y * 10 * root.graduation_y, 44 | 0, 0 45 | ] for y in range(self.num_graduations) 46 | ])) 47 | 48 | vertices_right: 49 | list(chain(*[[ 50 | self.right, 51 | self.y + y * 10 * root.graduation_y, 52 | 0, 0 53 | ] for y in range(self.num_graduations) 54 | ])) 55 | 56 | graduation_vertices: 57 | self.vertices_bottom + self.vertices_top + self.vertices_left + self.vertices_right 58 | 59 | graduation_indices: 60 | list(chain(*[[ 61 | (a + self.num_graduations * x) for x in range(4) 62 | ] for a in range(self.num_graduations) 63 | ])) if self.scale_factors else [] 64 | 65 | canvas: 66 | Color: 67 | rgba: 1, 1, 1, .3 68 | Mesh: 69 | mode: 'lines' 70 | vertices: root.graduation_vertices or [] 71 | indices: root.graduation_indices or [] 72 | 73 | Color: 74 | rgba: 1, 0, 0, .5 75 | Line: 76 | points: 77 | ( 78 | self.x, 79 | self.y + root.vertical_cursor, 80 | self.right, 81 | self.y + root.vertical_cursor, 82 | ) if self.scale_factors else [] 83 | Line: 84 | points: 85 | ( 86 | self.x + root.horizontal_cursor, 87 | self.y, 88 | self.x + root.horizontal_cursor, 89 | self.top, 90 | ) if self.scale_factors else [] 91 | 92 | Color: 93 | rgba: 1, 0, 0, 1 94 | Point: 95 | pointsize: 5 96 | points: self.error_points or [] 97 | source: 'data/glow_gray.png' 98 | 99 | Color: 100 | rgba: 1, 1, 1, 1 101 | Point: 102 | pointsize: 5 103 | points: self.failure_points or [] 104 | source: 'data/glow_gray.png' 105 | 106 | Color: 107 | rgba: 0, 1, 0, 1 108 | Point: 109 | pointsize: 5 110 | points: self.success_points or [] 111 | source: 'data/glow_gray.png' 112 | 113 | Slider: 114 | x: root.x 115 | top: self.height and root.top 116 | width: root.width 117 | height: '20dp' 118 | min: 0 119 | max: root.default_scale_factors[0] * 2 120 | value: root.default_scale_factors[0] 121 | on_value: root.scale_factors[0] = self.value 122 | 123 | Slider: 124 | orientation: 'vertical' 125 | right: self.size and root.right 126 | y: root.y 127 | height: root.height 128 | width: '20dp' 129 | min: 0 130 | max: root.default_scale_factors[1] * 2 131 | value: root.default_scale_factors[1] 132 | on_value: root.scale_factors[1] = self.value 133 | 134 | 135 | -------------------------------------------------------------------------------- /src/widgets/sparsegraph.py: -------------------------------------------------------------------------------- 1 | from kivy.uix.stencilview import StencilView 2 | from kivy.properties import ListProperty 3 | from utils import load_kv 4 | 5 | 6 | class ResultSparseGraph(StencilView): 7 | successes = ListProperty() 8 | failures = ListProperty() 9 | errors = ListProperty() 10 | success_points = ListProperty() 11 | failure_points = ListProperty() 12 | error_points = ListProperty() 13 | scale_factors = ListProperty() 14 | 15 | graduation_vertices = ListProperty() 16 | graduation_indices = ListProperty() 17 | 18 | 19 | load_kv() 20 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 2.0-dev 2 | --------------------------------------------------------------------------------