Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Allow inserting Tab characters in text boxes #1751

Merged
merged 3 commits into from Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/Origam.Gui.Win/AsTextBox.cs
Expand Up @@ -191,6 +191,9 @@ public bool IsPassword
[DefaultValue(false)]
public bool IsRichText { get; set; } = false;

[DefaultValue(false)]
public bool AllowTab { get; set; } = false;

[Browsable(false)]
public Guid StyleId { get; set; }

Expand Down
Expand Up @@ -1521,6 +1521,7 @@ private static void SetUserConfig(XmlDocument doc, XmlNode parentNode, string de
bool isPassword = false;
string gridColumnWidth = null;
bool isRichText = false;
bool allowTab = false;
bool hideOnForm = false;
Guid styleId = Guid.Empty;
UIStyle style = null;
Expand Down Expand Up @@ -1561,6 +1562,7 @@ private static void SetUserConfig(XmlDocument doc, XmlNode parentNode, string de
case "IsPassword": isPassword = property.BoolValue; break;
case "GridColumnWidth": gridColumnWidth = property.IntValue.ToString(); break;
case "IsRichText": isRichText = property.BoolValue; break;
case "AllowTab": allowTab = property.BoolValue; break;
case "HideOnForm": hideOnForm = property.BoolValue; break;
case "StyleId": styleId = property.GuidValue; break;
case "Format":
Expand Down Expand Up @@ -1729,6 +1731,7 @@ private static void SetUserConfig(XmlDocument doc, XmlNode parentNode, string de
buildDefinition.Multiline = multiline;
buildDefinition.IsPassword = isPassword;
buildDefinition.IsRichText = isRichText;
buildDefinition.AllowTab = allowTab;
buildDefinition.MaxLength = table.Columns[bindingMember].MaxLength;
buildDefinition.CustomNumberFormat = customNumericFormat;
TextBoxBuilder.Build(propertyElement, buildDefinition);
Expand Down
10 changes: 10 additions & 0 deletions backend/Origam.OrigamEngine/ModelXmlBuilders/TextBoxBuilder.cs
Expand Up @@ -55,6 +55,8 @@ public class TextBoxBuilder
XmlConvert.ToString(buildDefinition.IsPassword));
propertyElement.SetAttribute("IsRichText",
XmlConvert.ToString(buildDefinition.IsRichText));
propertyElement.SetAttribute("AllowTab",
XmlConvert.ToString(buildDefinition.AllowTab));
propertyElement.SetAttribute("MaxLength",
XmlConvert.ToString(buildDefinition.MaxLength));
}
Expand Down Expand Up @@ -102,6 +104,14 @@ public bool IsRichText
set { _IsRichText = value; }
}

private bool _AllowTab;

public bool AllowTab
{
get { return _AllowTab; }
set { _AllowTab = value; }
}

private int _MaxLength = 0;

public int MaxLength
Expand Down
Expand Up @@ -39,6 +39,7 @@ export class TextEditor extends React.Component<{
id?: string;
value: string | null;
isMultiline?: boolean;
isAllowTab?: boolean;
isReadOnly: boolean;
isPassword?: boolean;
backgroundColor?: string;
Expand Down Expand Up @@ -115,6 +116,23 @@ export class TextEditor extends React.Component<{
}
}

@action.bound
handleKeyDown(event: any) {
if(this.props.isAllowTab && event.key === 'Tab') {
event.preventDefault();
const {selectionStart, selectionEnd} = this.elmInput;
const value = this.props.value || '';
const newValue = value.substring(0, selectionStart) + '\t' + value.substring(selectionEnd);
this.elmInput.value = newValue;
const newCursorPosition = selectionStart + 1;
this.elmInput.selectionStart = newCursorPosition;
this.elmInput.selectionEnd = newCursorPosition;
this.props.onChange?.(null, newValue);
return
}
this.props.onKeyDown?.(event)
}

elmInput: any = null;
refInput = (elm: any) => {
this.elmInput = elm;
Expand Down Expand Up @@ -216,7 +234,7 @@ export class TextEditor extends React.Component<{
this.updateTextOverflowState();
}
}
onKeyDown={this.props.onKeyDown}
onKeyDown={this.handleKeyDown}
onClick={this.props.onClick}
onDoubleClick={this.props.onDoubleClick}
onBlur={this.props.onEditorBlur}
Expand Down Expand Up @@ -275,7 +293,7 @@ export class TextEditor extends React.Component<{
this.currentValue = event.target.value;
this.props.onChange && this.props.onChange(event, event.target.value);
}}
onKeyDown={this.props.onKeyDown}
onKeyDown={this.handleKeyDown}
onDoubleClick={this.props.onDoubleClick}
onClick={this.props.onClick}
onBlur={this.props.onEditorBlur}
Expand Down
Expand Up @@ -134,6 +134,7 @@ export class FormViewEditor extends React.Component<{
value={this.props.value}
isReadOnly={readOnly}
isMultiline={this.props.property!.multiline}
isAllowTab={this.props.property!.isAllowTab}
isPassword={this.props.property!.isPassword}
customStyle={this.props.property?.style}
maxLength={this.props.property?.maxLength}
Expand Down
Expand Up @@ -136,6 +136,7 @@ export class TableViewEditor extends React.Component<{
value={this.props.getCellValue!()}
isReadOnly={readOnly}
isPassword={this.props.property!.isPassword}
isAllowTab={false}
backgroundColor={backgroundColor}
foregroundColor={foregroundColor}
maxLength={this.props.property?.maxLength}
Expand Down
1 change: 1 addition & 0 deletions frontend-html/src/model/entities/Property.ts
Expand Up @@ -56,6 +56,7 @@ export class Property implements IProperty {
column: IPropertyColumn = IPropertyColumn.Text;
dock?: IDockType | undefined;
multiline: boolean = false;
isAllowTab: boolean = false;
isPassword: boolean = false;
isRichText: boolean = false;
maxLength: number = 0;
Expand Down
1 change: 1 addition & 0 deletions frontend-html/src/model/entities/types/IProperty.ts
Expand Up @@ -43,6 +43,7 @@ export interface IPropertyData {
column: IPropertyColumn;
dock?: IDockType;
multiline: boolean;
isAllowTab?: boolean;
alwaysHidden: boolean;
isPassword: boolean;
isRichText: boolean;
Expand Down
1 change: 1 addition & 0 deletions frontend-html/src/xmlInterpreters/screenXml.ts
Expand Up @@ -139,6 +139,7 @@ function parseProperty(node: any, idx: number): IProperty {
parameters: getPropertyParameters(node),
dock: node.attributes.Dock,
multiline: node.attributes.Multiline === "true",
isAllowTab: node.attributes.AllowTab === "true",
isPassword: node.attributes.IsPassword === "true",
isRichText: node.attributes.IsRichText === "true",
autoSort: node.attributes.AutoSort === "true",
Expand Down
161 changes: 84 additions & 77 deletions model-root/model/Root/Control/_Basic Controls/AsTextBox.origam
Expand Up @@ -3,7 +3,7 @@
xmlns:x="http://schemas.origam.com/model-persistence/1.0.0"
xmlns:asi="http://schemas.origam.com/Origam.Schema.AbstractSchemaItem/6.0.0"
xmlns:ci="http://schemas.origam.com/Origam.Schema.GuiModel.ControlItem/6.0.0"
xmlns:cpi="http://schemas.origam.com/Origam.Schema.GuiModel.ControlPropertyItem/6.0.0"
xmlns:cpi1="http://schemas.origam.com/Origam.Schema.GuiModel.ControlPropertyItem/6.0.0"
xmlns:csp="http://schemas.origam.com/Origam.Schema.GuiModel.ControlStyleProperty/6.0.0">
<ci:Control
asi:abstract="false"
Expand All @@ -14,139 +14,146 @@
ci:requestSaveAfterChangeAllowed="true"
ci:toolboxVisibility="PanelDesigner"
ci:typeName="Origam.Gui.Win.AsTextBox">
<cpi:ControlPropertyItem
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="02a5fdbd-f29d-408e-ac4a-0ef7e7be7a40"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="StyleId"
cpi:propertyType="UniqueIdentifier" />
<cpi:ControlPropertyItem
cpi1:propertyType="UniqueIdentifier" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="0a68bbf8-dc94-415f-baba-768e947f19e8"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="CaptionLength"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="16162dee-452f-4290-b8d5-753b89647f48"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="GridColumnWidth"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="1713bfc4-d991-4c6d-a26e-93bd8ef8046b"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="CustomNumericFormat"
cpi:propertyType="String" />
<cpi:ControlPropertyItem
cpi1:propertyType="String" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="1cfe8847-15cd-4bc6-80a5-481107a5b61f"
cpi1:localizable="false"
asi:name="AllowTab"
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi1:bindOnly="false"
x:id="2240ad59-99a5-4429-89e6-94a3d9fd62b8"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="ReadOnly"
cpi:propertyType="Boolean" />
<cpi:ControlPropertyItem
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="24326c8e-8fa1-40f5-9e52-ba02e755127c"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Dock"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="2b6c0455-a35e-4eef-9eaa-740f66732087"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="CaptionPosition"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="2feb3117-3bcd-4779-baa8-ef742e1eb108"
cpi:localizable="true"
cpi1:localizable="true"
asi:name="GridColumnCaption"
cpi:propertyType="String" />
<cpi:ControlPropertyItem
cpi1:propertyType="String" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="340fed3d-87c0-4c4b-a474-d28ebe2a7a14"
cpi:localizable="true"
cpi1:localizable="true"
asi:name="Caption"
cpi:propertyType="String" />
<cpi:ControlPropertyItem
cpi1:propertyType="String" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="47cd5ccd-1e49-40d0-bc82-ac6c98fee39f"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="TabIndex"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="5ec12c37-3a98-4d95-ac90-9a3045969728"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="HideOnForm"
cpi:propertyType="Boolean" />
<cpi:ControlPropertyItem
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="6a6e791e-0854-4779-9150-e70725b5d279"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="IsRichText"
cpi:propertyType="Boolean" />
<cpi:ControlPropertyItem
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="729b0402-6d81-47bc-936a-c26328136607"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Left"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="bf2e55d0-5859-4b26-9e82-f187a61f53f7"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Top"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="c2abd09e-17b2-4a60-9a62-c28078dc632a"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Multiline"
cpi:propertyType="Boolean" />
<cpi:ControlPropertyItem
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="c84ec964-046e-4a30-8941-a4eb234a2303"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Height"
cpi:propertyType="Integer" />
<cpi:ControlPropertyItem
cpi1:propertyType="Integer" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="d943815e-c6df-4236-99e8-566aaf4acc20"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="IsPassword"
cpi:propertyType="Boolean" />
<cpi:ControlPropertyItem
cpi1:propertyType="Boolean" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="e4c1751b-7b33-42d3-b945-11971cdf7c56"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Value"
cpi:propertyType="String" />
<cpi:ControlPropertyItem
cpi1:propertyType="String" />
<cpi1:ControlPropertyItem
asi:abstract="false"
cpi:bindOnly="false"
cpi1:bindOnly="false"
x:id="f40ac6ea-026c-4e8d-89e7-a13db97bd37c"
cpi:localizable="false"
cpi1:localizable="false"
asi:name="Width"
cpi:propertyType="Integer" />
cpi1:propertyType="Integer" />
<csp:ControlStyleProperty
asi:abstract="false"
x:id="394cb463-7104-4ec5-b165-3a31342f45d5"
Expand Down