# HG changeset patch # User veltr # Date 1345221372 -7200 # Node ID b43dd87f7ffa359b6826c657bfd9390303d386d6 # Parent bd58970ffd168350eef89ece61caedc8215ac101 Added Drag+Drop from a tweet list diff -r bd58970ffd16 -r b43dd87f7ffa client/css/renkan.css --- a/client/css/renkan.css Fri Aug 17 12:50:00 2012 +0200 +++ b/client/css/renkan.css Fri Aug 17 18:36:12 2012 +0200 @@ -46,11 +46,15 @@ } .Rk-Bins { - background: #F0F0F0; position: absolute; left: 0; top: 0; width: 200px; bottom: 0; + background: #F0F0F0; position: absolute; left: 0; top: 0; width: 300px; bottom: 0; overflow: hidden; } .Rk-Render { - position: absolute; left: 200px; top: 0; right: 0; bottom: 0; + position: absolute; left: 300px; top: 0; right: 0; bottom: 0; +} + +.Rk-Canvas { + position: absolute; left: 0; top: 0; right: 0; bottom: 0; } .Rk-Editor { @@ -105,13 +109,47 @@ background-position: -21px -20px; } -ul.Rk-TabButtons { +.Rk-Search-Input, .Rk-Search-Select { + border-radius: 5px; margin: 2px; padding: 2px; font-size: 13px; +} + +.Rk-Search-Input { + width: 180px; +} + +.Rk-Search-Select { + width: 100px; +} + +.Rk-Bin-Title { + border-top: 1px solid #cccccc; border-bottom: 1px solid #ffffff; background: #f0f0f0; + font-size: 14px; font-weight: bold; padding: 2px; cursor: pointer; +} + +.Rk-Bin-Main { + overflow: auto; } -li.Rk-TabButton { - float: left; padding: 2px; font-size: 13px; border-top-left-radius: 5px; border-top-right-radius: 5px; background: #CCCCCC; +.Rk-Twitter-Tweet { + padding: 2px; background: #f8f8f8; border-bottom: 1px solid #cccccc; min-height: 55px; +} + +.Rk-Twitter-TwImage { + float: left; width: 48px; height: 48px; margin: 2px 0; +} + +.Rk-Twitter-TwTitle, .Rk-Twitter-TwDate, .Rk-Twitter-TwText, .Rk-Twitter-TwActions { + margin: 2px 0 2px 50px; } -.Rk-TabDiv { - width: 100%; clear: both; overflow: auto; border-top: 1px solid #ccc; +.Rk-Twitter-TwTitle { + font-size: 13px; font-weight: bold; } + +.Rk-Twitter-TwDate { + font-size: 11px; font-style: italic; +} + +.Rk-Twitter-TwText { + font-size: 12px; +} \ No newline at end of file diff -r bd58970ffd16 -r b43dd87f7ffa client/js/main.js --- a/client/js/main.js Fri Aug 17 12:50:00 2012 +0200 +++ b/client/js/main.js Fri Aug 17 18:36:12 2012 +0200 @@ -79,63 +79,102 @@ Rkns.Bins = {} -Rkns.Bins._Base = function(_project) { - if (typeof _project !== "undefined") { - this._project = _project; +Rkns.Bins._Base = function(_renkan, _opts) { + if (typeof _renkan !== "undefined") { + this.renkan = _renkan; + this.renkan.$.find(".Rk-Bin-Main").hide(); + this.$ = Rkns.$('
  • ') + .addClass("Rk-Bin") + .appendTo(_renkan.$.find(".Rk-Bin-List")); + this.title_$ = Rkns.$('

    ') + .addClass("Rk-Bin-Title") + .appendTo(this.$); + this.main_$ = Rkns.$('
    ') + .addClass("Rk-Bin-Main") + .appendTo(this.$); + this.renkan.resizeBins(); } } - -Rkns.Bins._Base.prototype.baseTemplate = ''; - -Rkns.Bins._Base.prototype.addTab = function(_title) { - var _tabDiv = Rkns.$('
    '); - _tabDiv.addClass('Rk-TabDiv') - .css("display","none") - .appendTo('.Rk-TabDivs'); - var _tabButton = Rkns.$('
  • '); - _tabButton.addClass('Rk-TabButton') - .html(_title) - .click(function() { - Rkns.$('.Rk-TabButton').removeClass("active"); - Rkns.$(this).addClass("active"); - Rkns.$('.Rk-TabDiv').hide(); - _tabDiv.show(); - }) - .appendTo('.Rk-TabButtons'); - return { - button: _tabButton, - contents: _tabDiv - } -} - /* Point of entry */ Rkns.Renkan = function(_opts) { - if (typeof _opts.remotemodel == "undefined") { - _opts.remotemodel = "BasicJson"; + if (typeof _opts.remotemodel !== "string") { + _opts.remotemodel = "FullJson"; } - if (typeof _opts.language == "undefined" || typeof Rkns.i18n[_opts.language] == "undefined") { + if (typeof _opts.language !== "string" || typeof Rkns.i18n[_opts.language] == "undefined") { _opts.language = "en"; } - if (typeof _opts.container == "undefined") { + if (typeof _opts.container !== "string") { _opts.container = "renkan"; } + if (typeof _opts.search !== "object" || !_opts.search) { + _opts.search = []; + } this.project = new Rkns.ViewModel.Project(); this.project.l10n = Rkns.i18n[_opts.language]; if (typeof _opts.user === "object") { this.current_user = this.project.addUser(_opts.user) } - Rkns.$("#" + _opts.container).html(this.template()); - this.project.remotemodel = new Rkns.RemoteModels[_opts.remotemodel](this.project, _opts); - this.project.renderer = new Rkns.Renderer.Scene(this.project, _opts); + this.$ = Rkns.$("#" + _opts.container); + this.$.html(this.template()); + this.remotemodel = this.project.remotemodel = new Rkns.RemoteModels[_opts.remotemodel](this.project, _opts); + this.renderer = this.project.renderer = new Rkns.Renderer.Scene(this.project, _opts); + this.renderer.renkan = this; + this.tabs = []; + this.selected_bin_item = undefined; + this.mousedown = false; var _this = this; -/* if (typeof _opts.bins === "object") { - this.bins = Rkns._(_opts.bins).map(function(_type) { - return new Rkns.Bins[_type](_this); + this.$.mouseup(function() { + _this.selected_bin_item = undefined; + }); + if (!_opts.search.length) { + this.$.find(".Rk-Search-Form").detach(); + } else { + var _tmpl = Rkns._.template(''); + this.$.find(".Rk-Search-Select").html( + Rkns._(_opts.search).map(function(_name) { + return _tmpl({name:_name}); + }).join("") + ); + } + this.$.find(".Rk-Search-Form").submit(function() { + _this.tabs.push( + new Rkns.Bins[_this.$.find(".Rk-Search-Select").val()]( + _this, + { + search: _this.$.find(".Rk-Search-Input").val() + } + ) + ); + return false; + }); + this.$.find(".Rk-Bins") + .click(function(_e) { + if (_e.target.className == "Rk-Bin-Title") { + var _mainDiv = Rkns.$(_e.target).siblings(".Rk-Bin-Main"); + if (_mainDiv.is(":hidden")) { + _this.$.find(".Rk-Bin-Main").slideUp(); + _mainDiv.slideDown(); + } + } + }).mousedown(function(_e) { + var _t = Rkns.$(_e.target); + while (!_t.is(".Rk-Bins,.Rk-Bin-Item")) { + _t = _t.parent(); + } + if (_t.is(".Rk-Bin-Item")) { + _this.selected_bin_item = { + uri : $(_t).attr("data-uri"), + title : $(_t).attr("data-title"), + description : $(_t).attr("data-description") + } + return false; + } }); - Rkns.$('.Rk-TabButton:last').addClass("active"); - Rkns.$('.Rk-TabDiv:last').show(); -} */ + Rkns.$(window).resize(function() { + _this.resizeBins(); + }) + this.project.remotemodel.onLoad(function() { if (typeof _this.project.current_user === "undefined") { _this.project.current_user = _this.project.users[0]; @@ -145,9 +184,20 @@ } Rkns.Renkan.prototype.template = Rkns._.template( - '
    ' + '
    ' + + '
    ' + + '
      ' ); + +Rkns.Renkan.prototype.resizeBins = function() { + var _titles = this.$.find(".Rk-Bin-Title"), + _d = _titles.length * _titles.outerHeight() + this.$.find(".Rk-Search-Form").outerHeight(); + this.$.find(".Rk-Bin-Main").css({ + height: this.$.find(".Rk-Bins").height() - _d + }); +} + /* Utility functions */ Rkns.Utils = { diff -r bd58970ffd16 -r b43dd87f7ffa client/js/paper-renderer.js --- a/client/js/paper-renderer.js Fri Aug 17 12:50:00 2012 +0200 +++ b/client/js/paper-renderer.js Fri Aug 17 18:36:12 2012 +0200 @@ -380,7 +380,8 @@ Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) { this.end_pos = this.end_pos.add(_delta); - this._renderer.onMouseMove({point: this.end_pos}); + var _hitResult = paper.project.hitTest(this.end_pos); + this._renderer.findTarget(_hitResult); this.redraw(); } @@ -779,15 +780,18 @@ _tool.onMouseDrag = function(_event) { _this.onMouseDrag(_event); } - _tool.onMouseUp = function(_event) { + this.canvas_$.mouseup(function(_event) { _this.onMouseUp(_event); - } + }); this.canvas_$.mousewheel(function(_event, _delta) { _this.onScroll(_event, _delta); - }) + }); this.canvas_$.dblclick(function(_event) { _this.onDoubleClick(_event); }); + this.canvas_$.mouseenter(function(_event) { + _this.onMouseEnter(_event); + }); this.editor_$.find(".Rk-ZoomOut").click(function() { _this.offset = new paper.Point([ _this.canvas_$.width(), @@ -882,8 +886,7 @@ this.click_target = _tmpEdge; } -Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) { - var _hitResult = paper.project.hitTest(_event.point); +Rkns.Renderer.Scene.prototype.findTarget = function(_hitResult) { if (_hitResult && typeof _hitResult.item.__controller !== "undefined") { var _newTarget = _hitResult.item.__controller; if (this.selected_target !== _hitResult.item.__controller) { @@ -901,6 +904,20 @@ } } +Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) { + var _hitResult = paper.project.hitTest(_event.point); + if (this.is_dragging) { + if (this.click_target && typeof this.click_target.paperShift === "function") { + this.click_target.paperShift(_event.delta); + } else { + this.offset = this.offset.add(_event.delta); + this.redraw(); + } + } else { + this.findTarget(_hitResult); + } +} + Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) { this.is_dragging = false; var _hitResult = paper.project.hitTest(_event.point); @@ -919,17 +936,20 @@ Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) { this.is_dragging = true; - if (this.click_target && typeof this.click_target.paperShift === "function") { - this.click_target.paperShift(_event.delta); - } else { - this.offset = this.offset.add(_event.delta); - this.redraw(); - } + this.onMouseMove(_event); } Rkns.Renderer.Scene.prototype.onMouseUp = function(_event) { if (this.click_target) { - this.click_target.mouseup(_event); + var _off = this.canvas_$.offset(); + this.click_target.mouseup( + { + point: new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]) + } + ); } this.is_dragging = false; this.click_target = null; @@ -974,3 +994,26 @@ } paper.view.draw(); } + +Rkns.Renderer.Scene.prototype.onMouseEnter = function(_event) { + var _newEl = this.renkan.selected_bin_item; + if (_newEl) { + var _off = this.canvas_$.offset(), + _point = new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]), + _coords = this.toModelCoords(_point), + _node = this._project.addNode({ + uri: _newEl.uri, + title: _newEl.title, + description: _newEl.description, + position: { + x: _coords.x, + y: _coords.y + } + }, Rkns._RENDER_AND_SAVE); + this.is_dragging = true; + this.click_target = _node.__controller; + } +} \ No newline at end of file diff -r bd58970ffd16 -r b43dd87f7ffa client/js/random-data.js --- a/client/js/random-data.js Fri Aug 17 12:50:00 2012 +0200 +++ b/client/js/random-data.js Fri Aug 17 18:36:12 2012 +0200 @@ -2,8 +2,8 @@ Rkns.RemoteModels.RandomData.prototype._init = function() { this._USER_COUNT = 5; - this._NODE_COUNT = 20; - this._EDGE_COUNT = 40; + this._NODE_COUNT = 50; + this._EDGE_COUNT = 100; this.user_colors = ["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"]; this.load(); } @@ -24,10 +24,10 @@ title: "Node #"+(1+i), created_by: "user-" + Math.floor(this._USER_COUNT*Math.random()), position: { -// x: 200 * Math.random(), -// y: 150 * Math.random() - x: 100 * Math.cos(2 * Math.PI * i / this._NODE_COUNT), - y: 100 * Math.sin(2 * Math.PI * i / this._NODE_COUNT) + x: 200 * Math.random(), + y: 150 * Math.random() +// x: 100 * Math.cos(2 * Math.PI * i / this._NODE_COUNT), +// y: 100 * Math.sin(2 * Math.PI * i / this._NODE_COUNT) } })); } diff -r bd58970ffd16 -r b43dd87f7ffa client/js/twitter-bin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/js/twitter-bin.js Fri Aug 17 18:36:12 2012 +0200 @@ -0,0 +1,89 @@ +Rkns.Bins.Twitter = Rkns.Utils.inherit(Rkns.Bins._Base); + +Rkns.Bins.Twitter.prototype.tweetTemplate = Rkns._.template( + '
    • ' + + '' + + '

      @<%=tweet.from_user%> (<%=tweet.from_user_name%>)

      ' + + '

      <%=date%>

      ' + + '

      <%=text%>

      ' + + '

      show original · ' + + 'reply · ' + + 'retweet · ' + + 'favorite

    • ' +); + +Rkns.Bins.Twitter.prototype._init = function(_renkan, _opts) { + this.search = _opts.search; + this.title_$.html('Twitter: "' + this.search + '"') + var _this = this; + Rkns.$.getJSON( + "http://search.twitter.com/search.json?q=" + encodeURIComponent(this.search) + "&callback=?", + function(_data) { + var _html = Rkns._(_data.results).map(function(_result) { + var _entities = [], + _users = _result.text.match(/@[\w_]+/gm), + _lastpos = 0; + if (_users) { + for (var _i = 0; _i < _users.length; _i++) { + var _m = _users[_i], + _start = _lastpos + _result.text.substr(_lastpos).search(_m), + _lastpos = _start + _m.length; + _entities.push({ + "text" : _m, + "start" : _start, + "end" : _lastpos, + "link" :'', + }); + } + } + var _hashes = _result.text.match(/([^&]|^)#[^\s,.!?=#@&;()]+/gm), + _lastpos = 0; + if (_hashes) { + for (var _i = 0; _i < _hashes.length; _i++) { + var _m = _hashes[_i], + _h = ( _m[0] == '#' ? _m : _m.substr(1) ), + _start = _lastpos + _result.text.substr(_lastpos).search(_h), + _lastpos = _start + _h.length; + _entities.push({ + "text" : _h, + "start" : _start, + "end" : _lastpos, + "link" :'', + }); + } + } + + var _urls = _result.text.match(/(www\.|https?:\/\/)[\w./_\-]+/gim), + _lastpos = 0; + if (_urls) { + for (var _i = 0; _i < _urls.length; _i++) { + var _m = _urls[_i], + _start = _lastpos + _result.text.substr(_lastpos).search(_m), + _lastpos = _start + _m.length; + _entities.push({ + "text" : _m, + "start" : _start, + "end" : _lastpos, + "link" :'', + }); + } + } + _entities = Rkns._(_entities).sortBy(function(a) { return a.start }); + var _lastend = 0, + _text = Rkns._(_entities).map(function(_e) { + var _txt = _result.text.substring(_lastend, _e.start) + _e.link + _e.text + ''; + _lastend = _e.end; + return _txt; + }).join("") + _result.text.substring(_lastend); + + return _this.tweetTemplate({ + tweet: _result, + date: new Date(_result.created_at.replace(/(\+|-)/,'UTC$1')).toLocaleString(), + text: _text + }); + }).join(""); + _this.main_$.html(_html); + } + ); +} diff -r bd58970ffd16 -r b43dd87f7ffa client/render-test.html --- a/client/render-test.html Fri Aug 17 12:50:00 2012 +0200 +++ b/client/render-test.html Fri Aug 17 18:36:12 2012 +0200 @@ -14,6 +14,7 @@ +