index T00:00:00.000 2019-04-24T11:00:52.356 0 0 0 1 default 1 0 1 1 com.smartmobilestudio.app http://*/* https://*/* tel:* sms:* mailto:* geo:* 1 1 1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 None 0 0 index.js index.html www\ 0 1 0 0 0 0 Ubuntu https://fonts.googleapis.com/css?family=Ubuntu index 2017-02-11T20:52:54.654Z 2019-03-17T16:28:22.826 JElement 2017-02-12T22:20:12.098Z 2019-03-30T21:41:19.015 0 then SetLength(S, S.Length-2); Result := StrToInt(S); end; procedure TElement.SetTop(aTop: Integer); begin var FElementStyle := JElementCSSInlineStyle(FElement).style; FElementStyle.setProperty('top',inttostr(aTop)+'px'); end; function TElement.GetTop: Integer; begin var FElementStyle := JElementCSSInlineStyle(FElement).style; var S : string := FElementStyle.getPropertyValue('top'); if StrEndsWith(S,'px') then SetLength(S, S.Length-2); Result := StrToInt(S); end; procedure TElement.SetWidth(aWidth: Integer); begin var FElementStyle := JElementCSSInlineStyle(FElement).style; if aWidth = screenwidth then FElementStyle.setProperty('width','calc(100%)') else FElementStyle.setProperty('width',inttostr(aWidth)+'px'); end; function TElement.GetWidth: Integer; begin var FElementStyle := JElementCSSInlineStyle(FElement).style; var S : string := FElementStyle.getPropertyValue('width'); if StrEndsWith(S,'px') then SetLength(S, S.Length-2); Result := StrToInt(S); end; procedure TElement.SetHeight(aHeight: Integer); begin var FElementStyle := JElementCSSInlineStyle(FElement).style; FElementStyle.setProperty('height',inttostr(aHeight)+'px'); end; function TElement.GetHeight: Integer; begin var FElementStyle := JElementCSSInlineStyle(FElement).style; var S : string := FElementStyle.getPropertyValue('height'); if StrEndsWith(S,'px') then SetLength(S, S.Length-2); Result := StrToInt(S); end; procedure TElement.Clear; begin While assigned(FElement.firstChild) do FElement.removeChild(FElement.firstChild); end; destructor TElement.Destroy; begin If assigned(FElement.parentNode) then Felement.parentNode.removeChild(Felement); end; procedure TElement.touch2Mouse(e: variant); begin //mapping touch events to mouse events. See JSplitter for example //https://www.codicode.com/art/easy_way_to_add_touch_support_to_your_website.aspx var theTouch := e.changedTouches[0]; var mouseEv : variant; case e.type of "touchstart": mouseEv := "mousedown"; "touchend": mouseEv := "mouseup"; "touchmove": mouseEv := "mousemove"; else exit; end; var mouseEvent := document.createEvent("MouseEvent"); mouseEvent.initMouseEvent(mouseEv, true, true, window, 1, theTouch.screenX, theTouch.screenY, theTouch.clientX, theTouch.clientY, false, false, false, false, 0, null); theTouch.target.dispatchEvent(mouseEvent); e.preventDefault(); end; procedure TElement.PropertyObserve; begin //in w3c.dom var options : JMutationObserverInit; asm @options = Object.create(@options); end; options.attributes := true; options.attributeOldValue := true; var callback : JMutationCallback := procedure(mutations: array of JMutationRecord; observer: JMutationObserver) begin //console.log(handle.style.height); //console.log(self.Height); DisPatchEvent('PropertyChange',handle.id,'click',nil); end; var MyObserver : JMutationObserver; asm @MyObserver = Object.create(@MyObserver); end; MyObserver := JMutationObserver.Create(callback); MyObserver.observe(self.FElement, options); end; procedure TElement.Observe; begin var MyObserver := TMutationObserver.Create; var v: variant := new JObject; v.attributes := true; v.attributeOldValue := true; // v.childList := true; MyObserver.FHandle.observe(handle, v); end; /* //original readyexecute copied from rtl. Works but not needed //usage : // Handle.ReadyExecute( procedure () // begin // DoSomething; // end); // procedure TElement.ReadyExecute(const OnReady: Procedure); var LExists: Boolean; Begin LExists := document.body.contains(self.handle); if LExists then OnReady() else window.setTimeout(procedure () begin ReadyExecute(OnReady); end, 100); end; */ //############################################################################# // TMutationObserver //############################################################################# Constructor TMutationObserver.Create; var mRef: procedure (data:Variant); mhandle: variant; begin inherited Create; mRef:=@CBMutationChange; asm @mHandle = new MutationObserver(function (_a_d) {@mRef(_a_d);}); end; Fhandle:=mHandle; end; procedure TMutationObserver.CBMutationChange(mutationRecordsList:variant); var LEvent: Variant; begin FHandle.disconnect(); asm @LEvent = new Event('readyexecute'); end; mutationRecordsList[length(mutationRecordsList)-1].target.dispatchEvent(LEvent); end; initialization // ScreenWidth := Window.innerWidth; ScreenHeight := Window.innerHeight; end. ///////////////////////////// //options XMutationObserverInit = class external 'MutationObserverInit' public childList : Boolean; attributes : Boolean; characterData : Boolean; subtree : Boolean; attributeOldValue : Boolean; characterDataOldValue : Boolean; attributeFilter : array of String; end; //mutation XMutationRecord = class external 'MutationRecord' public &type : String; // Read Only target : JNode; // Read Only addedNodes : JNodeList; // Read Only removedNodes : JNodeList; // Read Only previousSibling : JNode; // Read Only nextSibling : JNode; // Read Only attributeName : String; // Read Only attributeNamespace : String; // Read Only oldValue : String; // Read Only end; XMutationCallback = procedure (mutations : array of XMutationRecord); XMutationObserver = class external 'MutationObserver' public constructor Create(callback : XMutationCallback); procedure observe(target : JNode; options : XMutationObserverInit); procedure disconnect; end; //////////////////////////////////////////////////// procedure TElement.PropertyObserve; begin var MyObserver := TPropertyObserver.Create; var v: variant := new JObject; v.attributes := true; v.attributeOldValue := true; // v.childList := true; MyObserver.FHandle.observe(handle, v); end; //############################################################################# // TPropertyObserver //############################################################################# Constructor TPropertyObserver.Create; begin inherited Create; var mRef := procedure(MutationsArray:variant) begin DisPatchEvent('PropertyChange',MutationsArray[length(MutationsArray)-1].target.id,'click',nil); end; asm @Fhandle = new MutationObserver(@mRef); end; end; ]]> JApplication 2017-08-30T19:39:37.789Z 2018-06-08T19:56:47.780 nil then FormsInstances[i].SetProperty('display','none'); If FormNames[i] = FormName then begin If FormsInstances[i] = nil //form has never been displayed yet then FormsInstances[i] := FormsClasses[i].Create(self) else FormsInstances[i].SetProperty('display','inline-block'); (FormsInstances[i] as FormsClasses[i]).InitializeForm; //ClearForm; (FormsInstances[i] as FormsClasses[i]).InitializeObject; //ShowForm; end; end; end; end. ]]> JForm 2017-08-30T19:45:08.310Z 2019-03-26T20:52:09.929 JImage 2017-08-30T20:56:30.879Z 2017-09-27T19:55:02.940 Globals 2017-08-30T21:17:51.387Z 2019-04-18T09:40:53.264 1 then begin var mAltered: boolean; repeat mAltered := false; for var x := 1 to myArray.length - 1 do begin var mLast := TElement(result[x - 1]); var mCurrent := TElement(result[x]); if attrib = 'left' then begin if mCurrent.left < mLast.left then begin result.Swap(x - 1,x); mAltered := true; end; end; if attrib = 'top' then begin if mCurrent.top < mLast.top then begin result.Swap(x - 1,x); mAltered := true; end; end; end; until mAltered = false; end; end; class function TW3Identifiers.GenerateUniqueObjectId: string; begin inc(__UNIQUE); result :='Component' + __UNIQUE.ToString(); end; function CreateObject(MyObject: variant): variant; begin result := JSON.parse(MyObject); end; function CreateArray(MyArray: Array of Variant): variant; begin asm @result = new Array(@MyArray); end; end; function MeasureTextWidth(const FontName: string; const FontSize: integer; const Text: string): integer; var mElement: variant; Begin if Text.length >0 then begin mElement := document.createElement("p"); if (mElement) then begin //mElement.style['font-family'] := FontName; mElement.style['font-size'] := '0.85em'; //IntToStr(FontSize) + 'px'; mElement.style['white-space'] := 'nowrap'; mElement.style['display'] := 'inline-block'; mElement.style['overflow'] := 'scroll'; mElement.style['margin'] := '0px'; mElement.style['padding'] := '0px'; mElement.style['border-style'] := 'none'; mElement.style['border-width'] := '0px'; mElement.style.width := '1px'; mElement.style.height := '1px'; mElement.innerHTML := Text.Replace(" ","_"); document.body.appendChild(mElement); result := mElement.scrollWidth; //result.tmHeight := mElement.scrollHeight; document.body.removeChild(mElement); end; end; end; function MeasureSize(content: string): integer; //var // mHandle: variant; begin /* mHandle := document.createElement("span"); mHandle.style.display := 'inline-block'; mHandle.style.visibility := 'hidden'; mHandle.style.fontFamily := 'Times New Roman, sans-serif'; //mHandle.style.fontSize := '0.85em'; mHandle.innerHTML := content; document.body.appendChild(mHandle); result := mHandle.clientWidth; //offsetWidth; document.body.removeChild(mHandle); */ result := measuretextwidth('',0,content); end; function getSBWidth: integer; begin var x : integer := 0; asm function getScrollBarWidth() { var inner = document.createElement('p'); inner.style.width = "100%"; inner.style.height = "200px"; var outer = document.createElement('div'); outer.style.position = "absolute"; outer.style.top = "0px"; outer.style.left = "0px"; outer.style.visibility = "hidden"; outer.style.width = "200px"; outer.style.height = "150px"; outer.style.overflow = "hidden"; outer.appendChild(inner); document.body.appendChild(outer); var w1 = inner.offsetWidth; outer.style.overflow = 'scroll'; var w2 = inner.offsetWidth; if (w1 == w2) { w2 = outer.clientWidth; } document.body.removeChild(outer); @x = (w1 - w2); return (w1 - w2); } getScrollBarWidth(); end; result := x; end; initialization // Application := JW3Application.Create(nil); //iOS specifics //temporary hack to eliminate rubberbanding window.onscroll := procedure begin window.scrollTo(0, 0); end; //without this ios won't scroll application.handle.addEventListener('touchmove', procedure(event:variant) begin event.stopPropagation(); end); //general initialisation //create stylesheet if there isn't one var s = document.styleSheets; if s.length = 0 then begin var style := document.createElement("STYLE"); document.head.appendChild(style); end; //set some initial css values (native scrolling) var s1 := #' body { overflow-y: auto; -webkit-overflow-scrolling: touch; scroll-behavior: smooth; overscroll-behavior-y: none; }'; document.styleSheets[0].insertRule(s1, 0); // document.body.style['overflow-y'] := 'auto'; // document.body.style['-webkit-overflow-scrolling'] := 'touch'; // document.body.style['scroll-behavior'] := 'smooth'; // document.body.style['overscroll-behavior-y'] := 'none'; //asm @FileReader = new Worker('https://www.lynkfs.com/native/www/filereader.js'); end; //asm @FileReader = new Worker('filereader.js'); end; end. ]]> JPanel 2017-09-02T18:48:46.916Z 2019-04-17T12:05:11.078 JButton 2017-09-02T19:58:54.567Z 2019-04-18T14:07:53.949 JToolBar 2017-09-02T21:01:39.031Z 2018-08-27T19:44:51.817 -1 //if form then Application.GoToForm((Sender as JW3Panel).tag) //then gotoform else window.postMessage([self.handle.id,'click',GoToForm],'*'); //else send message end; end; procedure JW3ToolBar.SetActiveMenu(FormName: String); begin // For var i := 0 to ToolBarItems.Count -1 do begin ToolBarItems[i].setProperty('font-weight', 'normal'); ToolBarItems[i].setProperty('text-decoration', 'none'); If ToolBarItems[i].Tag = FormName then begin ToolBarItems[i].setProperty('font-weight', 'bold'); ToolBarItems[i].setProperty('text-decoration', 'underline'); end; end; end; end. ]]> JListBox 2017-09-03T23:09:53.331Z 2019-04-19T11:57:14.174 = self.handle.scrollTop) and //if in viewport make visible (atop <= self.handle.scrollTop + self.height + 2) then begin c[i].style.display := 'inline-block'; end; if (atop > self.handle.scrollTop + self.height + 2) and //if past viewport then set invisible (c[i].style.display = 'inline-block') and (i < c.length-1) then c[i].style.display := 'none'; end; end; end; procedure JW3ListBox.Add(item: TElement); begin // item.SetProperty('padding','0px'); item.SetProperty('margin','0px'); item.setProperty('width','calc(100% - 2px)'); If Item.height = 0 then begin If RowHeight = 0 then Item.Height := 20 else Item.Height := RowHeight; end; item.SetBounds(0, ItemCount * (item.height+2), item.width, item.height+1); If editable then begin item.SetProperty('cursor','pointer'); item.SetAttribute('contenteditable','true'); end else begin item.SetAttribute('readonly','true'); //for JW3Input's end; //the following construct sets all entries which are not visible (outside the viewport) //to display-none, except the last entry which always will have display-inlineblock //this will render a correctly dimensioned proportional scroller //1-set the last entry to display-none if it is not visible If (item.Top > (self.Height + item.height)) and (self.height > 0) then self.handle.children[self.handle.children.length-1].style.display := 'none'; //2-append the new item self.FElement.appendchild(item.FElement); //3-always set the last entry to inline-block. self.handle.children[self.handle.children.length-1].style.display := 'inline-block'; //override border-width to 1px item.handle.style['border-width'] := '1px'; //onfocus = bringtofront //onblur = sendtoback Item.handle.onfocus := lambda() item.handle.style['z-index'] := 999; end; Item.handle.onblur := lambda() item.handle.style['z-index'] := 1; end; Inc(ItemCount); end; procedure JW3ListBox.Add(text: String); begin // var Item := JW3Input.Create(self); Item.handle.value := text; //if RowHeight not specified then default 20 If RowHeight <> 0 then Item.height := RowHeight else Item.Height := 20; item.setProperty('border','1px solid silver'); Add(Item); end; procedure JW3ListBox.Clear; begin While assigned(FElement.firstChild) do FElement.removeChild(FElement.firstChild); ItemCount := 0; end; procedure JW3ListBox.Sort; begin var element : array of variant; var children := self.handle.children; asm @element = [].slice.call(@children); end; element.sort(function(a, b: variant):integer begin result := 0; if (a.value > b.value) then result := 1; if (a.value < b.value) then result := -1; end); Clear; //Element.Reverse; //sort descending for var j := 0 to element.length-1 do begin var s : string := element[j].value; Add(s); end; Element.Clear; Children.Clear; end; end. ]]> Form1 2017-09-08T18:19:10.866Z 2019-04-24T11:00:52.355 nil then begin For var i := 0 to connections.length-1 do begin For var j := 0 to DesignPane.Tabs[1].Body.handle.children.length -1 do begin If DesignPane.Tabs[1].Body.handle.children[j].id <> nil then begin If connections[i].source.dataset.origid = DesignPane.Tabs[1].Body.handle.children[j].dataset.origid then begin For var k := 0 to DesignPane.Tabs[1].Body.handle.children.length -1 do begin if DesignPane.Tabs[1].Body.handle.children[k].id <> nil then begin If connections[i].target.dataset.origid = DesignPane.Tabs[1].Body.handle.children[k].dataset.origid then begin connection.source := DesignPane.Tabs[1].Body.handle.children[j].id; connection.target := DesignPane.Tabs[1].Body.handle.children[k].id; jsPlumb.connect(connection, common); end; end; end; end; end; end; end; end; ////////////////////// //onconnect event jsPlumb.bind('connection',procedure(info,ev: variant) begin var con := info.connection; //this is the new connection var found : boolean := false; If connections <> nil then begin for var i := 0 to connections.length-1 do begin If (connections[i].source.dataset.origid = con.source.dataset.origid) and (connections[i].target.dataset.origid = con.target.dataset.origid)then begin found := true; end; end; end; if found = false then connections := jsPlumb.getConnections(); end); //of onconnection end; //of tabs[1].onclick //open preview tab DesignPane.Tabs[2].handle.onclick := procedure(sender:TObject) begin //remove any resize handles DesignPane.Tabs[0].Body.handle.onclick(); // DesignPane.Tabs[2].Body.Clear; //copy elements from Design tab var d := DesignPane.Tabs[0].Body.handle.children; for var i := 0 to d.length-1 do begin var f := DesignPane.Tabs[2].Body.handle.appendChild(d[i].cloneNode(true)); if d[i].name = 'JLabel' then f.style.border := 'none'; if d[i].name = 'JMySQL' then f.style.display := 'none'; //invisible f.className := d[i].className; end; // //wing it // var f := DesignPane.Tabs[2].Body.handle.children; for var i := 0 to f.length-1 do begin //if f[i].name = 'JGrid' then f[i].style.display := 'none'; if f[i].name = 'JButton' then begin f[i].onclick := procedure(e: variant) begin e.target.style.display := 'none'; var DBGrid1 := JW3DBGrid.Create(DesignPane.Tabs[2].Body); DBGrid1.SetBounds(20, 20, 835, 400); DBGrid1.Server := 'https://www.lynkfs.com/native/www/lib/smsdbmysql.php'; DBGrid1.Query := #' Select Species_No as "ID", Category as "Category", Common_Name as "Common name", Species_Name as "Species name", Notes as "Note" from FishFacts'; DBGrid1.RowHeight := 40; //optional, default = 14 DBGrid1.ColumnWidths[5] := 300; //optional, overrides auto sizing for 5th column // //end of winging it // end; //of button click end; //of jbutton end; //of all elements end; //of tab[2].onclick // //Project Manager // ProjectPane := JW3TreeView.Create(self); ProjectPane.SetBounds(0, 120, DesignPane.left - 10, 120); ProjectPane.Subject := 'Project Manager'; ProjectPane.Add('design','','Forms'); //root ProjectPane.Add('Form1','design','Form1'); // //Property Inspector // PropertyPane := JW3TabControl.Create(self); PropertyPane.SetBounds(0, 270, DesignPane.left - 10, screenHeight-270-20); PropertyPane.handle.style.backgroundColor := 'whitesmoke'; PropertyPane.handle.style.border := '1px solid grey'; PropertyPane.TabHeight := 22; //default = 26 PropertyPane.TabWidth := 80; //default = 100 PropertyPane.AddTab('Properties'); PropertyPane.AddTab('Styles'); var TextID := JW3Panel.Create(PropertyPane.Tabs[0].Body); TextID.SetBounds(5, 5, 50, 25); TextId.Text := 'id'; var TextLeft := JW3Panel.Create(PropertyPane.Tabs[0].Body); TextLeft.SetBounds(5, 25, 50, 25); TextLeft.Text := 'left'; var TextTop := JW3Panel.Create(PropertyPane.Tabs[0].Body); TextTop.SetBounds(5, 45, 50, 25); TextTop.Text := 'top'; var TextWidth := JW3Panel.Create(PropertyPane.Tabs[0].Body); TextWidth.SetBounds(5, 65, 50, 25); TextWidth.Text := 'width'; var TextHeight := JW3Panel.Create(PropertyPane.Tabs[0].Body); TextHeight.SetBounds(5, 85, 50, 25); TextHeight.Text := 'height'; PropID := JW3Panel.Create(PropertyPane.Tabs[0].Body); PropID.SetBounds(80, 5, 200, 25); PropLeft := JW3Panel.Create(PropertyPane.Tabs[0].Body); PropLeft.SetBounds(80, 25, 200, 25); PropTop := JW3Panel.Create(PropertyPane.Tabs[0].Body); PropTop.SetBounds(80, 45, 200, 25); PropWidth := JW3Panel.Create(PropertyPane.Tabs[0].Body); PropWidth.SetBounds(80, 65, 200, 25); PropHeight := JW3Panel.Create(PropertyPane.Tabs[0].Body); PropHeight.SetBounds(80, 85, 200, 25); ListBoxStyles := JW3ListBox.Create(PropertyPane.Tabs[1].Body); ListBoxStyles.SetBounds(0, 0, DesignPane.left - 10 - 5, ScreenHeight - 320); ListBoxStyles.setProperty('background-color', 'white'); ListBoxStyles.SetProperty('border','2px double whitesmoke'); ListBoxStyles.SetProperty('font-size','13px'); ListBoxStyles.RowHeight := 25; ListBoxStyles.Editable := true; ListBoxStyles.handle.onchange := procedure(e:variant) begin var s1,s2 : string; s1 := StrBefore(document.getElementById(e.target.id).value, ' : '); s2 := StrAfter (document.getElementById(e.target.id).value, ' : '); If ReSizeArray.length = 1 then ReSizeArray[0].handle.style[s1] := s2 else window.alert('Select a specific visual component'); end; // //Init jsPlumb // DesignPane.Tabs[1].Body.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; DesignPane.Tabs[1].Body.handle.ontouchmove := DesignPane.Tabs[1].Body.handle.ontouchstart; DesignPane.Tabs[1].Body.handle.ontouchend := DesignPane.Tabs[1].Body.handle.ontouchstart; // //create a commonly used parameter object common := new JObject; common.isSource := true; common.isTarget := true; common.anchor := CreateArray(["Right","Left","Top","Bottom"]); common.connector := "Flowchart"; //common.connector := "Straight"; //"StateMachine"; //Flowchart" /* Endpoint-Style */ common.endpoint := "Dot"; //"Rectangle"; common.maxConnections := -1; common.paintStyle := class fill="white"; //"#699BCE"; outlineStroke="silver"; outlineWidth=1; radius=6; //strokeWidth=3; end; common.hoverPaintStyle := class outlineStroke="lightblue"; end; /* Connector(Line)-Style */ common.connectorStyle := class outlineStroke="green"; strokeWidth=1; end; common.connectorHoverStyle := class strokeWidth=2; end; var Script := document.createElement('script'); Script.src := 'lib/jsPlumb-2.2.3.js'; document.head.appendChild(Script); Script.onload := procedure begin console.log('loaded'); //Tab-1 of the DesignPane is the playground jsPlumb.setContainer(DesignPane.Tabs[1].Body.handle); end; end; procedure TForm1.ReSizeByHandles(Image0: TElement); begin //nwse = top left HandleLeftTop := JW3Panel.Create(DesignPane.Tabs[0].Body); HandleLeftTop.SetBounds(Image0.left-4,Image0.top-4,8,8); HandleLeftTop.SetProperty('border','1px solid grey'); HandleLeftTop.SetProperty('background-color','white'); HandleLeftTop.SetProperty('cursor','nwse-resize'); //nesw = top right HandleRightTop := JW3Panel.Create(DesignPane.Tabs[0].Body); HandleRightTop.SetBounds(Image0.left+Image0.Width-4,Image0.top-4,8,8); HandleRightTop.SetProperty('border','1px solid grey'); HandleRightTop.SetProperty('background-color','white'); HandleRightTop.SetProperty('cursor','nesw-resize'); //nwse = bottom right HandleRightBottom := JW3Panel.Create(DesignPane.Tabs[0].Body); HandleRightBottom.SetBounds(Image0.left+Image0.Width-4,Image0.top+Image0.Height-4,8,8); HandleRightBottom.SetProperty('border','1px solid grey'); HandleRightBottom.SetProperty('background-color','white'); HandleRightBottom.SetProperty('cursor','nwse-resize'); //nesw = bottom left HandleLeftBottom := JW3Panel.Create(DesignPane.Tabs[0].Body); HandleLeftBottom.SetBounds(Image0.left-4,Image0.top+Image0.Height-4,8,8); HandleLeftBottom.SetProperty('border','1px solid grey'); HandleLeftBottom.SetProperty('background-color','white'); HandleLeftBottom.SetProperty('cursor','nesw-resize'); //ns-resize and ew-resize // // event handling resize handlers // HandleLeftTop // mapping touchstart to mousedown, touchend to mouseup and touchmove to mousemove // see touch2Mouse in JElement. HandleLeftTop.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; HandleLeftTop.handle.ontouchmove := HandleLeftTop.handle.ontouchstart; HandleLeftTop.handle.ontouchend := HandleLeftTop.handle.ontouchstart; HandleLeftTop.handle.onmousedown := procedure(e: variant) begin var saveX := e.clientX; var saveY := e.clientY; DesignPane.Tabs[0].Body.handle.onmousemove := procedure(e: variant) begin HandleLeftTop.left := HandleLeftTop.Left - (saveX - e.clientX); HandleLeftTop.top := HandleLeftTop.top - (saveY - e.clientY); HandleLeftBottom.left := HandleLeftTop.Left; HandleRightTop.top := HandleLeftTop.Top; Image0.SetBounds(HandleLeftTop.left+4, HandleLeftTop.top+4, (HandleRightTop.left-HandleLeftTop.left), (HandleLeftBottom.top-HandleRightTop.top)); saveX := e.clientX; saveY := e.clientY; end; end; // // HandleRightTop // mapping touchstart to mousedown, touchend to mouseup and touchmove to mousemove // see touch2Mouse in JElement. HandleRightTop.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; HandleRightTop.handle.ontouchmove := HandleRightTop.handle.ontouchstart; HandleRightTop.handle.ontouchend := HandleRightTop.handle.ontouchstart; HandleRightTop.handle.onmousedown := procedure(e: variant) begin var saveX := e.clientX; var saveY := e.clientY; DesignPane.Tabs[0].Body.handle.onmousemove := procedure(e: variant) begin HandleRightTop.left := HandleRightTop.Left - (saveX - e.clientX); HandleRightTop.top := HandleRightTop.top - (saveY - e.clientY); HandleRightBottom.left := HandleRightTop.Left; HandleLeftTop.top := HandleRightTop.Top; Image0.SetBounds(HandleLeftTop.left+4, HandleRightTop.top+4, (HandleRightTop.left-HandleLeftTop.left), (HandleLeftBottom.top-HandleRightTop.top)); saveX := e.clientX; saveY := e.clientY; end; end; // // HandleLeftBottom // mapping touchstart to mousedown, touchend to mouseup and touchmove to mousemove // see touch2Mouse in JElement. HandleLeftBottom.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; HandleLeftBottom.handle.ontouchmove := HandleLeftBottom.handle.ontouchstart; HandleLeftBottom.handle.ontouchend := HandleLeftBottom.handle.ontouchstart; HandleLeftBottom.handle.onmousedown := procedure(e: variant) begin var saveX := e.clientX; var saveY := e.clientY; DesignPane.Tabs[0].Body.handle.onmousemove := procedure(e: variant) begin HandleLeftBottom.left := HandleLeftBottom.Left - (saveX - e.clientX); HandleLeftBottom.top := HandleLeftBottom.top - (saveY - e.clientY); HandleLeftTop.left := HandleLeftBottom.Left; HandleRightBottom.top := HandleLeftBottom.Top; Image0.SetBounds(HandleLeftTop.left+4, HandleLeftTop.top+4, (HandleRightTop.left-HandleLeftTop.left), (HandleLeftBottom.top-HandleRightTop.top)); saveX := e.clientX; saveY := e.clientY; end; end; // // HandleRightBottom // mapping touchstart to mousedown, touchend to mouseup and touchmove to mousemove // see touch2Mouse in JElement. HandleRightBottom.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; HandleRightBottom.handle.ontouchmove := HandleRightBottom.handle.ontouchstart; HandleRightBottom.handle.ontouchend := HandleRightBottom.handle.ontouchstart; HandleRightBottom.handle.onmousedown := procedure(e: variant) begin var saveX := e.clientX; var saveY := e.clientY; DesignPane.Tabs[0].Body.handle.onmousemove := procedure(e: variant) begin HandleRightBottom.left := HandleRightBottom.Left - (saveX - e.clientX); HandleRightBottom.top := HandleRightBottom.top - (saveY - e.clientY); HandleRightTop.left := HandleRightBottom.Left; HandleLeftBottom.top := HandleRightBottom.Top; Image0.SetBounds(HandleLeftTop.left+4, HandleRightTop.top+4, (HandleRightTop.left-HandleLeftTop.left), (HandleLeftBottom.top-HandleRightTop.top)); saveX := e.clientX; saveY := e.clientY; end; end; // // Image0 move // mapping touchstart to mousedown, touchend to mouseup and touchmove to mousemove // see touch2Mouse in JElement. Image0.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; Image0.handle.ontouchmove := Image0.handle.ontouchstart; Image0.handle.ontouchend := Image0.handle.ontouchstart; Image0.handle.onmousedown := procedure(e: variant) begin If assigned(HandleLeftTop) then HandleLeftTop.Destroy; If assigned(HandleRightTop) then HandleRightTop.Destroy; If assigned(HandleRightBottom) then HandleRightBottom.Destroy; If assigned(HandleLeftBottom) then HandleLeftBottom.Destroy; var saveX := e.clientX; var saveY := e.clientY; DesignPane.Tabs[0].Body.handle.onmousemove := procedure(e: variant) begin Image0.left := Image0.Left - (saveX - e.clientX); Image0.top := Image0.top - (saveY - e.clientY); HandleLeftTop.SetBounds(Image0.left-4,Image0.top-4,8,8); HandleRightTop.SetBounds(Image0.left+Image0.Width-4,Image0.top-4,8,8); HandleRightBottom.SetBounds(Image0.left+Image0.Width-4,Image0.top+Image0.Height-4,8,8); HandleLeftBottom.SetBounds(Image0.left-4,Image0.top+Image0.Height-4,8,8); saveX := e.clientX; saveY := e.clientY; end; end; // Image0.handle.onmouseup := procedure begin Image0.handle.onmousemove := null; //nullify mousemove end; // DesignPane.Tabs[0].Body.handle.onmouseup := procedure begin DesignPane.Tabs[0].Body.handle.onmousemove := null; //nullify mousemove end; // end; procedure TForm1.SetUpAlignDialog(Image0: TElement); begin Image0.handle.oncontextmenu := procedure(e:variant) //right-click begin //prevent the default right-click menu e.preventDefault(); // //if none selected, then ask for class properties If ReSizeArray.length = 0 then begin if LeftStr(e.target.className,6) = 'TW3Button' then e.target.className := 'TW3Button primary'; e.target.className := window.prompt('CSS classes',e.target.className); end; //if only 1 selected, then ask for delete y/n on right-click If ReSizeArray.length = 1 then begin var del := window.prompt('Delete ' + Image0.handle.name + ' ?', 'N'); if (del = 'y') or (del = 'Y') then begin //remove from DesignPane.Tabs[0].Body Image0.handle.remove(); //remove from ReSizeArray If ReSizeArray.IndexOf(Image0) > -1 then ReSizeArray.Delete(ReSizeArray.IndexOf(Image0)); end; end; // //if more then 1 selected then render the align options dialog If ReSizeArray.length > 1 then begin var Window1 := JW3Window.Create(self); Window1.SetProperty('z-index','99999'); //verticals var FieldSet1 := JW3FieldSet.Create(Window1); FieldSet1.SetBounds(10, 0, 200, 170); FieldSet1.Legend := 'Vertical'; var RadioButton1 := JW3RadioButton.Create(FieldSet1); RadioButton1.Label := 'Align top'; //RadioButton1.Checked := true; var RadioButton2 := JW3RadioButton.Create(FieldSet1); RadioButton2.Label := 'Align bottom'; var RadioButton3 := JW3RadioButton.Create(FieldSet1); RadioButton3.Label := 'Align centre'; var RadioButton4 := JW3RadioButton.Create(FieldSet1); RadioButton4.Label := 'Space evenly'; //horizontals var FieldSet2 := JW3FieldSet.Create(Window1); FieldSet2.SetBounds(240, 0, 200, 170); FieldSet2.Legend := 'Horizontal'; var RadioButton5 := JW3RadioButton.Create(FieldSet2); RadioButton5.Label := 'Align left sides'; var RadioButton6 := JW3RadioButton.Create(FieldSet2); RadioButton6.Label := 'Align right sides'; var RadioButton7 := JW3RadioButton.Create(FieldSet2); RadioButton7.Label := 'Align centre'; var RadioButton8 := JW3RadioButton.Create(FieldSet2); RadioButton8.Label := 'Space evenly'; // event listener for RadioButton click document.addEventListener('RadioButton', procedure(e: variant) begin var msg := JSON.parse(e.detail); //verticals //align top If msg.id = RadioButton1.handle.id then begin var saveTop := ReSizeArray[0].top; For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Top := saveTop; end; end; //align bottom If msg.id = RadioButton2.handle.id then begin var saveBottom := ReSizeArray[0].Top + ReSizeArray[0].Height; For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Top := saveBottom - ReSizeArray[i].Height; end; end; //align centre If msg.id = RadioButton3.handle.id then begin var saveCentre := ReSizeArray[0].Top + trunc(ReSizeArray[0].Height/2); For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Top := saveCentre - trunc(ReSizeArray[i].Height/2); end; end; //distribute evenly vertical If msg.id = RadioButton4.handle.id then begin If ReSizeArray.Length > 2 then //only for more than 2 elements begin ReSizeArray := Sort(ReSizeArray,'top'); //sort on top var inbetween : integer := 0; For var i := 1 to ReSizeArray.length -2 do begin inbetween := inbetween + ReSizeArray[i].height; end; var gap := (ReSizeArray[ReSizeArray.Length-1].top - ReSizeArray[0].top - ReSizeArray[0].height - inbetween) / (ReSizeArray.Length-1); For var i := 1 to ReSizeArray.length -2 do begin ReSizeArray[i].top := ReSizeArray[i-1].top + ReSizeArray[i-1].height + integer(gap); end; end; end; //horizontals //align left If msg.id = RadioButton5.handle.id then begin var saveLeft := ReSizeArray[0].left; For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Left := saveLeft; end; end; //align right If msg.id = RadioButton6.handle.id then begin var saveRight := ReSizeArray[0].left + ReSizeArray[0].Width; For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Left := saveRight - ReSizeArray[i].Width; end; end; //align centre If msg.id = RadioButton7.handle.id then begin var saveCentre := ReSizeArray[0].left + trunc(ReSizeArray[0].Width/2); For var i := 1 to ReSizeArray.length -1 do begin ReSizeArray[i].Left := saveCentre - trunc(ReSizeArray[i].Width/2); end; end; //distribute evenly horizontal If msg.id = RadioButton8.handle.id then begin If ReSizeArray.Length > 2 then //only for more than 2 elements begin ReSizeArray := Sort(ReSizeArray,'left'); //sort on left var inbetween : integer := 0; For var i := 1 to ReSizeArray.length -2 do begin inbetween := inbetween + ReSizeArray[i].width; end; var gap := (ReSizeArray[ReSizeArray.Length-1].left - ReSizeArray[0].left - ReSizeArray[0].width - inbetween) / (ReSizeArray.Length-1); For var i := 1 to ReSizeArray.length -2 do begin ReSizeArray[i].Left := ReSizeArray[i-1].Left + ReSizeArray[i-1].Width + integer(gap); end; end; end; end, false); var Button1 := JW3Button.Create(Window1); Button1.SetBounds(15,210,150,40); Button1.Caption := 'OK'; Button1.OnClick := procedure(sender:TObject) begin Window1.CloseWindow; end; Window1.OpenWindow; end; end; end; procedure TForm1.SelectMultipleHandles; begin For var i := 0 to ReSizeArray.length -1 do begin ReSizeArray[i].SetProperty('border','1px solid red'); end; If assigned(HandleLeftTop) then HandleLeftTop.Destroy; If assigned(HandleRightTop) then HandleRightTop.Destroy; If assigned(HandleRightBottom) then HandleRightBottom.Destroy; If assigned(HandleLeftBottom) then HandleLeftBottom.Destroy; end; procedure TForm1.Resize; begin inherited; end; end. ]]>
2017-09-08T18:19:10.866 2019-03-25T13:48:29.764 W3Form Form1
]]>
1 0 1
JSelect 2017-09-08T21:28:59.963Z 2018-08-12T17:15:23.517 JTextArea 2017-09-09T22:30:18.358Z 2018-05-30T21:57:23.967 JGrid 2017-09-13T17:31:16.709Z 2019-04-18T10:34:47.606 ItemHeight then ItemHeight := Cell.Height; //compute offset for the cell var CurLength : integer := 0; For var i := 1 to Column-1 do begin CurLength := CurLength + ColumnWidths[i-1] + 6; end; Cell.Left := CurLength; //set some cell properties and attach cell to the listbox row Cell.Top := 0; Cell.SetProperty('width',inttostr(ColumnWidths[column-1])+'px'); Cell.setProperty('border', '1px solid lightgrey'); Item.FElement.appendchild(Cell.FElement); //when inserting the last cell in a row, // - set the height of the row to largest cell height // - and add row to listbox If Column = ColumnCount then begin var c := Item.handle.children; for var i := 0 to c.length -1 do begin c[i].style.height := inttostr(Itemheight+6)+'px'; end; Item.SetProperty('height',inttostr(ItemHeight+10)+'px'); ListBox.Add(Item); end; end; procedure JW3Grid.HandleColumnReSize(columnTitle: JW3Panel); begin //set column titles & listbox to non-selectable //as it interferes somewhat visually while dragging document.styleSheets[0].insertRule('#' + columnTitle.FElement.id + ' { user-select:none}', 0); document.styleSheets[0].insertRule('#' + columnTitle.FElement.id + ' { -webkit-user-select:none}', 0); document.styleSheets[0].insertRule('#' + columnTitle.FElement.id + ' { -moz-user-select:none}', 0); document.styleSheets[0].insertRule('#' + columnTitle.FElement.id + ' { -ms-user-select:none}', 0); document.styleSheets[0].insertRule('#' + ListBox.FElement.id + ' { user-select:none}', 0); document.styleSheets[0].insertRule('#' + ListBox.FElement.id + ' { -webkit-user-select:none}', 0); document.styleSheets[0].insertRule('#' + ListBox.FElement.id + ' { -moz-user-select:none}', 0); document.styleSheets[0].insertRule('#' + ListBox.FElement.id + ' { -ms-user-select:none}', 0); //create resizers var ReSizer := JW3Panel.Create(columnTitle); ReSizer.SetProperty('background-color','gold'); ReSizer.SetBounds(0,1,4,22); ReSizer.Left := columnTitle.Width - 4; ReSizer.SetProperty('cursor','w-resize'); ReSizer.tag := IntToStr(ColumnCount); //map touchstart to mousedown, touchend to mouseup and touchmove to mousemove ReSizer.handle.ontouchstart := lambda(e: variant) touch2Mouse(e); end; ReSizer.handle.ontouchmove := ReSizer.handle.ontouchstart; ReSizer.handle.ontouchend := ReSizer.handle.ontouchstart; //adjust width of columnTitle while dragging ReSizer.handle.onmousedown := procedure(e: variant) begin var saveX := e.clientX; self.handle.onmousemove := procedure(e: variant) begin columnTitle.handle.style.zIndex := '999'; //BringToFront columnTitle.Width := columnTitle.Width - (saveX - e.clientX); saveX := e.clientX; ReSizer.Left := columnTitle.Width - 4; end; end; Columns.Add(columnTitle); //mouseUp = end of dragging columnTitle.handle.onmouseup := procedure begin ColumnWidths[ColumnCount] := columnTitle.Width; //get all rows var c := ListBox.handle.children; for var i := 0 to c.length -1 do begin //get all cells var d := c[i].children; for var j := 0 to d.length -1 do begin //set new cell widths for the resized column if j = StrToInt(ReSizer.Tag) then begin d[j].style.width := inttostr(ColumnWidths[ColumnCount]) + 'px'; var diff : integer := ColumnWidths[j] - columnTitle.Width; //shift all columns on the right hand side for var k := j+1 to d.length -1 do begin d[k].style.left := IntToStr(StrToInt(StrBefore(d[k].style.left, 'px')) - diff) + 'px'; Columns[k].Left := StrToInt(StrBefore(d[k].style.left, 'px'))+2; end; end; end; end; ColumnWidths[StrToInt(ReSizer.Tag)] := columnTitle.Width; columnTitle.handle.style.zIndex := '0'; self.handle.onmousemove := procedure begin end; //nullify mousemove end; end; end. ///////////////////////////////////////////////////////////////////////////// unit JGrid; interface uses JElement, JListBox, JPanel; type JW3Grid = class(TElement) private ListBox: JW3ListBox; Item: JW3Panel; ItemHeight: integer; ColumnCount : integer; ColumnWidths : array of integer; public constructor Create(parent: TElement); virtual; procedure AddColumn(title: string; colwidth: integer); procedure AddCell(row, column: integer; cell: TElement); end; implementation uses Globals; { JW3Grid } constructor JW3Grid.Create(parent: TElement); begin inherited Create('div', parent); ListBox := JW3ListBox.Create(self); Item := JW3Panel.Create(ListBox); ColumnCount := 0; //self.Observe; self.OnReadyExecute := procedure(sender: TObject) begin //set ListBox position relative to Grid dimensions ListBox.SetBounds(0,26,self.width-2,self.height-28); end; end; procedure JW3Grid.AddColumn(title: string; colwidth: integer); begin //add columnwidth to array ColumnWidths.Add(colwidth); //create column title var columnTitle := JW3Panel.Create(self); columnTitle.SetinnerHTML(title); columnTitle.SetBounds(0,0,colwidth,24); columnTitle.SetProperty('border','1px solid grey'); columnTitle.SetProperty('background-color','lightgrey'); //compute offset of column title var CurLength : integer := 2; For var i := 0 to ColumnCount-1 do begin CurLength := CurLength + ColumnWidths[i] + 6; end; columnTitle.Left := CurLength; //doubled up, ColumnCount is same as ColumnsWidths.Count Inc(ColumnCount); end; procedure JW3Grid.AddCell(row, column: integer; cell: TElement); begin // //when inserting the first cell in a row, create the listbox line-item If Column = 1 then begin Item := JW3Panel.Create(ListBox); Item.SetProperty('border-bottom','none'); Item.SetProperty('width',inttostr(self.width-2)+'px'); Item.SetProperty('height',inttostr(cell.height+6)+'px'); ItemHeight := Cell.Height; end; //keep track of largest height of any cell in a row If Cell.Height > ItemHeight then ItemHeight := Cell.Height; //compute offset for the cell var CurLength : integer := 2; For var i := 1 to Column-1 do begin CurLength := CurLength + ColumnWidths[i-1] + 6; end; Cell.Left := CurLength; //set some cell properties and attach cell to the listbox line-item Cell.Top := 2; Cell.SetProperty('width',inttostr(ColumnWidths[column-1]-4)+'px'); Cell.setProperty('border', '1px solid lightgrey'); Item.FElement.appendchild(Cell.FElement); //when inserting the last cell in a row, // - set the height of the listbox line-item to largest cell height // - and add listbox line-item to listbox If Column = ColumnCount then begin var c := Item.handle.children; //document.getElementById(Item.FElement.id).children; for var i := 0 to c.length -1 do begin c[i].style.height := inttostr(Itemheight+6)+'px'; end; Item.SetProperty('height',inttostr(ItemHeight+10)+'px'); ListBox.Add(Item); end; end; end. ]]> JTreeView 2017-10-18T19:42:00.093Z 2019-04-16T10:42:53.034 parent.node) then begin Parent.Children.push(Node); Node.Level := Parent.Level + 1; If node.level = 2 then node.Showing := true; //see line 82 end; end; end; Function JW3TreeView.FindNode(ThisNode:string):JW3TreeNode; begin var queue: Array of JW3TreeNode = [Root]; while (queue.length > 0) do begin var node := queue[0]; queue.delete(0); if node.Node = ThisNode then result := node; for var i := 0 to node.Children.length - 1 do begin queue.push(node.Children[i]); end; end; end; Procedure JW3TreeView.HideAllChildren(node: JW3TreeNode); begin Node.Showing := false; Node.Expanded := false; for var i := 0 to node.Children.length -1 do begin HideAllChildren(node.Children[i]); end; end; Procedure JW3TreeView.ShowTree; begin ListBox.Clear; Order(Root); end; Procedure JW3TreeView.Order(node: JW3TreeNode); begin if Node.Showing then begin var Item := JW3Panel.Create(Self); Item.SetAttribute('type','text'); Item.setProperty('background-color', 'whitesmoke'); //Item.SetProperty('font-size', '0.9em'); Item.Height := 24; var prefix : string := ''; If node.children.count > 0 then prefix := '▸ ' //triangle right else prefix := '  ▫ '; //white square If node.children.count > 0 then If node.Children[0].Showing then prefix := '▾ '; //triangle down var s: string := ''; For var i := 1 to node.Level do begin S := S + '  '; end; S := S + prefix; Item.SetinnerHTML(S + node.NodeDescription); Item.tag := node.NodeDescription; ListBox.Add(Item); Item.OnClick := procedure(Sender:TObject) begin Subject := (Sender as TElement).tag; //Title.Text := Subject; node.expanded := not node.expanded; For var j := 0 to Node.Children.Count -1 do Node.Children[j].Showing := Node.Expanded; If Node.Expanded = false then begin HideAllChildren(Node); Node.Showing := true; end; ShowTree; end; Item.handle.ondblclick := procedure begin window.postMessage([self.handle.id,'dblclick',subject],'*'); //= title.handle.value end; end; for var i := 0 to node.Children.length -1 do begin Order(node.Children[i]); end; end; end. ]]> JCheckBox 2017-10-20T22:31:29.221Z 2018-01-14T09:43:25.556 JSpinner 2017-10-27T12:48:06.340Z 2017-11-21T11:19:59.989
'); end; end. ]]>
JFieldSet 2017-10-30T13:58:56.483Z 2019-04-15T22:49:13.686 '' then begin Title := TElement.Create('legend',self); Title.handle.innerHTML := self.Legend; Title.handle.removeAttribute('style'); end; var d := self.handle.children; for var i := 0 to d.length -1 do begin If d[i].style.height = '0px' then begin d[i].style.left := '10px'; d[i].style.top := inttostr(30 + (i*34)) + 'px'; d[i].style.width := inttostr(self.width-14) + 'px'; d[i].style.height := '30px'; end; end; end; end; end. ]]> JRadioButton 2017-11-05T18:00:07.440Z 2019-04-15T22:43:58.464 JInput 2017-11-07T21:53:13.539Z 2018-08-12T11:52:52.972 JWindow 2017-11-18T21:29:12.102Z 2019-04-18T13:48:41.469 WindowArea.handle.id then begin //omit WindowArea // set child.top at least to CloseButton.height so as not to obscure close button var x := strtoInt(StrBefore(TempArray[j].style.top,'px')); If x <= 30 then TempArray[j].style.top := inttostr(x+30) + 'px'; // set height of WindowArea depending on lowest child-bottom var y := strtoInt(StrBefore(TempArray[j].style.top,'px')) + strtoInt(StrBefore(TempArray[j].style.height,'px')) + strtoInt(StrBefore(WindowArea.handle.style.marginBottom,'px')); If y > z then z := y; // move all elements (if any) from self to WindowArea WindowArea.handle.appendChild(TempArray[j]); end; If z > 0 then WindowArea.handle.style.height := inttostr(z+20) + 'px'; end; end. ]]> JTabControl 2018-06-01T16:31:21.557Z 2018-06-08T21:32:53.413 self.width then begin //tabs do not fit within components width Handle.style['overflow'] := 'auto'; //NativeScrolling := true Tabs[i].body.width := Tabs[i].width * NrVisible; end; end; end; end. ]]> JDBGrid 2018-07-22T18:40:16.896Z 2019-04-18T23:43:57.926 0 then begin var v : variant := new JObject; v := smscursor.rows[0]; //get first row asm @colProps = Object.keys(@v); end; //array of field names asm @colSize = Object.keys(@v); end; //will become array of column widths //compute column headers for var i := 0 to colProps.length -1 do begin //initial width = header text width colSize[i] := MeasureSize(colProps[i]); //MeasureSize in Globals unit end; for var j := 1 to DBRows do begin //check actual widths in all rows for var k := 1 to colProps.length do begin v := smscursor.rows[DBRows-1]; var content : string; asm @content = (@v)[Object.keys(@v)[@k-1]] ; end; if (MeasureSize(content)) > colSize[k-1] then colSize[k-1] := MeasureSize(content); //keep largest column width end; end; //set headers for var i := 0 to colProps.length -1 do begin If ColumnWidths[i+1] > 0 //width overrides ? then colSize[i] := ColumnWidths[i+1] else ColumnWidths[i+1] := Integer(colSize[i]); Grid.AddColumn(colProps[i],colSize[i]+30); //extra padding :( end; //fill rows and columns for var j := 1 to DBRows do begin for var k := 1 to colProps.length do begin LoadCells(j, k); end end; end else begin window.alert('no data'); end; end; procedure JW3DBGrid.LoadCells(row,column: integer); //called from LoadGrid begin var v : variant := new JObject; v := smscursor.rows[row-1]; var content : string; asm @content = (@v)[Object.keys(@v)[@column-1]] ; end; var Cell := JW3Panel.Create(Grid); Cell.Height := RowHeight; //default = 14 //Cell.SetProperty('font-size', '0.85em'); Cell.Text := content; Cell.OnClick := procedure(sender:TObject) begin window.alert(Cell.Text); end; Grid.AddCell(row,column,Cell); end; end. ]]> JScroller 2018-09-04T09:40:27.835Z 2018-09-06T14:41:44.888 ITabControl 2019-03-25T16:46:50.637Z 2019-04-23T15:28:06.730 self.width then begin //tabs do not fit within components width Handle.style['overflow'] := 'auto'; //NativeScrolling := true Tabs[i].body.width := Tabs[i].width * NrVisible; end; end; end; end. ]]> IScroller 2019-03-25T18:01:18.238Z 2019-03-26T01:09:59.612 default.html 2019-04-15T16:48:30.951Z 2019-04-23T11:42:15.269 default.html IPanel 2019-04-17T12:04:05.195Z 2019-04-18T00:06:25.131 JToggle 2019-04-23T13:52:54.404Z 2019-04-23T21:19:16.979
Browser Visual JForms Template