Compare commits

...
10 Commits
Author SHA1 Message Date
John Colvin b02f814c65 fix (ui): Remove context menu items that do nothing
They were accidentally brought over from Edge. Their functionality
hasn't been implemented in Spark.
2023-01-23 01:34:55 -05:00
John Colvin 8c42aa93a2 chore: Remove unused code 2023-01-23 01:34:55 -05:00
John Colvin 357bc5ad44 fix (ui): Format perp futs 'Perp' suffix (not bogus exp) 2023-01-23 01:34:55 -05:00
John Colvin 07fb9e8eb7 ui (pnl): Use 'default_text' foreground in popup titles
Previously, the foreground for some popups was a hardcoded dark gray,
which became hard-to-read following the Dark Theme changes.
2023-01-23 01:34:55 -05:00
John Colvin 9f9fc4c8ab fix (analytics-exps): Wait for sym list before loading selection
Bugs (fixed):
   * The selected symbols aren't restored with the workspace

   Cause: The selected symbols were getting loaded once, in the ctr, before the
   list of symbols had been properly initialized. The view automatically
   deselects items that aren't in the ItemsSource.
2023-01-22 12:23:03 -05:00
John Colvin 2aef052398 ui (pnl): Use gray font color when pnl is zero 2023-01-22 12:23:03 -05:00
John Colvin 1c2027506a refactor: Clean up NullableColor/FontWeightProto 2023-01-22 12:23:03 -05:00
John Colvin c3274b2008 refactor: Rename argb_color -> to_uint
This is a more appropriate name
2023-01-22 00:11:28 -05:00
John Colvin 99aef9e86e refactor: Get rid of redundant prop 'NullableColorProto.argb'
It was a relic of the past. Although different fns are called in the props'
getters ('rgb_color' vs 'argb_color'), both ultimately return the same value.
2023-01-22 00:09:38 -05:00
John Colvin 8e9233022e fix (mini-ob): Return root element in CancelColumn.view_factory
Bugs (fixed):
  * Mini Orderbook crashes immediately when opened

  Cause: The (cell) view_factory fn wasn't returning the cell's root
  element, and was instead returning the root's child element.
  As a result, when the row attempted to add this element to its visual
  tree, the following exception was thrown:

    System.ArgumentException: Specified Visual is already a child of
    another Visual or the root of a CompositionTarget.
2023-01-21 13:41:04 -05:00
43 changed files with 792 additions and 852 deletions

No files matched your search

@@ -43,6 +43,7 @@ namespace mbts.spark {
readonly ObservableHashSet<AnalyticsExpirationParametersRowVM> _selected_rows = new();
readonly DeferrableAction _raise_selected_rows_changed;
readonly IRaiseCanExecuteChangedCommand _set_driver_to_nearest_exp_cmd;
IList<string>? _pending_selected_symbols;
AnalyticsExpirationParametersMap? _parameter_map;
(ICommand cmd, IDisposable can_exe_sub)? _smart_copy_roll_target_to_selection_cmd;
@@ -65,9 +66,7 @@ namespace mbts.spark {
_is_dirty = backing(nameof(is_dirty), () => rows.Any(r => r.is_dirty));
if (startup_data is not null) {
if (!startup_data.selected_symbols.is_null_or_empty()) {
selected_symbols.AddRange(startup_data.selected_symbols);
}
_pending_selected_symbols = startup_data.selected_symbols;
auto_copy_rolls_is_checked = startup_data.auto_copy_rolls_is_checked;
auto_copy_rates_is_checked = startup_data.auto_copy_rates_is_checked;
}
@@ -297,8 +296,8 @@ namespace mbts.spark {
symbols.sync_with(_parameters.Select(p => p.security.symbol).Distinct().Ordered());
using var _ = _sync_visible_rows.defer();
if (is_first_update) {
// select all symbols on first update
selected_symbols.sync_with(symbols);
selected_symbols.sync_with(_pending_selected_symbols?.Intersect(symbols) ?? symbols);
_pending_selected_symbols = null;
}
}
@@ -96,7 +96,7 @@ namespace mbts.spark {
get => _core_settings.font_weight_override;
set {
using var _ = detect_property_change();
_core_settings.with(font_weight_override: value.HasValue ? new NullableFontWeightProto(value) : null);
_core_settings.with(font_weight_override: value.HasValue ? new(value) : null);
}
}
@@ -145,7 +145,7 @@ namespace mbts {
!(x == y);
public override string ToString() =>
$"{security_tuple} {expiration.ToShortDateString()}";
$"{security_tuple} {SecurityFormatter.format_expiration(expiration)}";
}
[ProtoContract]
@@ -79,10 +79,12 @@ namespace bts.shell.market_view {
var ask_col_index = columns.FindIndex(x => x.id == MarketViewWindowFactory.col_id(Columns.Ask));
if (bid_col_index > -1 && ask_col_index > -1) {
if (!columns[bid_col_index].background_color_override.HasValue) {
columns[bid_col_index] = columns[bid_col_index].with(background_color_override: new NullableColorProto(BTSColors.MarketData.bid.value));
columns[bid_col_index] = columns[bid_col_index].with(
background_color_override: new(BTSColors.MarketData.bid));
}
if (!columns[ask_col_index].background_color_override.HasValue) {
columns[ask_col_index] = columns[ask_col_index].with(background_color_override: new NullableColorProto(BTSColors.MarketData.ask.value));
columns[ask_col_index] = columns[ask_col_index].with(
background_color_override: new(BTSColors.MarketData.ask));
}
}
// and enable background color upgrade
@@ -70,11 +70,13 @@ namespace bts.shell {
bool applied = false;
if (bid_col_index > -1 && ask_col_index > -1) {
if (!columns[bid_col_index].background_color_override.HasValue) {
columns[bid_col_index] = columns[bid_col_index].with(background_color_override: new NullableColorProto(BTSColors.MarketData.bid.value));
columns[bid_col_index] = columns[bid_col_index].with(
background_color_override: new(BTSColors.MarketData.bid));
applied = true;
}
if (!columns[ask_col_index].background_color_override.HasValue) {
columns[ask_col_index] = columns[ask_col_index].with(background_color_override: new NullableColorProto(BTSColors.MarketData.ask.value));
columns[ask_col_index] = columns[ask_col_index].with(
background_color_override: new(BTSColors.MarketData.ask));
applied = true;
}
}
@@ -410,13 +410,13 @@ namespace mbts.spark {
day_change = new DaySettings {
// (neutral)
font = _default_font,
background_color = Colors.Transparent.rgb_color(),
background_color = Colors.Transparent.to_uint(),
// negative
negative_font_color = Colors.White.rgb_color(),
negative_background_color = Colors.Red.rgb_color(),
negative_font_color = Colors.White.to_uint(),
negative_background_color = Colors.Red.to_uint(),
// positive
positive_font_color = Colors.White.rgb_color(),
positive_background_color = Colors.Green.rgb_color()
positive_font_color = Colors.White.to_uint(),
positive_background_color = Colors.Green.to_uint()
},
session_low = _default_item,
session_high = _default_item,
@@ -431,8 +431,8 @@ namespace mbts.spark {
public static LadderPanelPricePointSettings tt_default {
get {
var rv = historic_default;
rv.day_change.background_color = Color.FromRgb(113, 201, 69).rgb_color();
rv.day_change.font.font_color = Colors.Black.rgb_color();
rv.day_change.background_color = Color.FromRgb(113, 201, 69).to_uint();
rv.day_change.font.font_color = Colors.Black.to_uint();
return rv;
}
}
@@ -484,7 +484,7 @@ namespace mbts.spark {
static ItemSettings _default_item =>
new ItemSettings {
font = _default_font,
background_color = Colors.Transparent.rgb_color()
background_color = Colors.Transparent.to_uint()
};
[ProtoContract]
@@ -97,7 +97,7 @@ namespace mbts.spark {
security_key = use_self_security ? null : selected_security_key,
price_type = _selected_price_type,
display = new LadderMarketBreakLine {
color = color.rgb_color(),
color = color.to_uint(),
show = show,
refresh_mode = refresh_mode
}
@@ -27,7 +27,7 @@ namespace mbts.spark {
class LadderOrderVM : DisposableViewModelBase {
static readonly Color _colorbg = Colors.White;
static readonly Color _darkbg = Color.FromRgb(0xbf, 0xbf, 0xbf);
static readonly Brush _color_bg_brush = _colorbg.rgb_color().rgb_brush();
static readonly Brush _color_bg_brush = _colorbg.to_uint().rgb_brush();
readonly LadderVM _owner;
readonly double _real_price;
@@ -228,7 +228,7 @@ namespace mbts.spark {
if (_orders.TryGetValue(order.Key, out var opm)) {
algo_studio_abbreviation = (opm.meta?.abbreviation).is_null_or_empty() ?
_abbreviate_algo(opm.algo) : opm.meta?.abbreviation ?? string.Empty;
border = opm.meta?.badge_color?.rgb_color().rgb_brush() ?? border;
border = opm.meta?.badge_color?.to_uint().rgb_brush() ?? border;
}
algo_type = order.order_type().is_bts_algo_type() ?
order.order_type() : CustomOrderDefinition.CustomOneofCase.None;
@@ -42,13 +42,13 @@ namespace mbts.spark {
public LadderPanelPricePointSettings.ItemSettings create() =>
new LadderPanelPricePointSettings.ItemSettings {
font = new FontParamsProto {
font_color = font_color.rgb_color(),
font_color = font_color.to_uint(),
font_size = font_size,
typeface = new(
font_family.name() ?? TextUtils.StandardFontFamilyName,
font_weight.ToOpenTypeWeight())
},
background_color = background_color.rgb_color(),
background_color = background_color.to_uint(),
show_label = show_label
};
@@ -111,11 +111,11 @@ namespace mbts.spark {
show_label = base_settings.show_label,
background_color = base_settings.background_color,
// negative
negative_font_color = negative_font_color.rgb_color(),
negative_background_color = negative_background_color.rgb_color(),
negative_font_color = negative_font_color.to_uint(),
negative_background_color = negative_background_color.to_uint(),
// positive
positive_font_color = positive_font_color.rgb_color(),
positive_background_color = positive_background_color.rgb_color()
positive_font_color = positive_font_color.to_uint(),
positive_background_color = positive_background_color.to_uint()
};
}
}
@@ -700,8 +700,8 @@ namespace mbts.spark {
font_weight = font_weight.ToOpenTypeWeight(),
width = width,
show = show,
foreground = foreground.rgb_color(),
background = background.rgb_color()
foreground = foreground.to_uint(),
background = background.to_uint()
};
}
}
@@ -891,7 +891,7 @@ namespace mbts.spark {
};
root_bd.SetBinding(
Border.BackgroundProperty, new Binding(nameof(background_brush)) { Source = this });
return button;
return root_bd;
}
}
@@ -231,7 +231,7 @@ namespace bts.shell {
sorting_criteria,
_vm.anchors,
filters,
state.grid.with(columns: cols, background: _vm.grid_background_color.rgb_color()),
state.grid.with(columns: cols, background: _vm.grid_background_color.to_uint()),
calc_type,
_vm.header_row_display,
menu_display: _menu_display_vm?.create());
@@ -68,10 +68,10 @@ namespace bts.shell.pnl {
typeface = new TypefaceProto(
cell_appearance.font_family?.name(),
(cell_appearance.font_weight ?? FontWeights.Normal).ToOpenTypeWeight()),
font_color = cell_appearance.foreground?.rgb_color() ?? 0,
font_color = cell_appearance.foreground?.to_uint() ?? 0,
font_size = cell_appearance.font_size,
},
background = cell_appearance.background?.rgb_color()
background = cell_appearance.background?.to_uint()
};
public PNLCellAppearance to_appearance() {
File diff suppressed because it is too large. Load diff
@@ -103,14 +103,14 @@ namespace bts.shell.pnl {
public PNLAnimation to_animation(PNLView.Columns key) =>
new PNLAnimation {
column = key,
foreground = is_font_color_overridden ? font_color_override.color.rgb_color() : (uint?)null,
background = is_background_overridden ? background_override.color.rgb_color() : (uint?)null,
foreground = is_font_color_overridden ? font_color_override.color.to_uint() : (uint?)null,
background = is_background_overridden ? background_override.color.to_uint() : (uint?)null,
font_weight = is_font_weight_overridden ? font_weight_override.ToOpenTypeWeight() : (int?)null
};
public PNLCellAppearanceProto to_appearance_proto() =>
new PNLCellAppearanceProto {
background = is_background_overridden ? background_override.color.rgb_color() : (uint?)null,
background = is_background_overridden ? background_override.color.to_uint() : (uint?)null,
font_params = to_font_params()
};
@@ -119,7 +119,7 @@ namespace bts.shell.pnl {
typeface = new TypefaceProto(
font_family_override?.name(),
is_font_weight_overridden ? font_weight_override.ToOpenTypeWeight() : 0),
font_color = is_font_color_overridden ? font_color_override.color.rgb_color() : 0,
font_color = is_font_color_overridden ? font_color_override.color.to_uint() : 0,
font_size = font_size_override
};
}
@@ -132,7 +132,7 @@ namespace bts.shell.pnl {
// group
var (group_cell_appearance, group_row_background_colors) = group_row_defaults.create();
s.group_cell_appearance = PNLCellAppearanceProto.from_appearance(group_cell_appearance);
s.group_background_colors.SetItems(group_row_background_colors.Select(c => c.rgb_color()));
s.group_background_colors.SetItems(group_row_background_colors.Select(c => c.to_uint()));
//
return s;
}
@@ -329,20 +329,19 @@ namespace bts.shell.pnl {
}
static (string desc, Color fg) _fills_title(Columns key) {
const uint net_fg = 0x333333u;
switch (key) {
case Columns.SODLongPos: return ("Open Buy Fills", BTSColors.MarketData.bid);
case Columns.SODShortPos: return ("Open Sell Fills", BTSColors.MarketData.ask);
case Columns.SODNetPos: return ("Open Fills", net_fg.rgb_color());
case Columns.SODNetPos: return ("Open Fills", BTSColors.UI.default_text);
case Columns.DayLongPos: return ("Day Buy Fills", BTSColors.MarketData.bid);
case Columns.DayShortPos: return ("Day Sell Fills", BTSColors.MarketData.ask);
case Columns.DayNetPos: return ("Day Fills", net_fg.rgb_color());
case Columns.DayNetPos: return ("Day Fills", BTSColors.UI.default_text);
case Columns.RawDayLongPos: return ("Raw Day Buy Fills", BTSColors.MarketData.bid);
case Columns.RawDayShortPos: return ("Raw Day Sell Fills", BTSColors.MarketData.ask);
case Columns.RawDayNetPos: return ("Raw Day Fills", net_fg.rgb_color());
case Columns.RawDayNetPos: return ("Raw Day Fills", BTSColors.UI.default_text);
case Columns.TotalLongPos: return ("All Buy Fills", BTSColors.MarketData.bid);
case Columns.TotalShortPos: return ("All Sell Fills", BTSColors.MarketData.ask);
case Columns.TotalNetPos: return ("All Fills", net_fg.rgb_color());
case Columns.TotalNetPos: return ("All Fills", BTSColors.UI.default_text);
default: throw ExceptionBuilder.Argument.unexpected_case(key, nameof(key));
}
}
@@ -368,7 +367,7 @@ namespace bts.shell.pnl {
switch (key) {
case Columns.WorkingLongPos: return ("Working Buy Orders", BTSColors.MarketData.bid);
case Columns.WorkingShortPos: return ("Working Sell Orders", BTSColors.MarketData.ask);
case Columns.WorkingNetPos: return ("Working Orders", 0x333333u.rgb_color());
case Columns.WorkingNetPos: return ("Working Orders", BTSColors.UI.default_text);
default: throw ExceptionBuilder.Argument.unexpected_case(key, nameof(key));
}
}
@@ -29,7 +29,7 @@ namespace mbts.spark {
get {
var m = new OrderMetadata { KeyBinding = string.Empty, NoProps = false };
if (_studio_meta.HasValue && _studio_meta.Value.badge_color.HasValue)
m.Color = _studio_meta.Value.badge_color.Value.rgb_color();
m.Color = _studio_meta.Value.badge_color.Value.to_uint();
return m;
}
}
@@ -136,7 +136,7 @@ namespace mbts.analytics {
IEnumerable<VolSurfaceExpiration> all_exps) {
var exps = all_exps.Where(vse => vse.symbol.is_null_or_empty()).ToArray();
var exp_header_cells = exps
.Select(vse => DateFormatter.Format(vse.expiration, DateFormat.DayMonthAbvDiff2000))
.Select(vse => SecurityFormatter.format_expiration(vse.expiration))
.ToArray();
return (exps, exp_header_cells);
}
@@ -145,7 +145,7 @@ namespace mbts.analytics {
IEnumerable<VolSurfaceExpiration> all_exps) {
var exps = all_exps.ToArray();
var exp_header_cells = exps.Select(vse => string.IsNullOrEmpty(vse.symbol) ?
DateFormatter.Format(vse.expiration, DateFormat.DayMonthAbvDiff2000) : vse.symbol)
SecurityFormatter.format_expiration(vse.expiration) : vse.symbol)
.ToArray();
return (exps, exp_header_cells);
}
@@ -57,8 +57,6 @@
<analytics:ComboFutureDataColumn x:Key="FutureSymDataColumn" HeaderTemplate="{StaticResource SymHeaderTemplate}" ElementStyle="{StaticResource FutureSymDataElementStyle}" MinWidth="60" x:Shared="False" />
<analytics:ComboOptionDataColumn x:Key="OptionExpDataColumn" HeaderTemplate="{StaticResource ExpHeaderTemplate}" ElementStyle="{StaticResource OptionExpDataElementStyle}" MinWidth="60" x:Shared="False" />
<analytics:ComboOptionDataColumn x:Key="OptionSymDataColumn" HeaderTemplate="{StaticResource SymHeaderTemplate}" ElementStyle="{StaticResource OptionSymDataElementStyle}" MinWidth="60" x:Shared="False" />
<MenuItem x:Key="LaunchConfigurationEditorMenuItem" x:Shared="False" Header="Report Configuration..." Command="{Binding DataContext.launch_configuration_editor, Source={x:Reference ComboWindow}}" />
<MenuItem x:Key="ExportToCSVMenuItem" Header="Export To CSV..." Command="{Binding export_to_csv_command}" CommandParameter="{Binding DataContext.show_call_put, Source={x:Reference ComboWindow}}" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
@@ -99,14 +97,7 @@
VerticalGridLinesBrush="LightGray"
CanUserResizeColumns="False"
CanUserReorderColumns="False"
IsReadOnly="True"
>
<DataGrid.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="LaunchConfigurationEditorMenuItem" />
</ContextMenu>
</DataGrid.ContextMenu>
</c:DataGridEx>
IsReadOnly="True" />
</AdornerDecorator>
<GridSplitter Grid.Row="2" Height="3" Background="Black" HorizontalAlignment="Stretch" />
@@ -144,12 +135,6 @@
<TextBlock Text="{Binding Item.strike, RelativeSource={RelativeSource AncestorType=DataGridRow}}" />
</DataTemplate>
</DataGrid.RowHeaderTemplate>
<DataGrid.ContextMenu>
<ContextMenu>
<StaticResourceExtension ResourceKey="LaunchConfigurationEditorMenuItem" />
<StaticResourceExtension ResourceKey="ExportToCSVMenuItem" />
</ContextMenu>
</DataGrid.ContextMenu>
</c:DataGridEx>
</AdornerDecorator>
@@ -1,5 +1,7 @@
#nullable enable
namespace mbts.analytics {
using bts.api;
using System;
using System.Diagnostics.Contracts;
@@ -17,13 +19,9 @@ namespace mbts.analytics {
symbol = null;
}
private static string _format_exp(DateTime exp) {
return mbts.ui.utility.ExpirationFormatter.DateFormatter.format_day_month_year(exp);
}
SlideGreekUnitKey(DateTime exp_date) {
exp = exp_date;
_unique_name = _format_exp(exp_date);
_unique_name = SecurityFormatter.format_expiration(exp_date);
type = GroupType.Exp;
symbol = null;
}
@@ -31,7 +29,7 @@ namespace mbts.analytics {
SlideGreekUnitKey(DateTime exp_date, string symbol) {
exp = exp_date;
this.symbol = symbol;
_unique_name = $"{_format_exp(exp_date)}:{symbol}";
_unique_name = $"{SecurityFormatter.format_expiration(exp_date)}:{symbol}";
type = GroupType.SymExp;
}
@@ -71,7 +71,8 @@ namespace BCG {
foreach (string sym in temp.Keys) {
SortedList<DateTime, string> temp2 = temp[sym];
foreach (KeyValuePair<DateTime, string> kvp in temp2) {
string datecode = bts.api.DateFormatter.Format(kvp.Key, bts.api.DateFormat.MonthCodeLastDigitYear);
string datecode = bts.api.SecurityFormatter.format_expiration(
kvp.Key, date_format: bts.api.DateFormat.MonthCodeLastDigitYear);
string explegs = (temp.Keys.Count > 1) ? string.Concat(sym, datecode, "_", kvp.Value) :
string.Concat(datecode, "_", kvp.Value);
@@ -61,7 +61,7 @@ namespace BCG {
string rv = String.Empty;
foreach (SingleSpreadLeg l in legs)
rv += (rv == String.Empty ? "" : "/") + l.symbol + //BCG.Utilities.Dates.DateCode.getMonthSymbol(l.exp) + (l.exp.Year - 2000);
bts.api.DateFormatter.Format(l.exp, bts.api.DateFormat.DayMonthAbvDiff2000);
SecurityFormatter.format_expiration(l.exp);
return rv;
}
@@ -253,6 +253,7 @@ namespace mbts.ui {
public static BTSColor foreground => UI.default_foreground;
public static BTSColor anchor => Colors.Gold;
public static BTSColor profit => Colors.Green;
public static BTSColor net_zero => BTSCoreColors.gray;
public static BTSColor loss => BTSCoreColors.venetian_red;
public static BTSColor header_row_background => 0xffaaaaaa;
// group background colors
@@ -17,7 +17,7 @@ namespace bts.proto {
readonly double _opacity;
public ColorOpacityProto(Color color = default, double opacity = 1.0)
: this(color.rgb_color(), opacity) { }
: this(color.to_uint(), opacity) { }
public ColorOpacityProto(uint color = 0u, double opacity = 1.0) {
_color = color;
@@ -16,7 +16,7 @@ namespace bts.proto {
readonly bool _show;
public ColorShowProto(Color value, bool show = true)
: this(value.rgb_color(), show) { }
: this(value.to_uint(), show) { }
public ColorShowProto(uint value, bool show = true) {
_value = value;
@@ -1,51 +0,0 @@
using bts.api;
using bts.utils;
using mbts.utils;
using ProtoBuf;
using System;
namespace bts.proto {
[ProtoContract]
public struct ExpDate : IEquatable<ExpDate> {
[ProtoMember(1)]
readonly uint _month;
[ProtoMember(2)]
readonly uint _year;
[ProtoMember(3)]
readonly uint _day;
public ExpDate(SecurityImmutable security)
: this(security.earliest_expiration()) { }
public ExpDate(DateTime date) {
_month = (uint)date.Month;
_year = (uint)date.Year;
_day = (uint)date.Day;
}
public uint month => _month;
public uint year => _year;
public uint day => _day;
public bool Equals(ExpDate other) =>
other._month == _month && other._year == year && other._day == day;
public override bool Equals(object obj) => obj is ExpDate ed && Equals(ed);
public static bool operator ==(ExpDate a, ExpDate b) => a.Equals(b);
public static bool operator !=(ExpDate a, ExpDate b) => !a.Equals(b);
public override int GetHashCode() =>
EqualityComparer.aggregate_hash((int)_month, (int)_day, (int)_year);
public override string ToString() =>
DateFormatter.Format((int)_year, (int)_month, (int)_day, DateFormat.MonthCodeLastDigitYear);
}
static class ExpDateExtensions {
public static DateTime to_date_time(this ExpDate exp_date) =>
new DateTime((int)exp_date.year, (int)exp_date.month, (int)exp_date.day);
}
}
@@ -1,36 +1,42 @@
using bts.utils;
using mbts.ui;
using ProtoBuf;
using System;
using System.Windows.Media;
#nullable enable
namespace bts.proto {
using bts.utils;
using mbts.ui;
using ProtoBuf;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Media;
[ProtoContract]
struct NullableColorProto : IEquatable<NullableColorProto> {
readonly struct NullableColorProto : IEquatable<NullableColorProto> {
[ProtoMember(1)]
readonly uint? _value;
public NullableColorProto(Color? value) =>
_value = value?.rgb_color();
_value = value?.to_uint();
public NullableColorProto(uint value) =>
_value = value;
public static NullableColorProto none => new(null);
public Color? value => _value?.rgb_color();
public Color? argb => _value?.argb_color();
public Color? value => _value?.argb_color();
[MemberNotNullWhen(true, nameof(value))]
public bool has_value => value.HasValue;
public bool Equals(NullableColorProto other) =>
EqualityComparer.nullable_equals(_value, other._value);
public override bool Equals(object obj) =>
public override bool Equals(object? obj) =>
obj is NullableColorProto ncp && Equals(ncp);
public override int GetHashCode() =>
_value.HasValue ? (int)_value.Value : 0;
public override string ToString() =>
_value?.ToString() ?? string.Empty;
public static bool operator ==(NullableColorProto a, NullableColorProto b) => a.Equals(b);
public static bool operator !=(NullableColorProto a, NullableColorProto b) => !a.Equals(b);
}
@@ -1,42 +0,0 @@
using bts.utils;
using mbts.utils;
using ProtoBuf;
using System;
using System.Windows;
namespace mbts.ui.settings {
[ProtoContract]
struct NullableFontWeightProto : IEquatable<NullableFontWeightProto> {
[ProtoMember(1)]
readonly ushort? _value;
public NullableFontWeightProto(FontWeight? value) =>
_value = (ushort?)value?.ToOpenTypeWeight();
public NullableFontWeightProto(ushort value) =>
_value = value;
public FontWeight? value {
get {
if (_value.HasValue)
return FontWeight.FromOpenTypeWeight(_value.Value);
return null;
}
}
public bool Equals(NullableFontWeightProto other) =>
EqualityComparer.nullable_equals(_value, other._value);
public override bool Equals(object obj) =>
obj is NullableFontWeightProto ncp && Equals(ncp);
public override int GetHashCode() =>
_value.HasValue ? _value.Value : 0;
public static bool operator ==(NullableFontWeightProto a, NullableFontWeightProto b) => a.Equals(b);
public static bool operator !=(NullableFontWeightProto a, NullableFontWeightProto b) => !a.Equals(b);
}
}
@@ -0,0 +1,49 @@
#nullable enable
namespace bts.proto {
using bts.utils;
using ProtoBuf;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
[ProtoContract]
readonly struct NullableFontWeightProto : IEquatable<NullableFontWeightProto> {
[ProtoMember(1)]
readonly int? _value;
public NullableFontWeightProto(FontWeight? value) =>
_value = value?.ToOpenTypeWeight();
public NullableFontWeightProto(int value) =>
_value = value;
public static NullableFontWeightProto none =>
new(null);
public FontWeight? value =>
_value.HasValue ? FontWeight.FromOpenTypeWeight(_value.Value) : null;
[MemberNotNullWhen(true, nameof(value))]
public bool has_value => value.HasValue;
public bool Equals(NullableFontWeightProto other) =>
EqualityComparer.nullable_equals(_value, other._value);
public override bool Equals(object? obj) =>
obj is NullableFontWeightProto fw && Equals(fw);
public override int GetHashCode() =>
_value ?? 0;
public override string ToString() =>
_value?.ToString() ?? string.Empty;
public static bool operator ==(NullableFontWeightProto a, NullableFontWeightProto b) =>
a.Equals(b);
public static bool operator !=(NullableFontWeightProto a, NullableFontWeightProto b) =>
!a.Equals(b);
}
}
@@ -103,7 +103,7 @@ namespace mbts.ui.controls {
color = brush.Color;
opacity = brush.Opacity;
}
public ColorOpacityProto to_proto() => new ColorOpacityProto(color.rgb_color(), opacity);
public ColorOpacityProto to_proto() => new ColorOpacityProto(color.to_uint(), opacity);
}
class NamedColorPickerPopupVM : ColorPickerPopupVM {
@@ -104,7 +104,7 @@ namespace mbts.ui.settings {
public bool is_expanded => _is_expanded;
public FontWeight? font_weight_override => _font_weight_override.value;
public Color? font_color_override => _font_color_override.value;
public Color? background_color_override => _background_color_override.argb;
public Color? background_color_override => _background_color_override.value;
public double width => _width;
public HorizontalAlignment horizontal_alignment => _horizontal_alignment;
public double horizontal_offset => _horizontal_offset;
@@ -126,7 +126,7 @@ namespace mbts.ui.settings {
width ?? this.width,
horizontal_alignment ?? this.horizontal_alignment,
horizontal_offset ?? this.horizontal_offset,
(background_color_override ?? _background_color_override).argb);
(background_color_override ?? _background_color_override).value);
public GridColumnSettings Clone() =>
ProtobufSerializationHelper.clone(this);
@@ -23,7 +23,7 @@
public static GridSettings Default =>
new GridSettings(
selection_highlight: Colors.MediumSlateBlue.with(0x63).argb_color(),
selection_highlight: Colors.MediumSlateBlue.with(0x63).to_uint(),
background: BTSColors.Grid.default_column_background,
font_color: BTSColors.Grid.default_column_foreground);
@@ -149,7 +149,7 @@ namespace mbts.ui.settings {
var a = sl.A.within_range((byte)30, (byte)200);
if (sl.A != a) {
sl.A = a;
new_settings = settings.with(selection_highlight: sl.rgb_color());
new_settings = settings.with(selection_highlight: sl.to_uint());
return true;
}
}
@@ -137,9 +137,9 @@ namespace mbts.spark {
foreach (IGrouping<TPredicateData, CellAnimation> g in animations)
animation_map.AddOrUpdate(g.Key, p => animation_tuple(c: g), (p, t) => t.cell_animations.AddRange(g));
}
return _create_settings_obj(new GridSettings(font_family.name(), font_size, font_weight, font_color.color.rgb_color(), selection_highlight.color.rgb_color(), col_settings,
return _create_settings_obj(new GridSettings(font_family.name(), font_size, font_weight, font_color.color.to_uint(), selection_highlight.color.to_uint(), col_settings,
background: background_color.color.with(
(byte)(background_color.opacity.within_range(0, 1) * 255.0)).rgb_color()),
(byte)(background_color.opacity.within_range(0, 1) * 255.0)).to_uint()),
animation_map.Select(kv => PredicateAnimations.create_data<TRowData, TPredicateData>(kv.Key, kv.Value.cell_animations, kv.Value.row_animations, kv.Value.sounds)));
//
(List<RowAnimation> row_animations, List<SoundNotification> sounds, List<CellAnimation> cell_animations) animation_tuple(IEnumerable<RowAnimation> r = null, IEnumerable<SoundNotification> s = null, IGrouping<TPredicateData, CellAnimation> c = null) =>
@@ -120,10 +120,10 @@ namespace mbts.spark {
font_family.name(),
font_size,
font_weight,
font_color.color.rgb_color(),
selection_highlight.color.rgb_color(),
font_color.color.to_uint(),
selection_highlight.color.to_uint(),
columns.Select(c => c.create()),
background: background_color.color.argb_color());
background: background_color.color.to_uint());
public void load_from(GridSettings value) {
if (value == null)
@@ -258,13 +258,13 @@ namespace mbts.spark {
settings.title_font_params = new() {
typeface = new(title_font_family, title_font_weight.ToOpenTypeWeight()),
font_size = title_font_size,
font_color = title_font_color.argb_color(),
font_color = title_font_color.to_uint(),
};
settings.font_params = new() {
typeface = new(font_family, font_weight.ToOpenTypeWeight()),
font_size = font_size,
font_color = font_color.argb_color(),
font_color = font_color.to_uint(),
};
}
@@ -42,6 +42,7 @@
<TextBlock
x:Name="PART_Context"
FontWeight="Bold"
Foreground="{u:BTSBrush UI.default_text}"
HorizontalAlignment="Left"
Margin="4,0,0,0"
Text="{Binding context}"
@@ -22,16 +22,11 @@ namespace mbts.ui.converters {
object value, Type target_type, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
public string convert(SecurityExpiration exp) {
var sb = new StringBuilder();
if (ShowType) {
sb.Append($"[{SecurityFormatter.format_security_type(exp.security_type)}] ");
}
if (ShowSymbol) {
sb.Append(exp.symbol);
}
sb.Append(DateFormatter.Format(exp.expiration, DateFormat));
return sb.ToString();
}
public string convert(SecurityExpiration exp) =>
SecurityFormatter.format_expiration(
exp.expiration,
ShowSymbol ? exp.symbol : null,
ShowType ? exp.security_type.contract_case() : null,
DateFormat);
}
}
@@ -114,10 +114,7 @@ namespace mbts.ui {
public static SolidColorBrush rgb_solid_brush(this uint color) =>
new SolidColorBrush(rgb_color(color));
public static UInt32 argb_color(this Color color) =>
(uint)color.A << 24 | (uint)color.R << 16 | (uint)color.G << 8 | (uint)color.B;
public static UInt32 rgb_color(this Color color) =>
public static uint to_uint(this Color color) =>
(uint)color.A << 24 | (uint)color.R << 16 | (uint)color.G << 8 | (uint)color.B;
public static Brush to_brush(this Color color) =>
@@ -33,13 +33,6 @@
public static string Format(DateTime date, DateFormat format) =>
Format(date.Year, date.Month, date.Day, format);
/// <summary>
/// Returns a concise string representation of a date (using single-letter month codes)
/// appropriate for UIs (e.g. March 22, 2019: 22 Mar 19, or 22 H19).
/// </summary>
public static string Format(uint year, uint month, uint day, DateFormat format) =>
Format((int)year, (int)month, (int)day, format);
/// <summary>
/// Returns a concise string representation of a date (using single-letter month codes)
/// appropriate for UIs (e.g. March 22, 2019: 22 Mar 19, or 22 H19).
@@ -10,6 +10,9 @@ namespace bts.api {
public partial class Security {
public static security_key key(Security s) { return s.Id; }
public static bool is_perpetual_exp(DateTime exp) =>
exp.Year < 2000 || exp.Year > 2999;
public static class Defaults {
public static ContractSpecification ContractSpecification =>
new() {
@@ -21,7 +21,7 @@
format_future(symbol, (uint)exp.Year, (uint)exp.Month, (uint)exp.Day);
public static string format_future(string symbol, uint exp_year, uint exp_month, uint exp_day) =>
$"{symbol}{DateFormatter.Format(exp_year, exp_month, exp_day, DateFormat.DayMonthAbvDiff2000)}";
$"{symbol}{format_expiration(new((int)exp_year, (int)exp_month, (int)exp_day))}";
public static string format_future(string symbol, FutureContractImmutable future) =>
format_future(symbol, future.ExpirationYear, future.ExpirationMonth, future.ExpirationDay);
@@ -108,12 +108,17 @@
string? symbol = null,
Security.ContractOneofCase? type = null,
DateFormat date_format = DateFormat.DayMonthAbvDiff2000) {
var result = DateFormatter.Format(exp_date, date_format);
var result = Security.is_perpetual_exp(exp_date) ?
"Perp" : DateFormatter.Format(exp_date, date_format);
if (symbol is not null) {
result = symbol + " " + result;
}
if (type.HasValue) {
result = format_security_type(type.Value) + " " + result;
if (result.Length == 0) {
result = format_security_type(type.Value);
} else {
result = $"[{format_security_type(type.Value)}] {result}";
}
}
return result;
}