improvements, fixes, and additions to Palette Editor and various Palette data formats

This commit is contained in:
Michael Becker 2021-04-29 23:06:27 -04:00
parent 2c0d651756
commit 358d78880c
No known key found for this signature in database
GPG Key ID: 98C333A81F18C22C
20 changed files with 1090 additions and 229 deletions

View File

@ -3,10 +3,11 @@
<Editor ID="{A0389580-FbE6-4512-95F0-BCDD51B8B623}" TypeName="UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette.PaletteEditor">
<Commands>
<Command ID="PaletteEditor_ContextMenu_Add" Title="A_dd entry..." />
<Command ID="PaletteEditor_ContextMenu_Add" Title="_Add entry..." />
<Command ID="PaletteEditor_ContextMenu_Change" Title="C_hange" />
<Command ID="PaletteEditor_ContextMenu_Delete" Title="_Delete" />
<Command ID="PaletteEditor_CalculateNeighboringColors" Title="Calculate _Neighboring Colors..." />
<Command ID="PaletteEditor_ContextMenu_Unselected">
<Items>
@ -15,8 +16,12 @@
</Command>
<Command ID="PaletteEditor_ContextMenu_Selected">
<Items>
<CommandReference CommandID="PaletteEditor_ContextMenu_Add" />
<Separator />
<CommandReference CommandID="PaletteEditor_ContextMenu_Change" />
<CommandReference CommandID="PaletteEditor_ContextMenu_Delete" />
<CommandReference CommandID="EditDelete" />
<Separator />
<CommandReference CommandID="PaletteEditor_CalculateNeighboringColors" />
</Items>
</Command>
</Commands>

View File

@ -0,0 +1,178 @@
//
// ColorPaletteControl.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Drawing;
using MBS.Framework.UserInterface.Input.Mouse;
using UniversalEditor.ObjectModels.Multimedia.Palette;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Controls.ColorPalette
{
public class ColorPaletteControl : CustomControl
{
public event EventHandler SelectionChanged;
protected virtual void OnSelectionChanged(EventArgs e)
{
SelectionChanged?.Invoke(this, e);
}
public PaletteEntry.PaletteEntryCollection Entries { get; set; } = new PaletteEntry.PaletteEntryCollection();
public Dimension2D PaletteEntrySize { get; set; } = new Dimension2D(64, 24);
public double ZoomFactor { get; set; } = 1.0;
private int GetLineWidth()
{
return (int)((double)Size.Width / (PaletteEntrySize.Width * ZoomFactor));
}
public PaletteEntry HitTest(Vector2D location)
{
int x = 0, y = 0, w = (int)(PaletteEntrySize.Width * ZoomFactor), h = (int)(PaletteEntrySize.Height * ZoomFactor);
y = (int)VerticalAdjustment.Value;
int startIndex = (int)(VerticalAdjustment.Value / h) * GetLineWidth(), endIndex = Entries.Count - 1;
int startLine = startIndex / w;
y = (int)VerticalAdjustment.Value;
int zcount = 0;
for (int i = startIndex; i <= endIndex; i++)
{
if (x > (int)(Size.Width - w))
{
x = 0;
y += h;
}
Rectangle rect = new Rectangle(x + paletteSpacingX, y + paletteSpacingY, w - paletteSpacingX - paletteSpacingX, h - paletteSpacingY - paletteSpacingY);
if (rect.Contains(location))
return Entries[i];
x += w;
}
return null;
}
public PaletteEntry HitTest(double x, double y)
{
return HitTest(new Vector2D(x, y));
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Focus();
PaletteEntry entry = HitTest(e.Location);
SelectedEntry = entry;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
int x = 0, y = 0, w = (int)(PaletteEntrySize.Width * ZoomFactor), h = (int)(PaletteEntrySize.Height * ZoomFactor);
double shscrh = Entries.Count / GetLineWidth();
ScrollBounds = new Dimension2D(0, (shscrh * h) + h);
int startIndex = (int)(VerticalAdjustment.Value / h) * GetLineWidth(), endIndex = Entries.Count - 1;
int startLine = startIndex / w;
y = (int)VerticalAdjustment.Value;
int zcount = 0;
for (int i = startIndex; i <= endIndex; i++)
{
if (x > (int)(Size.Width - w))
{
x = 0;
y += h;
}
if (y > (int)(VerticalAdjustment.Value + Size.Height + h + h))
{
// we're done for now
return;
}
Rectangle rect = new Rectangle(x + paletteSpacingX, y + paletteSpacingY, w - paletteSpacingX - paletteSpacingX, h - paletteSpacingY - paletteSpacingY);
PaletteEntry entry = Entries[i];
if (entry.Color.A < 1.0)
{
// only fill the alpha background if we need to
DrawAlphaBackground(e.Graphics, rect);
}
e.Graphics.FillRectangle(new SolidBrush(entry.Color), rect);
if (entry == SelectedEntry)
{
e.Graphics.DrawRectangle(new Pen(SystemColors.HighlightBackground, new Measurement(2, MeasurementUnit.Pixel)), new Rectangle(x, y, w, h));
}
zcount++;
x += w;
}
}
private TextureBrush AlphaBackgroundBrush = null;
private void DrawAlphaBackground(Graphics g, Rectangle rect)
{
// this is too slow for now, do absolutely nothing
return;
/*
if (AlphaBackgroundBrush == null)
{
Image AlphaBackgroundImage = Image.Create(24, 24);
Graphics g = Graphics.FromImage(AlphaBackgroundImage);
g.FillRectangle(Brushes.White, new Rectangle(0, 0, 24, 24));
g.FillRectangle(Brushes.Black, new Rectangle(16, 16, 16, 16));
AlphaBackgroundBrush = new TextureBrush(AlphaBackgroundImage);
}
*/
int qs = 0;
for (int patternY = 0; patternY < rect.Height; patternY += 8)
{
for (int patternX = qs; patternX < rect.Width - qs; patternX += 8)
{
g.FillRectangle(Brushes.Black, new Rectangle(rect.X + patternX, rect.Y + patternY, 4, 4));
}
if (qs == 0)
{
qs = 8;
}
else
{
qs = 0;
}
}
// e.Graphics.FillRectangle(AlphaBackgroundBrush, rect);
}
int paletteSpacingX = 2;
int paletteSpacingY = 2;
private PaletteEntry _SelectedEntry = null;
public PaletteEntry SelectedEntry { get { return _SelectedEntry; } set { bool changed = (_SelectedEntry != value); _SelectedEntry = value; if (changed) { Refresh(); OnSelectionChanged(EventArgs.Empty); } } }
}
}

View File

@ -0,0 +1,107 @@
//
// CalculateNeighboringColorsDialog.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using UniversalEditor.ObjectModels.Multimedia.Palette;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette.Dialogs
{
[ContainerLayout(typeof(CalculateNeighboringColorsDialog), "UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette.Dialogs.CalculateNeighboringColorsDialog.glade")]
public class CalculateNeighboringColorsDialog : CustomDialog
{
private Button cmdOK;
private Controls.ColorPalette.ColorPaletteControl cc;
private ComboBox cboMode;
public Color SelectedColor { get; set; } = Color.Empty;
public Color[] Colors { get; private set; } = new Color[0];
[EventHandler(nameof(cboMode), nameof(ComboBox.Changed))]
private void cboMode_Changed(object sender, EventArgs e)
{
cc.Entries.Clear();
Color[] colors = new Color[5];
for (int i = 0; i < colors.Length; i++)
{
colors[i] = (Color)SelectedColor.Clone();
}
int selectedIndex = (cboMode.Model as DefaultTreeModel).Rows.IndexOf(cboMode.SelectedItem);
switch (selectedIndex)
{
case 0: // analogous
{
double hue = colors[2].GetHueScaled(360.0);
// hsv in GIMP is 0.0-360.0, 0.0-100.0, and 0.0-100.0, so that's what we'll use
colors[0].Saturation -= 0.05;
colors[0].SetHueScaled(hue + 32, 360.0);
colors[1].Saturation -= 0.05;
colors[1].SetHueScaled(hue + 16, 360.0);
colors[3].Saturation -= 0.05;
colors[3].SetHueScaled(hue - 16, 360.0);
colors[4].Saturation -= 0.05;
colors[4].SetHueScaled(hue - 32, 360.0);
break;
}
case 8: // shades
{
colors[0].Saturation = 0.65;
colors[1].Saturation = 0.40;
colors[2].Saturation = 0.90;
colors[3].Saturation = 0.95;
colors[4].Saturation = 0.80;
break;
}
}
cc.Entries.Clear();
for (int i = 0; i < colors.Length; i++)
{
cc.Entries.Add(colors[i]);
}
cc.Refresh();
}
protected override void OnCreated(EventArgs e)
{
base.OnCreated(e);
DefaultButton = cmdOK;
}
[EventHandler(nameof(cmdOK), nameof(Control.Click))]
private void cmdOK_Click(object sender, EventArgs e)
{
List<Color> list = new List<Color>();
for (int i = 0; i < cc.Entries.Count; i++)
{
list.Add(cc.Entries[i].Color);
}
Colors = list.ToArray();
}
}
}

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkListStore" id="tmMode">
<columns>
<!-- column-name colMode -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Analogous</col>
</row>
<row>
<col id="0" translatable="yes">Monochromatic</col>
</row>
<row>
<col id="0" translatable="yes">Triadic</col>
</row>
<row>
<col id="0" translatable="yes">Complementary</col>
</row>
<row>
<col id="0" translatable="yes">Split complementary</col>
</row>
<row>
<col id="0" translatable="yes">Double split complementary</col>
</row>
<row>
<col id="0" translatable="yes">Square</col>
</row>
<row>
<col id="0" translatable="yes">Compound</col>
</row>
<row>
<col id="0" translatable="yes">Shades</col>
</row>
</data>
</object>
<object class="GtkDialog">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Calculate Neighboring Colors</property>
<property name="type_hint">dialog</property>
<child type="titlebar">
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cmdOK">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cmdCancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Mode</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cboMode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="model">tmMode</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="cc">
<property name="name">UniversalEditor.Plugins.Multimedia.UserInterface.Controls.ColorPalette.ColorPaletteControl</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">cmdOK</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -1,65 +0,0 @@
//
// PaletteEditor.Designer.cs - UWT designer initialization for PaletteEditor
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019-2020 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Layouts;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette
{
partial class PaletteEditor
{
private CustomControl cc = null;
private Container cInfo = null;
private TextBox txtColorName = null;
/// <summary>
/// UWT designer initialization for <see cref="PaletteEditor" />.
/// </summary>
/// <remarks>
/// UWT designer initialization in code is deprecated; continue improving the cross-platform Glade XML parser for <see cref="ContainerLayoutAttribute" />!
/// </remarks>
private void InitializeComponent()
{
this.Layout = new BoxLayout(Orientation.Vertical);
cc = new CustomControl();
cc.MouseDown += cc_MouseDown;
cc.MouseDoubleClick += cc_MouseDoubleClick;
cc.KeyDown += cc_KeyDown;
cc.Paint += cc_Paint;
this.Controls.Add(cc, new BoxLayout.Constraints(true, true));
cInfo = new Container();
cInfo.Layout = new BoxLayout(Orientation.Vertical);
this.Controls.Add(cInfo, new BoxLayout.Constraints(false, false));
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Add", PaletteEditor_ContextMenu_Add_Click);
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Change", PaletteEditor_ContextMenu_Change_Click);
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Delete", PaletteEditor_ContextMenu_Delete_Click);
txtColorName = new TextBox();
txtColorName.KeyDown += txtColorName_KeyDown;
cInfo.Controls.Add(txtColorName, new BoxLayout.Constraints(false, true));
}
}
}

View File

@ -20,23 +20,97 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Specialized;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Dialogs;
using MBS.Framework.UserInterface.Drawing;
using MBS.Framework.UserInterface.Input.Keyboard;
using UniversalEditor.ObjectModels.Multimedia.Palette;
using UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette.Dialogs;
using UniversalEditor.UserInterface;
using UniversalEditor.UserInterface.Panels;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette
{
/// <summary>
/// Provides a UWT-based <see cref="Editor" /> for a <see cref="PaletteObjectModel" />.
/// </summary>
public partial class PaletteEditor : Editor
[ContainerLayout(typeof(PaletteEditor), "UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Palette.PaletteEditor.glade")]
public class PaletteEditor : Editor
{
private Toolbar tb;
private Container pnlNoColors;
private Controls.ColorPalette.ColorPaletteControl cc;
private Container pnlColorInfo;
private TextBox txtColorName;
private Button cmdAddColor;
protected override void OnCreated(EventArgs e)
{
base.OnCreated(e);
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Add", PaletteEditor_ContextMenu_Add_Click);
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Change", PaletteEditor_ContextMenu_Change_Click);
Context.AttachCommandEventHandler("PaletteEditor_ContextMenu_Delete", PaletteEditor_ContextMenu_Delete_Click);
Context.AttachCommandEventHandler("PaletteEditor_CalculateNeighboringColors", PaletteEditor_CalculateNeighboringColors_Click);
cc.Visible = false;
pnlNoColors.Visible = true;
pnlColorInfo.Visible = false;
(tb.Items["tsbColorAdd"] as ToolbarItemButton).Click += tsbColorAdd_Click;
(tb.Items["tsbColorEdit"] as ToolbarItemButton).Click += tsbColorEdit_Click;
(tb.Items["tsbColorRemove"] as ToolbarItemButton).Click += tsbColorRemove_Click;
ContextMenuCommandID = "PaletteEditor_ContextMenu_Unselected";
OnObjectModelChanged(e);
}
private void PaletteEditor_CalculateNeighboringColors_Click(object sender, EventArgs e)
{
if (SelectedEntry == null)
{
MessageDialog.ShowDialog("Please select a palette entry.", "Error", MessageDialogButtons.OK, MessageDialogIcon.Error);
return;
}
PaletteObjectModel palette = (ObjectModel as PaletteObjectModel);
if (palette == null) return;
CalculateNeighboringColorsDialog dlg = new CalculateNeighboringColorsDialog();
dlg.SelectedColor = SelectedEntry.Color;
if (dlg.ShowDialog() == DialogResult.OK)
{
int index = palette.Entries.IndexOf(SelectedEntry);
for (int i = 0; i < dlg.Colors.Length; i++)
{
PaletteEntry entry = new PaletteEntry();
entry.Color = dlg.Colors[i];
palette.Entries.Insert(index, entry);
cc.Entries.Insert(index, entry);
}
}
}
private void tsbColorAdd_Click(object sender, EventArgs e)
{
PaletteEditor_ContextMenu_Add_Click(sender, e);
}
private void tsbColorEdit_Click(object sender, EventArgs e)
{
PaletteEditor_ContextMenu_Change_Click(sender, e);
}
private void tsbColorRemove_Click(object sender, EventArgs e)
{
PaletteEditor_ContextMenu_Delete_Click(sender, e);
}
protected override Selection CreateSelectionInternal(object content)
{
throw new NotImplementedException();
@ -65,10 +139,7 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
return _er;
}
public PaletteEditor()
{
InitializeComponent();
}
private PropertyPanelClass ppclasColor = new PropertyPanelClass("Color", new PropertyPanelProperty[] { new PropertyPanelProperty("Color", typeof(Color)) });
private void PaletteEditor_ContextMenu_Add_Click(object sender, EventArgs e)
{
@ -79,8 +150,24 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
if (dlg.ShowDialog() == DialogResult.OK)
{
BeginEdit();
palette.Entries.Add(new PaletteEntry(dlg.SelectedColor));
PaletteEntry entry = new PaletteEntry(dlg.SelectedColor);
palette.Entries.Add(entry);
cc.Entries.Add(entry);
PropertyPanelObject ppobj = new PropertyPanelObject(entry.Name, ppclasColor);
ppobj.SetExtraData<PaletteEntry>("content", entry);
ppobj.Properties.Add(new PropertyPanelProperty("Color", typeof(Color), entry.Color));
PropertiesPanel.Objects.Add(ppobj);
EndEdit();
pnlNoColors.Visible = false;
pnlColorInfo.Visible = true;
cc.Visible = true;
cc.Refresh();
}
}
private void PaletteEditor_ContextMenu_Change_Click(object sender, EventArgs e)
@ -108,71 +195,43 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
if (MessageDialog.ShowDialog("Do you wish to delete the selected color?", "Delete Selected Color", MessageDialogButtons.YesNo, MessageDialogIcon.Warning) == DialogResult.Yes)
{
BeginEdit();
palette.Entries.Remove(SelectedEntry);
cc.Entries.Remove(SelectedEntry);
EndEdit();
SelectedEntry = null;
cc.Refresh();
if (palette.Entries.Count == 0)
{
cc.Visible = false;
pnlNoColors.Visible = true;
pnlColorInfo.Visible = false;
}
else
{
cc.Visible = true;
pnlNoColors.Visible = false;
pnlColorInfo.Visible = true;
}
}
}
private int paletteEntryWidth = 64;
private int paletteEntryHeight = 24;
private double _ZoomFactor = 1.0;
public double ZoomFactor
{
get
{
return _ZoomFactor;
}
set
{
_ZoomFactor = value;
cc.Refresh();
}
get { return cc.ZoomFactor; }
set { cc.ZoomFactor = value; }
}
public PaletteEntry HitTest(Vector2D location)
void txtColorName_KeyDown(object sender, KeyEventArgs e)
{
PaletteObjectModel palette = (ObjectModel as PaletteObjectModel);
if (palette == null) return null;
int x = 0, y = 0, w = (int)(paletteEntryWidth * ZoomFactor), h = (int)(paletteEntryHeight * ZoomFactor);
y = (int)cc.VerticalAdjustment.Value;
int startIndex = (int)(cc.VerticalAdjustment.Value / h) * GetLineWidth(), endIndex = palette.Entries.Count - 1;
int startLine = startIndex / w;
y = (int)cc.VerticalAdjustment.Value;
int zcount = 0;
for (int i = startIndex; i <= endIndex; i++)
{
if (x > (int)(cc.Size.Width - w))
{
x = 0;
y += h;
}
Rectangle rect = new Rectangle(x + paletteSpacingX, y + paletteSpacingY, w - paletteSpacingX - paletteSpacingX, h - paletteSpacingY - paletteSpacingY);
if (rect.Contains(location))
return palette.Entries[i];
x += w;
}
return null;
}
public PaletteEntry HitTest(double x, double y)
{
return HitTest(new Vector2D(x, y));
}
void txtColorName_KeyDown(object sender, MBS.Framework.UserInterface.Input.Keyboard.KeyEventArgs e)
{
if (e.Key == MBS.Framework.UserInterface.Input.Keyboard.KeyboardKey.Enter)
if (e.Key == KeyboardKey.Enter)
{
if (SelectedEntry != null)
{
@ -183,17 +242,20 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
}
}
private void cc_MouseDown(object sender, MBS.Framework.UserInterface.Input.Mouse.MouseEventArgs e)
[EventHandler(nameof(cc), nameof(UserInterface.Controls.ColorPalette.ColorPaletteControl.SelectionChanged))]
private void cc_SelectionChanged(object sender, EventArgs e)
{
cc.Focus();
SelectedEntry = cc.SelectedEntry;
PaletteEntry entry = HitTest(e.Location);
if (entry != null)
Selections.Clear();
if (cc.SelectedEntry != null)
{
SelectedEntry = entry;
Selections.Add(new PaletteEntrySelection(cc.SelectedEntry));
}
}
/*
[EventHandler(nameof(cc), nameof(Control.KeyDown))]
private void cc_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
@ -293,21 +355,24 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
}
}
}
*/
private int GetLineWidth()
{
return (int)((double)cc.Size.Width / (paletteEntryWidth * ZoomFactor));
}
[EventHandler(nameof(cc), nameof(Control.MouseDoubleClick))]
private void cc_MouseDoubleClick(object sender, MBS.Framework.UserInterface.Input.Mouse.MouseEventArgs e)
{
SelectedEntry = HitTest(e.Location);
SelectedEntry = cc.HitTest(e.Location);
if (SelectedEntry != null)
{
DisplayEntryProperties(SelectedEntry);
}
}
[EventHandler(nameof(cmdAddColor), nameof(Control.Click))]
private void cmdAddColor_Click(object sender, EventArgs e)
{
PaletteEditor_ContextMenu_Add_Click(sender, e);
}
public void DisplayEntryProperties(PaletteEntry entry)
{
if (entry == null)
@ -352,7 +417,7 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
bool changed = (_SelectedEntry != value);
if (!changed) return;
if (SelectedEntry != null)
if (value != null)
{
ContextMenuCommandID = "PaletteEditor_ContextMenu_Selected";
}
@ -362,108 +427,52 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Pa
}
Selections.Clear();
Selections.Add(new PaletteEntrySelection(value));
if (value != null)
{
Selections.Add(new PaletteEntrySelection(value));
}
System.ComponentModel.CancelEventArgs ce = new System.ComponentModel.CancelEventArgs();
OnSelectionChanging(ce);
if (ce.Cancel) return;
_SelectedEntry = value;
cc.SelectedEntry = _SelectedEntry;
OnSelectionChanged(EventArgs.Empty);
cc.Refresh();
}
}
private TextureBrush AlphaBackgroundBrush = null;
private void DrawAlphaBackground(Graphics g, Rectangle rect)
{
// this is too slow for now, do absolutely nothing
return;
/*
if (AlphaBackgroundBrush == null)
{
Image AlphaBackgroundImage = Image.Create(24, 24);
Graphics g = Graphics.FromImage(AlphaBackgroundImage);
g.FillRectangle(Brushes.White, new Rectangle(0, 0, 24, 24));
g.FillRectangle(Brushes.Black, new Rectangle(16, 16, 16, 16));
AlphaBackgroundBrush = new TextureBrush(AlphaBackgroundImage);
}
*/
int qs = 0;
for (int patternY = 0; patternY < rect.Height; patternY += 8)
{
for (int patternX = qs; patternX < rect.Width - qs; patternX += 8)
{
g.FillRectangle(Brushes.Black, new Rectangle(rect.X + patternX, rect.Y + patternY, 4, 4));
}
if (qs == 0)
{
qs = 8;
}
else
{
qs = 0;
}
}
// e.Graphics.FillRectangle(AlphaBackgroundBrush, rect);
}
int paletteSpacingX = 2;
int paletteSpacingY = 2;
private void cc_Paint(object sender, PaintEventArgs e)
{
PaletteObjectModel palette = (ObjectModel as PaletteObjectModel);
if (palette == null) return;
int x = 0, y = 0, w = (int)(paletteEntryWidth * ZoomFactor), h = (int)(paletteEntryHeight * ZoomFactor);
double shscrh = palette.Entries.Count / GetLineWidth();
cc.ScrollBounds = new Dimension2D(0, (shscrh * h) + h);
int startIndex = (int)(cc.VerticalAdjustment.Value / h) * GetLineWidth(), endIndex = palette.Entries.Count - 1;
int startLine = startIndex / w;
y = (int)cc.VerticalAdjustment.Value;
int zcount = 0;
for (int i = startIndex; i <= endIndex; i++)
{
if (x > (int)(cc.Size.Width - w))
{
x = 0;
y += h;
}
if (y > (int)(cc.VerticalAdjustment.Value + cc.Size.Height + h + h))
{
// we're done for now
return;
}
Rectangle rect = new Rectangle(x + paletteSpacingX, y + paletteSpacingY, w - paletteSpacingX - paletteSpacingX, h - paletteSpacingY - paletteSpacingY);
PaletteEntry entry = palette.Entries[i];
if (entry.Color.A < 1.0)
{
// only fill the alpha background if we need to
DrawAlphaBackground(e.Graphics, rect);
}
e.Graphics.FillRectangle(new SolidBrush(entry.Color), rect);
if (entry == SelectedEntry)
{
e.Graphics.DrawRectangle(new Pen(SystemColors.HighlightBackground, new Measurement(2, MeasurementUnit.Pixel)), new Rectangle(x, y, w, h));
}
zcount++;
x += w;
}
}
protected override void OnObjectModelChanged(EventArgs e)
{
base.OnObjectModelChanged(e);
Refresh();
if (!IsCreated) return;
cc.Entries.Clear();
PaletteObjectModel palette = (ObjectModel as PaletteObjectModel);
if (palette == null) return;
if (palette.Entries.Count > 0)
{
pnlNoColors.Visible = false;
pnlColorInfo.Visible = true;
cc.Visible = true;
}
else
{
pnlNoColors.Visible = true;
pnlColorInfo.Visible = false;
cc.Visible = false;
}
foreach (PaletteEntry entry in palette.Entries)
{
cc.Entries.Add(entry);
}
cc.Refresh();
}

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow">
<property name="can_focus">False</property>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar" id="tb">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToolButton" id="tsbColorAdd">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Add</property>
<property name="label" translatable="yes">Add</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-add</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="tsbColorEdit">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Edit</property>
<property name="label" translatable="yes">Edit</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-edit</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="tsbColorRemove">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Remove</property>
<property name="label" translatable="yes">Remove</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-remove</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="cc">
<property name="name">UniversalEditor.Plugins.Multimedia.UserInterface.Controls.ColorPalette.ColorPaletteControl</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="pnlNoColors">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">32</property>
<property name="margin_right">32</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="label" translatable="yes">No colors yet</property>
<attributes>
<attribute name="font-desc" value="Sans 32"/>
<attribute name="weight" value="thin"/>
</attributes>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cmdAddColor">
<property name="label" translatable="yes">_Add Color</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="pnlColorInfo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="txtColorName">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -36,7 +36,6 @@
<Compile Include="Controls\DrawingArea\DrawingAreaControl.cs" />
<Compile Include="PictureObjectModelExtensions.cs" />
<Compile Include="Editors\Multimedia\Palette\PaletteEditor.cs" />
<Compile Include="Editors\Multimedia\Palette\PaletteEditor.Designer.cs" />
<Compile Include="Editors\Multimedia\Playlist\PlaylistEditor.cs" />
<Compile Include="Editors\Multimedia\Playlist\PlaylistEditor.Designer.cs" />
<Compile Include="Editors\Multimedia\Palette\PaletteEntrySelection.cs" />
@ -59,6 +58,8 @@
<Compile Include="Editors\Multimedia\VectorImage\Controls\VectorImageControl.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\Views\PianoRoll\NoteRenderedEvent.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\Views\PianoRoll\NoteEvent.cs" />
<Compile Include="Controls\ColorPalette\ColorPaletteControl.cs" />
<Compile Include="Editors\Multimedia\Palette\Dialogs\CalculateNeighboringColorsDialog.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Editors\" />
@ -81,6 +82,7 @@
<Folder Include="Editors\Multimedia\PictureCollection\Dialogs\" />
<Folder Include="Editors\Multimedia\VectorImage\" />
<Folder Include="Editors\Multimedia\VectorImage\Controls\" />
<Folder Include="Controls\ColorPalette\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
@ -116,6 +118,8 @@
<EmbeddedResource Include="SettingsProviders\Default.xml" />
<EmbeddedResource Include="Editors\Multimedia\Audio\Waveform\Controls\WaveformAudioEditorTrack.glade" />
<EmbeddedResource Include="Editors\Multimedia\Audio\Waveform\Controls\WaveformAudioEditorTrackControlPanel.glade" />
<EmbeddedResource Include="Editors\Multimedia\Palette\PaletteEditor.glade" />
<EmbeddedResource Include="Editors\Multimedia\Palette\Dialogs\CalculateNeighboringColorsDialog.glade" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -18,7 +18,7 @@
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Palette.PaletteObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.Adobe.ACODataFormat" />
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.Adobe.ACO.ACODataFormat" />
</DataFormats>
</Association>
</Associations>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<UniversalEditor Version="4.0">
<Associations>
<Association>
<Filters>
<Filter Title="Adobe color table" ContentType="application/x-adobe-colortable" IconName="gnome-color-manager">
<FileNameFilters>
<FileNameFilter>*.act</FileNameFilter>
</FileNameFilters>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Palette.PaletteObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.Adobe.ACT.ACTDataFormat" />
</DataFormats>
</Association>
</Associations>
</UniversalEditor>

View File

@ -18,7 +18,7 @@
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Palette.PaletteObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.Adobe.ASEDataFormat" />
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.Adobe.SwatchExchange.ASEDataFormat" />
</DataFormats>
</Association>
</Associations>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<UniversalEditor Version="4.0">
<Associations>
<Association>
<Filters>
<Filter Title="Microsoft DevStudio RIFF palette" ContentType="application/x-microsoft-devstudio-palette" IconName="gnome-color-manager">
<FileNameFilters>
<FileNameFilter>*.gpl</FileNameFilter>
</FileNameFilters>
<MagicByteSequences>
<MagicByteSequence>
<MagicByte Type="String">GIMP Palette</MagicByte>
</MagicByteSequence>
</MagicByteSequences>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Palette.PaletteObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.GIMP.GPLDataFormat" />
</DataFormats>
</Association>
</Associations>
</UniversalEditor>

View File

@ -70,7 +70,18 @@ namespace UniversalEditor.DataFormats.Multimedia.Palette.PaintShop
protected override void SaveInternal(ObjectModel objectModel)
{
throw new NotImplementedException();
PaletteObjectModel palette = (objectModel as PaletteObjectModel);
if (palette == null) throw new ObjectModelNotSupportedException();
IO.Writer tw = base.Accessor.Writer;
tw.WriteLine("JASC-PAL");
tw.WriteLine();
tw.WriteLine(palette.Entries.Count.ToString());
foreach (PaletteEntry entry in palette.Entries)
{
tw.WriteLine(String.Format("{0} {1} {2}", entry.Color.GetRedByte(), entry.Color.GetGreenByte(), entry.Color.GetBlueByte()));
}
}
}
}

View File

@ -78,8 +78,6 @@
<Compile Include="DataFormats\Multimedia\Audio\Synthesized\SPC\SPC700Memory.cs" />
<Compile Include="DataFormats\Multimedia\Audio\Synthesized\SPC\SPC700Registers.cs" />
<Compile Include="DataFormats\Multimedia\Audio\VoicebankPhonemeDictionary\PhonemeDictionaryXMLDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\ACODataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\ASEDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\GIMP\GPLDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\PaintShop\PaintShopPaletteDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Picture\ARGB\ARGBDataFormat.cs" />
@ -341,6 +339,10 @@
<Compile Include="ObjectModels\Multimedia\Audio\Waveform\WaveformAudioSampleRequestEvent.cs" />
<Compile Include="ObjectModels\Multimedia\Audio\Waveform\WaveformAudioSamples.cs" />
<Compile Include="ObjectModels\Multimedia\Audio\Waveform\WaveformAudioSampleLengthRequestEvent.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\ACO\ACOColorSpace.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\ACO\ACODataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\ACT\ACTDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Adobe\SwatchExchange\ASEDataFormat.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Compression\UniversalEditor.Compression.csproj">
@ -403,6 +405,9 @@
<Folder Include="Associations\Video\" />
<Folder Include="Associations\AudioCollection\" />
<Folder Include="Associations\AudioCollection\Synthesized\" />
<Folder Include="DataFormats\Multimedia\Palette\Adobe\ACO\" />
<Folder Include="DataFormats\Multimedia\Palette\Adobe\ACT\" />
<Folder Include="DataFormats\Multimedia\Palette\Adobe\SwatchExchange\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Associations\Playlist\ASX.uexml" />
@ -474,6 +479,8 @@
<EmbeddedResource Include="Associations\WaveformAudio\OSLib.uexml" />
<EmbeddedResource Include="Associations\SynthesizedAudio\PSF.uexml" />
<EmbeddedResource Include="Associations\SynthesizedAudio\SPC.uexml" />
<EmbeddedResource Include="Associations\Palette\Adobe\ACTColorPalette.uexml" />
<EmbeddedResource Include="Associations\Palette\RIFFPalette.uexml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<UniversalEditor Version="4.0">
<Associations>
<Association>
<Filters>
<Filter Title="LibreOffice color palette" ContentType="application/x-opendocument-palette" IconName="gnome-color-manager" HintComparison="FilterOnly">
<FileNameFilters>
<FileNameFilter>*.soc</FileNameFilter>
</FileNameFilters>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.Multimedia.Palette.PaletteObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.Multimedia.Palette.OpenDocument.OpenDocumentSOCPaletteDataFormat" />
</DataFormats>
</Association>
</Associations>
</UniversalEditor>

View File

@ -0,0 +1,90 @@
//
// OpenDocumentSOCPaletteDataFormat.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using MBS.Framework.Drawing;
using UniversalEditor.DataFormats.Markup.XML;
using UniversalEditor.ObjectModels.Markup;
using UniversalEditor.ObjectModels.Multimedia.Palette;
namespace UniversalEditor.DataFormats.Multimedia.Palette.OpenDocument
{
public class OpenDocumentSOCPaletteDataFormat : XMLDataFormat
{
private static DataFormatReference _dfr = null;
protected override DataFormatReference MakeReferenceInternal()
{
if (_dfr == null)
{
_dfr = base.MakeReferenceInternal();
_dfr.Capabilities.Clear();
_dfr.Capabilities.Add(typeof(PaletteObjectModel), DataFormatCapabilities.All);
_dfr.Title = "OpenDocument / OpenOffice / LibreOffice color palette";
}
return _dfr;
}
protected override void BeforeLoadInternal(Stack<ObjectModel> objectModels)
{
base.BeforeLoadInternal(objectModels);
objectModels.Push(new MarkupObjectModel());
}
protected override void BeforeSaveInternal(Stack<ObjectModel> objectModels)
{
base.BeforeSaveInternal(objectModels);
}
protected override void AfterLoadInternal(Stack<ObjectModel> objectModels)
{
base.AfterLoadInternal(objectModels);
MarkupObjectModel mom = (objectModels.Pop() as MarkupObjectModel);
PaletteObjectModel palette = (objectModels.Pop() as PaletteObjectModel);
if (palette == null) throw new ObjectModelNotSupportedException();
MarkupTagElement tagColorTable = mom.FindElementUsingSchema(OpenDocumentXMLSchemas.Office2004, "color-table") as MarkupTagElement;
string drawSchema = OpenDocumentXMLSchemas.DrawUrn;
if (tagColorTable == null)
{
tagColorTable = mom.FindElementUsingSchema(OpenDocumentXMLSchemas.Office2000, "color-table") as MarkupTagElement;
drawSchema = OpenDocumentXMLSchemas.Draw2000;
}
if (tagColorTable == null)
throw new InvalidDataFormatException("could not find color-table tag in OpenOffice 2000 or 2004 schema");
foreach (MarkupTagElement tagColor in tagColorTable.Elements.OfType<MarkupTagElement>())
{
if (!(tagColor.XMLSchema == drawSchema && tagColor.Name == "color")) continue;
MarkupAttribute attName = tagColor.FindAttributeUsingSchema(drawSchema, "name");
MarkupAttribute attColor = tagColor.FindAttributeUsingSchema(drawSchema, "color");
if (attColor == null) continue;
PaletteEntry entry = new PaletteEntry();
entry.Name = attName?.Value;
entry.Color = Color.Parse(attColor.Value);
palette.Entries.Add(entry);
}
}
}
}

View File

@ -0,0 +1,32 @@
//
// OpenDocumentXMLSchemas.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.DataFormats.Multimedia.Palette.OpenDocument
{
public static class OpenDocumentXMLSchemas
{
public static string DrawUrn { get; } = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";
public static string Draw2000 { get; } = "http://openoffice.org/2000/drawing";
public static string Office2000 { get; } = "http://openoffice.org/2000/office";
public static string Office2004 { get; } = "http://openoffice.org/2004/office";
}
}

View File

@ -48,6 +48,8 @@
<Compile Include="ObjectModels\Spreadsheet\Sheet.cs" />
<Compile Include="DataFormats\VectorImage\OpenDocument\OpenDocumentVectorImageDataFormat.cs" />
<Compile Include="DataFormats\VectorImage\OpenDocument\OpenDocumentXMLSchemas.cs" />
<Compile Include="DataFormats\Multimedia\Palette\OpenDocument\OpenDocumentSOCPaletteDataFormat.cs" />
<Compile Include="DataFormats\Multimedia\Palette\OpenDocument\OpenDocumentXMLSchemas.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="ObjectModels\" />
@ -62,6 +64,8 @@
<Folder Include="DataFormats\VectorImage\" />
<Folder Include="DataFormats\VectorImage\OpenDocument\" />
<Folder Include="Associations\VectorImage\" />
<Folder Include="DataFormats\Multimedia\" />
<Folder Include="Associations\Palette\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
@ -84,6 +88,7 @@
<ItemGroup>
<EmbeddedResource Include="Associations\Presentation\HyperCardDataFormat.uexml" />
<EmbeddedResource Include="Associations\VectorImage\OpenDocumentVectorImageDataFormat.uexml" />
<EmbeddedResource Include="Associations\Palette\OpenDocumentPalette.uexml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,81 @@
//
// UnrealPaletteDataFormat.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Framework.Drawing;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.Multimedia.Palette;
namespace UniversalEditor.DataFormats.Multimedia.Palette.Unreal
{
public class UnrealPaletteDataFormat : DataFormat
{
public UnrealPaletteDataFormat()
{
}
protected override void LoadInternal(ref ObjectModel objectModel)
{
PaletteObjectModel palette = (objectModel as PaletteObjectModel);
if (palette == null) throw new ObjectModelNotSupportedException();
Reader reader = Accessor.Reader;
ushort signature = reader.ReadUInt16();
while (!reader.EndOfStream)
{
byte r = reader.ReadByte();
byte g = reader.ReadByte();
byte b = reader.ReadByte();
byte a = reader.ReadByte();
palette.Entries.Add(Color.FromRGBAByte(r, g, b, a));
}
}
protected override void SaveInternal(ObjectModel objectModel)
{
PaletteObjectModel palette = (objectModel as PaletteObjectModel);
if (palette == null) throw new ObjectModelNotSupportedException();
Writer writer = Accessor.Writer;
writer.WriteUInt16(0x4001);
for (int i = 0; i < Math.Min(palette.Entries.Count, 256); i++)
{
writer.WriteByte(palette.Entries[i].Color.GetRedByte());
writer.WriteByte(palette.Entries[i].Color.GetGreenByte());
writer.WriteByte(palette.Entries[i].Color.GetBlueByte());
writer.WriteByte(palette.Entries[i].Color.GetAlphaByte());
}
int remaining = (256 - palette.Entries.Count);
if (remaining > 0)
{
for (int i = 0; i < remaining; i++)
{
writer.WriteByte(0);
writer.WriteByte(0);
writer.WriteByte(0);
writer.WriteByte(0);
}
}
}
}
}

View File

@ -52,6 +52,7 @@
<Compile Include="ObjectModels\UnrealEngine\PropertyType.cs" />
<Compile Include="ObjectModels\UnrealEngine\UnrealPackageObjectModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataFormats\Multimedia\Palette\Unreal\UnrealPaletteDataFormat.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
@ -62,13 +63,26 @@
<Project>{30467E5C-05BC-4856-AADC-13906EF4CADD}</Project>
<Name>UniversalEditor.Essential</Name>
</ProjectReference>
<ProjectReference Include="..\UniversalEditor.Plugins.Multimedia\UniversalEditor.Plugins.Multimedia.csproj">
<Project>{BE4D0BA3-0888-42A5-9C09-FC308A4509D2}</Project>
<Name>UniversalEditor.Plugins.Multimedia</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\MBS.Framework\MBS.Framework\MBS.Framework.csproj">
<Project>{00266B21-35C9-4A7F-A6BA-D54D7FDCC25C}</Project>
<Name>MBS.Framework</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Associations\" />
<Folder Include="Associations\Palette\" />
<Folder Include="DataFormats\Multimedia\" />
<Folder Include="DataFormats\Multimedia\Palette\" />
<Folder Include="DataFormats\Multimedia\Palette\Unreal\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Associations\UnrealPackage.uexml" />
<EmbeddedResource Include="Associations\UnrealUMOD.uexml" />
<EmbeddedResource Include="Associations\Palette\UnrealPalette.uexml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.