Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
<!-- Framework-Agnostic Packages -->
<ItemGroup>
<!-- AX# Libraries -->
<PackageVersion Include="AXSharp.Abstractions" Version="0.47.0-alpha.394" />
<PackageVersion Include="AXSharp.Connector" Version="0.47.0-alpha.394" />
<PackageVersion Include="AXSharp.Connector.S71500.WebAPI" Version="0.47.0-alpha.394" />
<PackageVersion Include="AXSharp.Presentation.Blazor" Version="0.47.0-alpha.394" />
<PackageVersion Include="AXSharp.Presentation.Blazor.Controls" Version="0.47.0-alpha.394" />
<PackageVersion Include="Inxton.Operon" Version="0.3.0-alpha.104" />
<PackageVersion Include="AXSharp.Abstractions" Version="0.47.0-alpha.396" />
<PackageVersion Include="AXSharp.Connector" Version="0.47.0-alpha.396" />
<PackageVersion Include="AXSharp.Connector.S71500.WebAPI" Version="0.47.0-alpha.396" />
<PackageVersion Include="AXSharp.Presentation.Blazor" Version="0.47.0-alpha.396" />
<PackageVersion Include="AXSharp.Presentation.Blazor.Controls" Version="0.47.0-alpha.396" />
<PackageVersion Include="Inxton.Operon" Version="0.3.0-alpha.106" />
<!-- Data & Serialization -->
<PackageVersion Include="ClosedXML" Version="0.105.0" />
<PackageVersion Include="Microsoft.Build" Version="18.0.2" />
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public partial class VisualComposerContainer
[Inject]
private ProtectedLocalStorage _protectedLocalStorage { set; get; }

private bool _editSVG { get; set; } = false;
//private bool _editSVG { get; set; } = false;
private bool _inDesignMode { get; set; } = false;
private Guid _backgroundId { get; set; } = Guid.NewGuid();
public ZoomableContainer ZoomableContainer { get; set; }
Expand Down Expand Up @@ -144,7 +144,7 @@ internal async Task AddItemAsync(ITwinElement item)
{
if (_useOption)
{
_items.Add(new VisualComposerItemData(EventCallback.Factory.Create(this, StateHasChanged), EventCallback.Factory.Create(this, SaveAsync), item, _options.Left, _options.Top, _options.Transform, _options.Presentation, _options.Width, _options.Height, _options.ZIndex, _options.Scale, _options.Rotate, _options.Roles, _options.PresentationTemplate, _options.Background, _options.BackgroundColor, _options.PollingInterval));
_items.Add(new VisualComposerItemData(EventCallback.Factory.Create(this, StateHasChanged), EventCallback.Factory.Create(this, SaveAsync), item, _options.Left, _options.Top, _options.Transform, _options.Presentation, _options.Width, _options.Height, _options.ZIndex, _options.Scale, _options.Rotate, _options.Roles, _options.PresentationTemplate, _options.Background, _options.BackgroundColorLight, _options.BackgroundColorDark, _options.PollingInterval));

if (_optionsMove)
{
Expand Down Expand Up @@ -387,6 +387,14 @@ private async Task ChangeThemeAsync()
await SaveAsync();
}

private async Task SetDefaultBackgroundColorsAsync()
{
CurrentView.BackgroundColorLight = "var(--color-background-dark)";
CurrentView.BackgroundColorDark = "var(--color-background-dark)";

await SaveAsync();
}

private async Task ChangeSaveLocationAsync(ChangeEventArgs e, SaveLocationType oldType, string view)
{
var newSaveLocation = e.Value.ToString();
Expand Down Expand Up @@ -435,6 +443,84 @@ private async Task ChangeSaveLocationAsync(ChangeEventArgs e, SaveLocationType o
StateHasChanged();
}

private async Task ExportViewAsync(string viewName, SaveLocationType saveLocationType)
{
SerializableView? viewToExport = null;

if (saveLocationType == SaveLocationType.Server)
{
viewToExport = await Serializing<SerializableView>.DeserializeAsync(
Path.Combine(Settings.VisualComposerSerializeFolderPath, Id.CorrectFilePath(), viewName.CorrectFilePath() + ".json"));
}
else if (saveLocationType == SaveLocationType.Local && _localStorageData.ContainsKey(viewName))
{
viewToExport = _localStorageData[viewName];
}

if (viewToExport != null)
{
var json = System.Text.Json.JsonSerializer.Serialize(viewToExport, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
var jsObject = await js.InvokeAsync<IJSObjectReference>("import", "./_content/AXOpen.VisualComposer/Components/VisualComposerContainer.razor.js");
await jsObject.InvokeVoidAsync("downloadFile", $"{viewName}.json", "application/json", json);
}
}

private async Task ImportViewAsync(InputFileChangeEventArgs e)
{
try
{
var file = e.File;
if (file == null || !file.Name.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
return;

using var stream = file.OpenReadStream(maxAllowedSize: 10 * 1024 * 1024); // 10MB max
var importedView = await System.Text.Json.JsonSerializer.DeserializeAsync<SerializableView>(stream);

if (importedView == null)
return;

var viewName = Path.GetFileNameWithoutExtension(file.Name);
var originalName = viewName;
var counter = 1;

// Ensure unique name
while (_serverStorageAllViews.Contains(viewName) || _localStorageData.ContainsKey(viewName))
{
viewName = $"{originalName}_{counter}";
counter++;
}

// Import based on selected location
if (_importViewSaveLocation == SaveLocationType.Server)
{
_serverStorageAllViews.Add(viewName);

if (!Directory.Exists(Path.Combine(Settings.VisualComposerSerializeFolderPath, Id.CorrectFilePath())))
Directory.CreateDirectory(Path.Combine(Settings.VisualComposerSerializeFolderPath, Id.CorrectFilePath()));

await Serializing<SerializableView>.SerializeAsync(
Path.Combine(Settings.VisualComposerSerializeFolderPath, Id.CorrectFilePath(), viewName.CorrectFilePath() + ".json"),
importedView);
}
else
{
_localStorageData.Add(viewName, importedView);
await LocalStorage<Dictionary<string, SerializableView>>.SaveAsync(_protectedLocalStorage, Id, _localStorageData);
}

// Load the imported view
await LoadAsync(viewName);

StateHasChanged();
}
catch (Exception ex)
{
Console.WriteLine($"Error importing view: {ex.Message}");
}
}

private SaveLocationType _importViewSaveLocation { get; set; } = SaveLocationType.Server;

private async Task ClearScaleAndTranslateAsync()
{
CurrentView.Scale = 1;
Expand Down Expand Up @@ -579,9 +665,7 @@ private async Task UploadFile(InputFileChangeEventArgs e)

CurrentView.ImgSrc = Settings.VisualComposerImagesSerializeName + "/" + Id.CorrectFilePath() + "/" + newName.CorrectFilePath();

var dimensions = await GetImageDimensions(CurrentView.ImgSrc);
CurrentView.BackgroundWidth = dimensions.Width;
CurrentView.BackgroundHeight = dimensions.Height;
CurrentView.BackgroundImageScale = 1;

_isFileImported = true;
}
Expand All @@ -596,20 +680,6 @@ private async Task UploadFile(InputFileChangeEventArgs e)
await SaveAsync();
}

private async Task<Size> GetImageDimensions(string filePath)
{
try
{
var jsObject = await js.InvokeAsync<IJSObjectReference>("import", "./_content/AXOpen.VisualComposer/Components/VisualComposerContainer.razor.js");
return await jsObject.InvokeAsync<Size>("getImageDimensions", filePath);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return new Size { Width = 0, Height = 0 };
}
}

private async Task<Size> GetElementSize(string id)
{
try
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,4 @@
export function getImageDimensions(filePath) {
return new Promise((resolve, reject) => {
// Create a new image element
const img = new Image();

// Set the source of the image to the provided file path
img.src = filePath;

// When the image is loaded, resolve the promise with its dimensions
img.onload = function () {
resolve({
width: img.width,
height: img.height
});
};

// If there's an error loading the image, reject the promise
img.onerror = function () {
reject('Error loading image');
};
});
}

export function getWindowSize() {
export function getWindowSize() {
return {
width: window.innerWidth,
height: window.innerHeight
Expand Down Expand Up @@ -57,4 +34,16 @@ export function registerViewportChangeCallback(dotnetHelper, methodName, id) {
window.addEventListener('resize', () => {
dotnetHelper.invokeMethodAsync(methodName, getWindowSize(), getElementSize(id));
});
}

export function downloadFile(fileName, contentType, content) {
const blob = new Blob([content], { type: contentType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
<AuthorizeView Roles="Administrator">

<style>
.bg-switcher {
background-color: @Origin.BackgroundColorLight;
border-color: @Origin.BackgroundColorLight !important;
}

[data-theme="dark"] .bg-switcher {
background-color: @Origin.BackgroundColorDark;
border-color: @Origin.BackgroundColorLight !important;
}
</style>

<AuthorizeView Roles="Administrator">
<Authorized>
@if (InDesign)
{
<div @onpointerdown="Down"
@onpointerup="Up"
@onwheel="Wheel"
style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale)) rotate(@(Origin.Rotate)deg); translate: @(Origin.Transform.X)% @(Origin.Transform.Y)%; width: @(Origin.Width != -1 ? Origin.Width + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null)" style="@(Origin.Background ? "background-color: " + @Origin.BackgroundColor + "; border-color: " + @Origin.BackgroundColor + " !important;" : null)">
style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale.ToString().Replace(',', '.'))) rotate(@(Origin.Rotate.ToString().Replace(',', '.'))deg); translate: @(Origin.Transform.X.ToString().Replace(',', '.'))% @(Origin.Transform.Y.ToString().Replace(',', '.'))%; width: @(Origin.Width != -1 ? Origin.Width.ToString().Replace(',', '.') + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height.ToString().Replace(',', '.') + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null) @(Origin.Background ? "bg-switcher" : null)">
<RenderableContentControl @ref="renderableContentControlRcc"
Context="@Origin.TwinElement"
Presentation="@Origin.Presentation.ToString()"
Expand All @@ -21,8 +34,8 @@
}
else
{
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale)) rotate(@(Origin.Rotate)deg); translate: @(Origin.Transform.X)% @(Origin.Transform.Y)%; width: @(Origin.Width != -1 ? Origin.Width + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null)" style="@(Origin.Background ? "background-color: " + @Origin.BackgroundColor + "; border-color: " + @Origin.BackgroundColor + " !important;" : null)">
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale.ToString().Replace(',', '.'))) rotate(@(Origin.Rotate.ToString().Replace(',', '.'))deg); translate: @(Origin.Transform.X.ToString().Replace(',', '.'))% @(Origin.Transform.Y.ToString().Replace(',', '.'))%; width: @(Origin.Width != -1 ? Origin.Width.ToString().Replace(',', '.') + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height.ToString().Replace(',', '.') + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null) @(Origin.Background ? "bg-switcher" : null)">
<RenderableContentControl Context="@Origin.TwinElement"
Presentation="@Origin.Presentation.ToString()"
ParentContainer="@this"
Expand All @@ -36,8 +49,8 @@
@if (Origin.Roles != null && Origin.Roles != "")
{
<AuthorizeView Roles="@Origin.Roles" Context="SecondAuthorizeView">
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale)) rotate(@(Origin.Rotate)deg); translate: @(Origin.Transform.X)% @(Origin.Transform.Y)%; width: @(Origin.Width != -1 ? Origin.Width + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null)" style="@(Origin.Background ? "background-color: " + @Origin.BackgroundColor + "; border-color: " + @Origin.BackgroundColor + " !important;" : null)">
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale.ToString().Replace(',', '.'))) rotate(@(Origin.Rotate.ToString().Replace(',', '.'))deg); translate: @(Origin.Transform.X.ToString().Replace(',', '.'))% @(Origin.Transform.Y.ToString().Replace(',', '.'))%; width: @(Origin.Width != -1 ? Origin.Width.ToString().Replace(',', '.') + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height.ToString().Replace(',', '.') + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null) @(Origin.Background ? "bg-switcher" : null)">
<RenderableContentControl Context="@Origin.TwinElement"
Presentation="@Origin.Presentation.ToString()"
ParentContainer="@this"
Expand All @@ -49,8 +62,8 @@
}
else
{
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale)) rotate(@(Origin.Rotate)deg); translate: @(Origin.Transform.X)% @(Origin.Transform.Y)%; width: @(Origin.Width != -1 ? Origin.Width + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null)" style="@(Origin.Background ? "background-color: " + @Origin.BackgroundColor + "; border-color: " + @Origin.BackgroundColor + " !important;" : null)">
<div style="position: absolute; left: @(Origin.Left.ToString().Replace(',', '.'))%; top: @(Origin.Top.ToString().Replace(',', '.'))%; transform: scale(@(Origin.Scale.ToString().Replace(',', '.'))) rotate(@(Origin.Rotate.ToString().Replace(',', '.'))deg); translate: @(Origin.Transform.X.ToString().Replace(',', '.'))% @(Origin.Transform.Y.ToString().Replace(',', '.'))%; width: @(Origin.Width != -1 ? Origin.Width.ToString().Replace(',', '.') + "rem" : "max-content"); height: @(Origin.Height != -1 ? Origin.Height.ToString().Replace(',', '.') + "rem" : "max-content"); z-index: @Origin.ZIndex; @(Origin.Width == -1 ? "max-width:50rem;" : "") @(Origin.Height == -1 ? "max-height:30rem;" : "")">
<div class="@(Origin.Background ? "simple-border" : null) @(Origin.Background ? "bg-switcher" : null)">
<RenderableContentControl Context="@Origin.TwinElement"
Presentation="@Origin.Presentation.ToString()"
ParentContainer="@this"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private async Task MoveAsync(PointerEventArgs eventArgs)
if (_isDragging)
{
double offsetX = ((eventArgs.ClientX - _startX) / Parent!.ElementSize.Width * 100) * (1 / Parent.CurrentView.Scale);
double offsetY = ((eventArgs.ClientY - _startY) / ((Parent!.CurrentView.BackgroundHeight / Parent!.CurrentView.BackgroundWidth) * Parent!.ElementSize.Width) * 100) * (1 / Parent.CurrentView.Scale);
double offsetY = ((eventArgs.ClientY - _startY) / Parent!.ElementSize.Width * 100) * (1 / Parent.CurrentView.Scale);

Origin._left += offsetX;
Origin._top += offsetY;
Expand Down
Loading
Loading