From f6466bd4d3bb6788c92d90a605df7418c2aeb7e6 Mon Sep 17 00:00:00 2001 From: Robert Zorko Date: Wed, 16 Sep 2015 17:49:25 +0200 Subject: basis for the state machine and some UI improvements (currently disabled) --- css/codeq.css | 58 +++++++++ index.html | 1 + js/codeq/prologPythonLib.js | 5 + js/codeq/startup.js | 2 + js/codeq/stateMachine.js | 307 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 373 insertions(+) create mode 100644 js/codeq/prologPythonLib.js create mode 100644 js/codeq/stateMachine.js diff --git a/css/codeq.css b/css/codeq.css index 7172ef8..cfb9286 100644 --- a/css/codeq.css +++ b/css/codeq.css @@ -38,6 +38,16 @@ body { border: 0; } +/**** animations *****/ +.transition{ + -moz-transition: all 1s ease; + -webkit-transition: all 1s ease; + -o-transition: all 1s ease; + -ms-transition: all 1s ease; + transition: all 1s ease; +} + + /***** responsiveness *****/ /* lg */ @media (min-width: 1200px) { @@ -49,6 +59,30 @@ body { overflow: auto; min-height: 100%; height: 100%; } + + .block-focus { + overflow: auto; + min-height: 100%; height: 100%; + min-width: 34%; width: 34%; + } + + .block-less-height{/*these names were made for the 'md' variant but need to be the same here for the javascript code to resize them when the focus changes*/ + overflow: auto; + min-height: 100%; height: 100%; + min-width: 22%; width: 22%; + } + + .block-less-width{/*these names were made for the 'md' variant but need to be the same here for the javascript code to resize them when the focus changes*/ + overflow: auto; + min-height: 100%; height: 100%; + min-width: 22%; width: 22%; + } + + .block-less-everything{/*these names were made for the 'md' variant but need to be the same here for the javascript code to resize them when the focus changes*/ + overflow: auto; + min-height: 100%; height: 100%; + min-width: 22%; width: 22%; + } } /* md */ @@ -61,6 +95,30 @@ body { overflow: auto; min-height: 50%; height: 50%; } + + .block-focus { + overflow: auto; + min-height: 60%; height: 60%; + min-width: 60%; width: 60%; + } + + .block-less-height{ + overflow: auto; + min-height: 40%; height: 40%; + min-width: 60%; width: 60%; + } + + .block-less-width{ + overflow: auto; + min-height: 60%; height: 60%; + min-width: 40%; width: 40%; + } + + .block-less-everything{ + overflow: auto; + min-height: 40%; height: 40%; + min-width: 40%; width: 40%; + } } /* sm */ diff --git a/index.html b/index.html index fb8342a..a7769fd 100644 --- a/index.html +++ b/index.html @@ -136,6 +136,7 @@ + diff --git a/js/codeq/prologPythonLib.js b/js/codeq/prologPythonLib.js new file mode 100644 index 0000000..5fed4dc --- /dev/null +++ b/js/codeq/prologPythonLib.js @@ -0,0 +1,5 @@ +/** + * Created by robert on 9/15/15. + */ + + diff --git a/js/codeq/startup.js b/js/codeq/startup.js index 980d3d7..9a0473c 100644 --- a/js/codeq/startup.js +++ b/js/codeq/startup.js @@ -94,4 +94,6 @@ $(document).ready(function () { alert('Request to obtain list of problems failed: ' + reason); } ).done(); + + //codeq.globalStateMachine.transition('login'); }); \ No newline at end of file diff --git a/js/codeq/stateMachine.js b/js/codeq/stateMachine.js new file mode 100644 index 0000000..720400d --- /dev/null +++ b/js/codeq/stateMachine.js @@ -0,0 +1,307 @@ +/** + * Created by robert on 9/15/15. + */ + +codeq.makeStateMachine = function(def){ + var currState = null; + return { + 'transition': function(name){ + if(currState !== null) currState.exit(); + currState = def[name]; + currState.enter(); + }, + 'destroy': function(){ + if(currState !== null) currState.exit(); + currState = null; + } + } +} + + + + +var loginFun = function(){ + var identifier = $('#problem_group').val().split('/'), + problem = $('#problems').val(); + if (identifier.length < 2) alert('Choose a problem group'); + else if (!problem) alert('Choose a problem'); + else { + $('#disabled').css('display', ''); + codeq.comms.login($('#username').val(), $('#password').val()) + .then(function (data) { + $('#disabled').css('display', 'none'); + if (data.code !== 0) throw new Error('Login failed, code: ' + data.code + ', message: ' + data.message); + }) + .then(function () { + return codeq.comms.getProblem(identifier[0], identifier[1], problem); + }) + .then(function (data) { + if (data.code !== 0) throw new Error('Failed to obtain problem data, code: ' + data.code + ', message: ' + data.message); + $('#disabled').css('display', 'none'); + switch (identifier[0]) { + case 'prolog': + // TODO: assignment to window for debug only + //$('#screen_login').css('display', 'none'); + //$('#screen_prolog').css('display', ''); + codeq.globalStateMachine.transition('prolog'); + window.phandler = codeq.createPrologHandler(data.data); + + var jq = $('#console textarea').on('focus',function(){ + codeq.log.debug('focus'); + }).on('blur',function(){ + codeq.log.debug('blur'); + }); + + var c = $('#console').on('focus',function(){ + codeq.log.debug('console focus'); + }).on('blur',function(){ + codeq.log.debug('console blur'); + }); + + codeq.log.debug("textareas: "+jq.length ); + codeq.log.debug("consols: "+c.length ); + + break; + case 'python': + // TODO: assignment to window for debug only + //$('#screen_login').css('display', 'none'); + //$('#screen_prolog').css('display', ''); + codeq.globalStateMachine.transition('prolog'); + window.phandler = codeq.createPythonHandler(data.data); + $('#console textarea').on('focus',function(){ + codeq.log.debug('focus'); + }); + $('#console textarea').on('blur',function(){ + codeq.log.debug('blur'); + }); + + break; + default: + alert('Unknown language: ' + identifier[0]); + break; + } + }) + .fail(function (reason) { + $('#disabled').css('display', 'none'); + alert('Login request failed: ' + reason); + }) + .done(); + } +} + +codeq.globalStateMachine = codeq.makeStateMachine({ + 'login':{ + 'enter': function(){ + codeq.comms.connect().then(function () { + return codeq.comms.send({'action': 'list_problems'});//currently problem list and the actual login are still in the same state + }).then( + function success(data) { + var i, groups, group, problems, problem, first_group, + jqGroup = $('#problem_group'), + jqProblems = $('#problems'), + html = [], + mapping = {}, + onGroupChange = function () { + var problems = mapping[jqGroup.val()], + html = [], + i, p; + if (problems) { + for (i = 0; i < problems.length; i++) { + p = problems[i]; + html.push('\n') + } + } + jqProblems.html(html.join('')); + }; + + if (data && (data.code === 0)) { + $('#disabled').css('display', 'none'); + groups = data.problems; + for (i = 0; i < groups.length; i++) { + group = groups[i]; + var identifier = group.identifier.language + '/' + group.identifier.group; + var name = group.name.language + ': ' + group.name.group; + html.push('\n'); + mapping[identifier] = group.problems; + } + jqGroup.html(html.join('')); + first_group = html[1]; + html = null; + + jqGroup.on('click', onGroupChange); + jqGroup.val(first_group); + onGroupChange(); + + $("#submit").on('click', loginFun); + } + else { + $('#disabled').css('cursor', ''); + alert('Obtaining list of problems failed: code=' + data.code + ', reason=' + data.message); + } + }, + + function failure(reason) { + $('#disabled').css('cursor', ''); + alert('Request to obtain list of problems failed: ' + reason); + } + ).done(); + }, + 'exit' : function(){ + $("#submit").off('click', loginFun); + $("#screen_login").css('display', 'none'); + } + }, + + 'prolog':{ + 'enter': function(){ + $('#screen_prolog').css('display', ''); + removeFocusFromElements(); + problems = codeq.makeStateMachine(substates); + //problems.transition('instructions'); + problems.transition('instructions'); + }, + 'exit': function(){ + $('#screen_prolog').css('display', 'none'); + problems.destroy(); + } + } +}); + +/* +the following variables are used in the sub-state machine representing the 4 different panels in the codeq app + */ +var problems,//this will the actual state machine + description = $('div.col-lg-3.col-md-6.col-sm-12:has(#description)'),//lets actually find the needed divs for later use + code = $('div.col-lg-3.col-md-6.col-sm-12:has(#code_editor)'), + consoleDiv = $('div.col-lg-3.col-md-6.col-sm-12:has(#console)'),//named 'consoleDiv', because 'console' is already in use + info = $('div.col-lg-3.col-md-6.col-sm-12:has(#info)'), + + //some functions used inside the enter and exit functions of the state machine + eventName = 'mousedown',//event name of the event which will trigger the transition between these substates + mouseDownEventFunctionDescription = function(){ + problems.transition('instructions'); + }, + mouseDownEventFunctionCode = function(){ + problems.transition('code'); + }, + mouseDownEventFunctionConsole = function(){ + problems.transition('console'); + }, + mouseDownEventFunctionInfo = function(){ + problems.transition('info'); + }, + removeListenersFromDivs = function(){ + description.off(eventName,mouseDownEventFunctionDescription); + code.off(eventName,mouseDownEventFunctionCode); + consoleDiv.off(eventName,mouseDownEventFunctionConsole); + info.off(eventName,mouseDownEventFunctionInfo); + }, + removeBlockClassesFromDivs = function(){ + description.removeClass('block'); + code.removeClass('block'); + consoleDiv.removeClass('block'); + info.removeClass('block'); + }, + removeChangedClassesFromDivs = function(){ + description.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');//these class names were chosen for the view where the screen is partitioned in 4 quarters (2 by 2) + code.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block'); + consoleDiv.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block'); + info.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block'); + }, + setTransitionsBetweenDivs = function(current){ + if(current !== description)description.on(eventName,mouseDownEventFunctionDescription); + if(current !== code)code.on( eventName,mouseDownEventFunctionCode); + if(current !== info)info.on( eventName,mouseDownEventFunctionInfo); + if(current !== consoleDiv)consoleDiv.on( eventName,mouseDownEventFunctionConsole); + + /*if(current !== description)description.on( eventName,function(){ + problems.transition('instructions'); + }); + if(current !== info)info.on( eventName,function(){ + problems.transition('info'); + }); + if(current !== code)code.on( eventName,function(){ + problems.transition('code'); + }); + if(current !== consoleDiv)consoleDiv.on( eventName,function(){ + problems.transition('console'); + });*/ + }, + removeFocusFromElements = function(){ + + }, + + //the states of the sub-state machine + substates = { + 'instructions':{ + 'enter': function(){ + removeBlockClassesFromDivs(); + + description.addClass('block-focus'); + code.addClass('block-less-width'); + consoleDiv.addClass('block-less-height'); + info.addClass('block-less-everything'); + + setTransitionsBetweenDivs(description); + }, + 'exit': function(){ + removeFocusFromElements(); + removeChangedClassesFromDivs(); + removeListenersFromDivs(); + } + }, + 'code':{ + 'enter': function(){ + removeBlockClassesFromDivs(); + + description.addClass('block-less-width'); + code.addClass('block-focus'); + consoleDiv.addClass('block-less-everything'); + info.addClass('block-less-height'); + + setTransitionsBetweenDivs(code); + }, + 'exit': function(){ + removeFocusFromElements(); + removeChangedClassesFromDivs(); + removeListenersFromDivs(); + } + }, + 'info':{ + 'enter': function(){ + removeBlockClassesFromDivs(); + + description.addClass('block-less-everything'); + code.addClass('block-less-height'); + consoleDiv.addClass('block-less-width'); + info.addClass('block-focus'); + + setTransitionsBetweenDivs(info); + }, + 'exit': function(){ + //$('div.col-lg-3.col-md-6.col-sm-12').addClass('block'); + removeFocusFromElements(); + removeChangedClassesFromDivs(); + removeListenersFromDivs(); + } + }, + 'console':{ + 'enter': function(){ + removeBlockClassesFromDivs(); + + description.addClass('block-less-height'); + code.addClass('block-less-everything'); + consoleDiv.addClass('block-focus'); + info.addClass('block-less-width'); + + setTransitionsBetweenDivs(consoleDiv); + }, + 'exit': function(){ + //$('span.cursor.blink').removeClass('blink'); + + removeFocusFromElements(); + removeChangedClassesFromDivs(); + removeListenersFromDivs(); + } + } + }; \ No newline at end of file -- cgit v1.2.1