From 7a54f94ac065f90ccbf23659566821fac62e37b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 5 Apr 2012 14:58:43 +0200 Subject: [PATCH] [IMP] First working draft of the OnScreen Keyboard bzr revid: fva@openerp.com-20120405125843-axg3m7h10g5sg6mx --- addons/point_of_sale/static/src/css/pos.css | 146 +++++++++++++++ addons/point_of_sale/static/src/js/pos.js | 195 ++++++++++++++++++++ addons/point_of_sale/static/src/xml/pos.xml | 104 +++++++++++ 3 files changed, 445 insertions(+) diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css index 09fbe3818f2..47ea23f202b 100644 --- a/addons/point_of_sale/static/src/css/pos.css +++ b/addons/point_of_sale/static/src/css/pos.css @@ -487,3 +487,149 @@ } } +/* Onscreen Keyboard http://net.tutsplus.com/tutorials/javascript-ajax/creating-a-keyboard-with-css-and-jquery/ */ + +.point-of-sale .keyboard_frame{ + display: none; + position:absolute; + left: 0; + bottom: 0px; + margin: 0; + padding: 0; + padding-top: 15px; + width: 100%; + height: 0px; /* 235px, animated via jquery */ + background-color: #BBB; + overflow:hidden; + -webkit-box-shadow: 0px 0px 10px rgba(0,0,0, 0.3); + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} +.point-of-sale .keyboard_frame .close_button{ + height:40px; + width:60px; + text-align:center; + background-color: #DDD; + font-size: 12px; + line-height:40px; + border: 1px solid #CCC; + -webkit-border-radius: 5px; + -webkit-box-shadow: 0px 2px 5px rgba(0,0,0, 0.2); + position:absolute; + top:0; + right:15px; + cursor: pointer; +} +.point-of-sale .keyboard li { + float: left; + text-align: center; + background-color: #fff; + border: 1px solid #f0f0f0; + top:0; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -webkit-box-shadow: 0px 2px 5px rgba(0,0,0, 0.2); + -webkit-transition-property: top, background-color; + -webkit-transition-duration: 0.2s; + -webkit-transition-timing-function: linear; +} +.point-of-sale .keyboard li:hover { + position: relative; + top: 2px; + left: 0px; + border-color: #ddd; + background-color:#e5e5e5; + cursor: pointer; + -webkit-transition-property: top, background-color; + -webkit-transition-duration: 0.1s; + -webkit-transition-timing-function: ease-out; +} +.point-of-sale .uppercase { + text-transform: uppercase; +} +.point-of-sale .on { + display: none; +} +.point-of-sale .firstitem{ + clear: left; +} +.point-of-sale .keyboard .lastitem { + margin-right: 0; +} + +/* ---- full sized keyboard ---- */ + +.point-of-sale .full_keyboard { + list-style: none; + font-size: 14px; + width: 680px; + height: 100%; + margin-left: auto; + margin-right: auto; +} +.point-of-sale .full_keyboard li{ + margin: 0 5px 5px 0; + width: 40px; + height: 40px; + line-height: 40px; +} +.point-of-sale .full_keyboard .tab, .point-of-sale .full_keyboard .delete { + width: 70px; +} +.point-of-sale .full_keyboard .capslock { + width: 80px; +} +.point-of-sale .full_keyboard .return { + width: 77px; +} +.point-of-sale .full_keyboard .left-shift { + width: 95px; +} +.point-of-sale .full_keyboard .right-shift { + width: 109px; +} +.point-of-sale .full_keyboard .space { + clear: left; + width: 673px; +} + +/* ---- simplified keyboard ---- */ + +.point-of-sale .simple_keyboard { + list-style: none; + font-size: 16px; + width: 545px; + height: 220px; + margin-left: auto; + margin-right: auto; +} +.point-of-sale .simple_keyboard li{ + margin: 0 5px 5px 0; + width: 49px; + height: 49px; + line-height: 49px; +} +.point-of-sale .simple_keyboard .firstitem.row_asdf{ + margin-left:25px; +} +.point-of-sale .simple_keyboard .firstitem.row_zxcv{ + margin-left:55px; +} +.point-of-sale .simple_keyboard .delete{ + width: 103px; +} +.point-of-sale .simple_keyboard .return{ + width: 103px; +} +.point-of-sale .simple_keyboard .space{ + width:268px; +} +.point-of-sale .simple_keyboard .numlock{ + width:103px; +} + diff --git a/addons/point_of_sale/static/src/js/pos.js b/addons/point_of_sale/static/src/js/pos.js index a03e34a3e53..7d37ae5dd8c 100644 --- a/addons/point_of_sale/static/src/js/pos.js +++ b/addons/point_of_sale/static/src/js/pos.js @@ -1082,6 +1082,198 @@ openerp.point_of_sale = function(db) { } }); + // A Widget that displays an onscreen keyboard. + // There are two options when creating the widget : + // + // * 'keyboard_model' : 'simple' | 'full' (default) + // The 'full' emulates a PC keyboard, while 'simple' emulates an 'android' one. + // + // * 'input_selector : (default: '.searchbox input') + // defines the dom element that the keyboard will write to. + // + // The widget is initally hidden. It can be shown with this.show(), and is + // automatically shown when the input_selector gets focused. + var OnscreenKeyboardWidget = db.web.Widget.extend({ + tagName: 'div', + + init: function(parent, options){ + var self = this; + + function get_option(opt,default_value){ + if(options){ + return options[opt] || default_value; + }else{ + return default_value; + } + } + + this.keyboard_model = get_option('keyboard_model','full'); + this.template_simple = qweb_template('pos-onscreen-keyboard-simple-template'); + this.template_full = qweb_template('pos-onscreen-keyboard-full-template'); + + this.template_fct = function(){ + if( this.keyboard_model == 'full' ){ + return this.template_full.apply(this,arguments); + }else{ + return this.template_simple.apply(this,arguments); + } + }; + + this.input_selector = get_option('input_selector','.searchbox input'); + + //show the keyboard when the input zone is clicked. + $(this.input_selector).focus(function(){self.show();}); + + //Keyboard state + this.capslock = false; + this.shift = false; + this.numlock = false; + }, + + // Write a character to the input zone + writeCharacter: function(character){ + var $input = $(this.input_selector); + $input[0].value += character; + $input.keydown(); + $input.keyup(); + }, + + // Sends a 'return' character to the input zone. TODO + sendReturn: function(){ + }, + + // Removes the last character from the input zone. + deleteCharacter: function(){ + var $input = $(this.input_selector); + var input_value = $input[0].value; + $input[0].value = input_value.substr(0, input_value.length - 1); + $input.keydown(); + $input.keyup(); + }, + + // Clears the content of the input zone. + deleteAllCharacters: function(){ + var $input = $(this.input_selector); + $input[0].value = ""; + $input.keydown(); + $input.keyup(); + }, + renderElement: function(){ + this.$element.html(this.template_fct()); + }, + + // Makes the keyboard show and slide from the bottom of the screen. + show: function(){ + $('.keyboard_frame').show().animate({'height':'235px'}, 500, 'swing'); + }, + + // Makes the keyboard hide by sliding to the bottom of the screen. + hide: function(){ + var self = this; + var frame = $('.keyboard_frame'); + frame.animate({'height':'0'}, 500, 'swing', function(){ frame.hide(); self.reset(); }); + }, + + //What happens when the shift key is pressed : toggle case, remove capslock + toggleShift: function(){ + $('.letter').toggleClass('uppercase'); + $('.symbol span').toggle(); + + self.shift = (self.shift === true) ? false : true; + self.capslock = false; + }, + + //what happens when capslock is pressed : toggle case, set capslock + toggleCapsLock: function(){ + $('.letter').toggleClass('uppercase'); + self.capslock = true; + }, + + //What happens when numlock is pressed : toggle symbols and numlock label + toggleNumLock: function(){ + $('.symbol span').toggle(); + $('.numlock span').toggle(); + self.numlock = (self.numlock === true ) ? false : true; + }, + + //After a key is pressed, shift is disabled. + removeShift: function(){ + if (self.shift === true) { + $('.symbol span').toggle(); + if (this.capslock === false) $('.letter').toggleClass('uppercase'); + + self.shift = false; + } + }, + + // Resets the keyboard to its original state; capslock: false, shift: false, numlock: false + reset: function(){ + if(this.shift){ + this.toggleShift(); + } + if(this.capslock){ + this.toggleCapsLock(); + } + if(this.numlock){ + this.toggleNumLock(); + } + }, + + //called after the keyboard is in the DOM, sets up the key bindings. + start: function(){ + var self = this; + + //this.show(); + + + $('.close_button').click(function(){ + self.deleteAllCharacters(); + self.hide(); + }); + + // Keyboard key click handling + $('.keyboard li').click(function(){ + + var $this = $(this), + character = $this.html(); // If it's a lowercase letter, nothing happens to this variable + + if ($this.hasClass('left-shift') || $this.hasClass('right-shift')) { + self.toggleShift(); + return false; + } + + if ($this.hasClass('capslock')) { + self.toggleCapsLock(); + return false; + } + + if ($this.hasClass('delete')) { + self.deleteCharacter(); + return false; + } + + if ($this.hasClass('numlock')){ + self.toggleNumLock(); + return false; + } + + // Special characters + if ($this.hasClass('symbol')) character = $('span:visible', $this).html(); + if ($this.hasClass('space')) character = ' '; + if ($this.hasClass('tab')) character = "\t"; + if ($this.hasClass('return')) character = "\n"; + + // Uppercase letter + if ($this.hasClass('uppercase')) character = character.toUpperCase(); + + // Remove shift once a key is clicked. + self.removeShift(); + + self.writeCharacter(character); + }); + }, + }); + var ShopWidget = db.web.OldWidget.extend({ init: function(parent, options) { this._super(parent); @@ -1179,6 +1371,9 @@ openerp.point_of_sale = function(db) { this.categoryView = new CategoryWidget(null, 'products-screen-categories'); this.categoryView.on_change_category.add_last(_.bind(this.category, this)); this.category(); + + this.onscreenKeyboard = new OnscreenKeyboardWidget(null,{keyboard_model:'simple'}); + this.onscreenKeyboard.appendTo($(".point-of-sale #content")); }; App.prototype.category = function(id) { diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 16192f208c8..b772b9ca2e5 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -294,4 +294,108 @@ + + +
+
    +
  • `~
  • +
  • 1!
  • +
  • 2@
  • +
  • 3#
  • +
  • 4$
  • +
  • 5%
  • +
  • 6^
  • +
  • 7&
  • +
  • 8*
  • +
  • 9(
  • +
  • 0)
  • +
  • -_
  • +
  • =+
  • +
  • delete
  • +
  • tab
  • +
  • q
  • +
  • w
  • +
  • e
  • +
  • r
  • +
  • t
  • +
  • y
  • +
  • u
  • +
  • i
  • +
  • o
  • +
  • p
  • +
  • [{
  • +
  • ]}
  • +
  • \|
  • +
  • caps lock
  • +
  • a
  • +
  • s
  • +
  • d
  • +
  • f
  • +
  • g
  • +
  • h
  • +
  • j
  • +
  • k
  • +
  • l
  • +
  • ;:
  • +
  • '"
  • +
  • return
  • +
  • shift
  • +
  • z
  • +
  • x
  • +
  • c
  • +
  • v
  • +
  • b
  • +
  • n
  • +
  • m
  • +
  • ,<
  • +
  • .>
  • +
  • /?
  • +
  • shift
  • +
  • &nbsp;
  • +
+

close

+
+
+ +
+
    +
  • q1
  • +
  • w2
  • +
  • e3
  • +
  • r4
  • +
  • t5
  • +
  • y6
  • +
  • u7
  • +
  • i8
  • +
  • o9
  • +
  • p0
  • + +
  • a@
  • +
  • s#
  • +
  • d%
  • +
  • f*
  • +
  • g/
  • +
  • h-
  • +
  • j+
  • +
  • k(
  • +
  • l)
  • + +
  • z?
  • +
  • x!
  • +
  • c"
  • +
  • v'
  • +
  • b:
  • +
  • n;
  • +
  • m,
  • +
  • delete
  • + +
  • 123ABC
  • +
  • &nbsp;
  • +
  • ..
  • +
  • return
  • +
+

close

+
+