DetachablePanel.hx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package hide.comp;
  2. enum Side {
  3. None;
  4. Left;
  5. Right;
  6. Top;
  7. Bottom;
  8. }
  9. class DetachablePanel extends hide.comp.Component {
  10. // don't touch the width ? on resize check the new height to not go beyond min bottom
  11. var currentSide = Side.None;
  12. public var defaultState = {
  13. left : "20%",
  14. right : "620px",
  15. bottom : "20px",
  16. top : "unset",
  17. width : "unset",
  18. };
  19. public var minWidth = 300;
  20. public var minBottom = 20;
  21. public function new(?parent : Element, ?el : Element) {
  22. super(parent, el);
  23. element.addClass("detachable-panel");
  24. var layoutControls = new Element('<div class="layout-controls">
  25. <div class="splitter horizontal handle-right"><div class="drag-handle"></div></div>
  26. <div class="splitter horizontal handle-left"><div class="drag-handle"></div></div>
  27. <div class="splitter vertical handle-top"><div class="drag-handle"></div></div>
  28. </div>');
  29. // <div class="splitter vertical handle-bottom"><div class="drag-handle"></div></div>
  30. var document = new Element(js.Browser.document);
  31. var startState = { x : 0, y : 0, left : 0, right : 0, top : 0, bottom : 0, width : 0, height : 0 };
  32. function initDrag(e : js.jquery.Event) {
  33. startState = {
  34. x : e.clientX,
  35. y : e.clientY,
  36. left : Std.parseInt(element.css("left")),
  37. right : Std.parseInt(element.css("right")),
  38. top : Std.parseInt(element.css("top")),
  39. bottom : Std.parseInt(element.css("bottom")),
  40. width : Std.parseInt(element.css("width")),
  41. height : Std.parseInt(element.css("height")),
  42. }
  43. element.css("width", startState.width + "px");
  44. element.css("right", "unset");
  45. }
  46. layoutControls.find(".handle-right .drag-handle").first().mousedown((e : js.jquery.Event) -> {
  47. currentSide = Right;
  48. initDrag(e);
  49. });
  50. layoutControls.find(".handle-left .drag-handle").first().mousedown((e : js.jquery.Event) -> {
  51. currentSide = Left;
  52. initDrag(e);
  53. });
  54. layoutControls.find(".handle-top .drag-handle").first()
  55. .mousedown((e : js.jquery.Event) -> {
  56. currentSide = Top;
  57. initDrag(e);
  58. })
  59. .dblclick((e) -> {
  60. e.preventDefault();
  61. resetLayout();
  62. });
  63. document.mousemove((e : js.jquery.Event) -> {
  64. switch (currentSide) {
  65. case Left:
  66. e.stopPropagation();
  67. var newLeft = e.clientX;
  68. if( newLeft < 0 )
  69. return;
  70. var diff = newLeft - startState.left;
  71. var newWidth = startState.width - diff;
  72. if( newWidth < minWidth ) {
  73. newLeft = startState.left + startState.width - minWidth;
  74. newWidth = minWidth;
  75. }
  76. element.css("left", newLeft + "px");
  77. element.css("width", newWidth + "px");
  78. case Right:
  79. e.stopPropagation();
  80. var newWidth = startState.width + e.clientX - startState.x;
  81. if( startState.left + newWidth > js.Browser.window.innerWidth )
  82. newWidth = Std.int(js.Browser.window.innerWidth) - e.clientX;
  83. if( newWidth < minWidth )
  84. newWidth = minWidth;
  85. element.css("width", newWidth + "px");
  86. case Top:
  87. e.stopPropagation();
  88. var diffx = startState.x - e.clientX;
  89. var newLeft = startState.left - diffx;
  90. if( newLeft < 0 )
  91. newLeft = 0;
  92. if( newLeft + startState.width > js.Browser.window.innerWidth )
  93. newLeft = Std.int(js.Browser.window.innerWidth) - startState.width;
  94. element.css("left", newLeft + "px");
  95. case Bottom:
  96. case None:
  97. }
  98. });
  99. document.mouseleave((_) -> {
  100. currentSide = None;
  101. });
  102. document.mouseup((_) -> {
  103. currentSide = None;
  104. saveLayout();
  105. });
  106. layoutControls.appendTo(element);
  107. }
  108. function saveLayout() {
  109. var toSave = element.css(["left", "right"]);
  110. if( toSave != null )
  111. saveDisplayState("detachedOffsets", toSave);
  112. }
  113. public function resetLayout() {
  114. element.css(defaultState);
  115. saveDisplayState("detachedOffsets", {});
  116. }
  117. public function setDetached(val) {
  118. element.toggleClass("detached", val);
  119. var existingState = getDisplayState("detachedOffsets");
  120. if( existingState != null )
  121. element.css(existingState);
  122. }
  123. }