diff --git a/JM/CF/Defines/CFDefines.c b/JM/CF/Defines/CFDefines.c index 3b26fa74..2a483d2d 100644 --- a/JM/CF/Defines/CFDefines.c +++ b/JM/CF/Defines/CFDefines.c @@ -5,6 +5,15 @@ //#define CF_TRACE_ENABLED +#define CF_MVVM +//#define CF_MVVM_TRACE + +#define CF_WINDOWS +//#define CF_WINDOWS_TRACE + +#define CF_DEBUG +//#define CF_DEBUG_TRACE + #define CF_GHOSTICONS //#define CF_MODSTORAGE @@ -16,3 +25,7 @@ #define CF_SURFACES #define CF_MODULES + +#ifdef CF_DEBUG +#define CF_DebugUI +#endif diff --git a/JM/CF/GUI/config.cpp b/JM/CF/GUI/config.cpp index 89be2acf..b1c775e7 100644 --- a/JM/CF/GUI/config.cpp +++ b/JM/CF/GUI/config.cpp @@ -10,4 +10,168 @@ class CfgPatches "DZ_Data" }; }; +}; +class CfgWrapperUI +{ + class Colors + { + color1[] = {0.0,0.0,0.0,1.0}; + color2[] = {0.2,0.2,0.2,1.0}; + color3[] = {0.5,0.5,0.5,1.0}; + color4[] = {0.6,0.6,0.6,1.0}; + color5[] = {0.8,0.8,0.8,1.0}; + }; + class Background + { + alpha = 0.75; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class TitleBar + { + alpha = 0.3; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class GroupBox + { + alpha = 0.2; + }; + class GroupBox2 + { + alpha = 0.5; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class Button + { + color1[] = {0.0,0.0,0.0,0.3}; + color2[] = {0.2,0.2,0.2,0.3}; + color3[] = {0.5,0.5,0.5,0.3}; + color4[] = {0.6,0.6,0.6,0.3}; + color5[] = {0.8,0.8,0.8,0.3}; + }; + class ListBox + { + line = "#(argb,8,8,3)color(1,1,1,1)"; + thumb = "#(argb,8,8,3)color(1,1,1,1)"; + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + boxLeft = "#(argb,8,8,3)color(1,1,1,1)"; + boxRight = "#(argb,8,8,3)color(1,1,1,1)"; + boxHorz = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class Slider + { + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + thumb = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class Cursors + { + class Arrow + { + texture = "JM\CF\GUI\textures\arrow_raw.paa"; + width = 16; + height = 16; + hotspotX = 0; + hotspotY = 0; + color[] = {0.8,0.8,0.8,1}; + shadow = 0; + }; + class Debug: Arrow + { + color[] = {1.0,1.0,0.7,1}; + shadow = 0; + }; + class Track + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.7,0.1,0.0,1}; + shadow = 0; + }; + class Move + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.0,0.6,0.0,1}; + shadow = 0; + }; + class Scroll + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.8,0.6,0.0,1}; + shadow = 0; + }; + class Rotate + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.1,0.1,0.9,1}; + shadow = 0; + }; + class Track3D + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.7,0.1,0.0,1}; + shadow = 0; + }; + class Move3D + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.0,0.6,0.0,1}; + shadow = 0; + }; + class Rotate3D + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.1,0.1,0.9,1}; + shadow = 0; + }; + class Raise3D + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0,0.8,1,1}; + shadow = 0; + }; + class Wait + { + texture = "#(argb,32,32,1)color(1,1,1,1)"; + width = 24; + height = 24; + hotspotX = 0.5; + hotspotY = 0.5; + color[] = {0.1,0.1,0.9,1}; + shadow = 0; + }; + }; }; \ No newline at end of file diff --git a/JM/CF/GUI/layouts/debug/debugui.layout b/JM/CF/GUI/layouts/debug/debugui.layout new file mode 100644 index 00000000..6c5a51ff --- /dev/null +++ b/JM/CF/GUI/layouts/debug/debugui.layout @@ -0,0 +1,81 @@ +WrapSpacerWidgetClass BlockSpacer { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_WrapSpacerWidget" + Padding 0 + Margin 0 + { + ScrollWidgetClass scroller { + ignorepointer 0 + position 0 0 + size 1 1 + valign bottom_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_ScrollWidget" + style blank + "Scrollbar V" 1 + "Scrollbar V Left" 0 + { + MultilineTextWidgetClass TextField { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_MultilineTextWidget" + text "AAA" + font "gui/fonts/system" + "exact text" 1 + "size to text h" 1 + "size to text v" 1 + { + ScriptParamsClass { + Text "m_Data" + } + } + } + } + { + ScriptParamsClass { + Visible "m_ViewInWorld:CF_TypeConverter_BoolInvert" + } + } + } + MultilineTextWidgetClass TextFieldLocked { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_MultilineTextWidget" + text "AAA" + font "gui/fonts/system" + "exact text" 1 + "size to text h" 1 + "size to text v" 1 + { + ScriptParamsClass { + Visible "m_ViewInWorld" + Text "m_Data" + } + } + } + } + { + ScriptParamsClass { + Model "CF_DebugUI" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/debug/entry.layout b/JM/CF/GUI/layouts/debug/entry.layout new file mode 100644 index 00000000..bea5d055 --- /dev/null +++ b/JM/CF/GUI/layouts/debug/entry.layout @@ -0,0 +1,53 @@ +PanelWidgetClass cf_debug_entry { + ignorepointer 1 + color 0.2941 0.2941 0.2941 0.5529 + position 0 0 + size 1 20 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_PanelWidget" + style DayZDefaultPanel + { + TextWidgetClass cf_debug_entry_name { + ignorepointer 1 + position 0 0 + size 1 1 + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_TextWidget" + { + ScriptParamsClass { + Text "m_Name" + } + } + } + CheckBoxWidgetClass cf_debug_entry_toggle_ui { + size 200 1 + halign right_ref + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 1 + vexactsize 0 + scriptclass "CF_CheckBoxWidget" + style Default + text "Window" + { + ScriptParamsClass { + Event_Change "Event_ToggleWindow" + Checked "m_UI" + } + } + } + } + { + ScriptParamsClass { + Model "CF_Debug" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/debug/panel.layout b/JM/CF/GUI/layouts/debug/panel.layout new file mode 100644 index 00000000..4ada75b4 --- /dev/null +++ b/JM/CF/GUI/layouts/debug/panel.layout @@ -0,0 +1,99 @@ +WrapSpacerWidgetClass cf_debug_panel { + ignorepointer 1 + color 0.1922 0.1922 0.1922 0.2471 + position 0 0 + size 400 1 + hexactpos 1 + vexactpos 0 + hexactsize 1 + vexactsize 0 + scriptclass "CF_ScrollWidget" + style DayZDefaultPanel + content_halign center + { + PanelWidgetClass cf_debug_title_panel { + ignorepointer 1 + color 0.2549 0.2549 0.2549 0.4 + position 0 0 + size 1 40 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + style rover_sim_colorable + { + TextWidgetClass cf_debug_title { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + style Normal + text "Debug" + font "gui/fonts/Metron-Bold" + "exact text" 1 + "text halign" center + "text valign" center + } + CheckBoxWidgetClass cf_debug_cursor_toggle { + clipchildren 0 + size 0.204 0.98 + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + fixaspect fixwidth + scriptclass "CF_CheckBoxWidget" + { + ScriptParamsClass { + Event_Change "Event_ToggleCursor" + Enabled "m_CanChangeInputState" + Text "m_InputCombo" + Checked "m_InputState" + } + } + } + } + } + ScrollWidgetClass cf_debug_scroll { + ignorepointer 0 + size 0.95 1 + halign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + style blank + "Scrollbar V" 1 + { + WrapSpacerWidgetClass cf_debug_entries { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_WrapSpacerWidget" + Padding 3 + Margin 3 + "Size To Content V" 1 + content_halign center + { + ScriptParamsClass { + Children "m_Instances" + } + } + } + } + } + } + { + ScriptParamsClass { + Model "CF_DebugManager" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/mvvm/dropdown.layout b/JM/CF/GUI/layouts/mvvm/dropdown.layout new file mode 100644 index 00000000..17949d90 --- /dev/null +++ b/JM/CF/GUI/layouts/mvvm/dropdown.layout @@ -0,0 +1,24 @@ +FrameWidgetClass rootFrame { + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + { + VideoWidgetClass XComboBoxWidget0 { + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_VideoWidget" + video "test.mp4" + { + ScriptParamsClass { + } + } + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/mvvm/dropdowntext.layout b/JM/CF/GUI/layouts/mvvm/dropdowntext.layout new file mode 100644 index 00000000..e69de29b diff --git a/JM/CF/GUI/layouts/mvvm/test.layout b/JM/CF/GUI/layouts/mvvm/test.layout new file mode 100644 index 00000000..cb0657a8 --- /dev/null +++ b/JM/CF/GUI/layouts/mvvm/test.layout @@ -0,0 +1,123 @@ +WrapSpacerWidgetClass root { + keepsafezone 0 + color 0.8745 0.6549 0.8196 1 + position 0 0 + size 1 1 + halign center_ref + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 0 + scriptclass "CF_WrapSpacerWidget" + style Colorable + { + GridSpacerWidgetClass GridSpacerWidget1 { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + "Size To Content H" 1 + "Size To Content V" 1 + Columns 2 + Rows 2 + { + CheckBoxWidgetClass CheckBoxWidget0 { + position 0 0 + size 0.5 50 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_CheckBoxWidget" + { + ScriptParamsClass { + Event_Change "OnCheckboxChange" + Text "TextInput" + Checked "BlockInput" + } + } + } + CheckBoxWidgetClass CheckBoxWidget1 { + position 0 0 + size 0.5 50 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_CheckBoxWidget" + { + ScriptParamsClass { + Event_Change "OnCheckboxChange" + Text "TextInput" + Checked "BlockInput:CF_TypeConverter_BoolInvert" + } + } + } + EditBoxWidgetClass EditBoxWidget0 { + position 0 0 + size 0.5 50 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_EditBoxWidget" + { + ScriptParamsClass { + Event_Change "OnChange" + Text "TextInput" + } + } + } + ButtonWidgetClass button { + position 0 0 + size 0.5 40 + halign center_ref + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_ButtonWidget" + "no focus" 1 + text "Toggle" + font "gui/fonts/Metron-Bold28" + switch toggle + { + ScriptParamsClass { + Event_Click "OnClick" + Text "ButtonText" + } + } + } + } + } + GridSpacerWidgetClass GridSpacerWidget0 { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_GridSpacerWidget" + "Size To Content H" 1 + "Size To Content V" 1 + Columns 1 + Rows 100 + { + ScriptParamsClass { + Children "Test" + } + } + } + } + { + ScriptParamsClass { + Model "CF_TestModel" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/mvvm/testitem.layout b/JM/CF/GUI/layouts/mvvm/testitem.layout new file mode 100644 index 00000000..af963cd2 --- /dev/null +++ b/JM/CF/GUI/layouts/mvvm/testitem.layout @@ -0,0 +1,40 @@ +PanelWidgetClass root { + color 0.8745 0.6549 0.8196 1 + position 0 0 + size 1 25 + halign center_ref + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_PanelWidget" + { + ButtonWidgetClass button { + position 0 0 + size 1 1 + halign center_ref + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 0 + scriptclass "CF_ButtonWidget" + "no focus" 1 + text "Toggle" + font "gui/fonts/Metron-Bold28" + switch toggle + { + ScriptParamsClass { + Event_Click "Remove" + Text "ButtonText" + } + } + } + } + { + ScriptParamsClass { + Model "CF_Model_Test2" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/popups/dropdown.layout b/JM/CF/GUI/layouts/popups/dropdown.layout new file mode 100644 index 00000000..90fc6572 --- /dev/null +++ b/JM/CF/GUI/layouts/popups/dropdown.layout @@ -0,0 +1,48 @@ +PanelWidgetClass dropdown { + position 0 0 + size 1 1 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_PanelWidget" + style blank + { + FrameWidgetClass dropdown_selected_element { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_FrameWidget" + { + ScriptParamsClass { + SubModel "m_Selected" + } + } + } + ButtonWidgetClass dropdown_popup_toggle { + position 0 0 + size 1 1 + halign right_ref + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + fixaspect fixwidth + scriptclass "CF_ButtonWidget" + { + ScriptParamsClass { + Event_Click "OnToggle" + } + } + } + } + { + ScriptParamsClass { + Model "CF_Dropdown" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/popups/dropdown_element.layout b/JM/CF/GUI/layouts/popups/dropdown_element.layout new file mode 100644 index 00000000..ef9ec6c8 --- /dev/null +++ b/JM/CF/GUI/layouts/popups/dropdown_element.layout @@ -0,0 +1,16 @@ +TextWidgetClass dropdown_element { + position 0 0 + size 1 30 + vexactpos 0 + hexactsize 0 + vexactsize 1 + scriptclass "CF_TextWidget" + style Normal + font "gui/fonts/Metron12" + { + ScriptParamsClass { + Model "CF_DropdownElementBase" + Text "m_Data" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/popups/dropdown_popup.layout b/JM/CF/GUI/layouts/popups/dropdown_popup.layout new file mode 100644 index 00000000..633adcae --- /dev/null +++ b/JM/CF/GUI/layouts/popups/dropdown_popup.layout @@ -0,0 +1,15 @@ +ScrollWidgetClass dropdown_popup { + position 0 0 + size 400 400 + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + scriptclass "CF_ScrollWidget" + style blank + { + ScriptParamsClass { + Children "m_Elements" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/windows/button.layout b/JM/CF/GUI/layouts/windows/button.layout new file mode 100644 index 00000000..9ab63666 --- /dev/null +++ b/JM/CF/GUI/layouts/windows/button.layout @@ -0,0 +1,42 @@ +ButtonWidgetClass cf_window_button { + visible 1 + ignorepointer 0 + color 1 0 0 1 + position 30 1 + size 25 25 + halign right_ref + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + scriptclass "CF_ButtonWidget" + style Default + { + ImageWidgetClass cf_window_button_image { + ignorepointer 1 + position 0 0 + size 0.8 0.8 + halign center_ref + valign center_ref + hexactsize 0 + vexactsize 0 + image0 "set:cf_imageset image:fullscreen_white" + mode additive + "src alpha" 1 + scriptclass "CF_ImageWidget" + { + ScriptParamsClass { + File "m_Image" + } + } + } + } + { + ScriptParamsClass { + Model "CF_WindowButton" + Event_Click "OnClickButton" + Visible "m_IsVisible" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/windows/container.layout b/JM/CF/GUI/layouts/windows/container.layout new file mode 100644 index 00000000..b87c6dc9 --- /dev/null +++ b/JM/CF/GUI/layouts/windows/container.layout @@ -0,0 +1,13 @@ +PanelWidgetClass windows_container { + ignorepointer 1 + visible 1 + color 0 0 0 0 + position 0 0 + size 1 1 + halign left_ref + valign top_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 +} \ No newline at end of file diff --git a/JM/CF/GUI/layouts/windows/window.layout b/JM/CF/GUI/layouts/windows/window.layout new file mode 100644 index 00000000..49a2f492 --- /dev/null +++ b/JM/CF/GUI/layouts/windows/window.layout @@ -0,0 +1,505 @@ +PanelWidgetClass cf_window { + visible 1 + ignorepointer 1 + size 400 400 + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + scriptclass "CF_PanelWidget" + style Outline + { + PanelWidgetClass cf_window_background { + visible 1 + ignorepointer 0 + color 0.06 0.08 0.11 0.8 + position 0 0 + size 1 1 + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 0 + style rover_sim_colorable + } + PanelWidgetClass cf_window_client { + visible 1 + ignorepointer 0 + color 0 0 0 0 + position 0 27 + size 396 398 + halign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + scriptclass "CF_PanelWidget" + { + ScriptParamsClass { + Width "m_ContentWidth" + Height "m_ContentHeight" + } + } + } + PanelWidgetClass cf_window_titlebar_dragger { + visible 1 + ignorepointer 0 + color 0 0 0 0 + position 0 0 + size 1 25 + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 1 + draggable 1 + scriptclass "CF_PanelWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_Drag "OnDrag" + Event_Dragging "OnDragging" + Event_Drop "OnDragging" + } + } + } + PanelWidgetClass cf_window_titlebar { + visible 1 + ignorepointer 1 + color 0.0196 0.0196 0.0196 1 + position 0 2 + size 396 25 + halign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 0 + scriptclass "CF_Widget" + style rover_sim_colorable + { + WrapSpacerWidgetClass cf_window_titlebar_right_buttons { + ignorepointer 1 + size 1 1 + halign right_ref + valign center_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_PanelWidget" + Padding 0 + Margin 0 + "Size To Content H" 1 + content_halign right + content_valign center + { + ScriptParamsClass { + Children "m_TitleBarButtons" + } + } + } + PanelWidgetClass cf_window_titlebar_text_container { + ignorepointer 1 + position 0 0 + size 1 1 + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 0 + { + TextWidgetClass cf_window_titlebar_text { + ignorepointer 1 + color 1 1 1 1 + position 2 0 + size 1 1 + halign left_ref + valign center_ref + hexactpos 1 + vexactpos 0 + hexactsize 0 + vexactsize 0 + scriptclass "CF_TextWidget" + style Normal + text "Placeholder Title" + font "gui/fonts/sdf_MetronLight24" + "exact text" 1 + "exact text size" 18 + "text halign" left + "text valign" center + { + ScriptParamsClass { + Text "m_Title" + } + } + } + } + } + } + { + ScriptParamsClass { + Width "m_ContentWidth" + } + } + } + PanelWidgetClass cf_window_border_drag_up { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 1 3 + halign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderUp" + Event_MouseLeave "OnMouseBorderUp" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingUp" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_down { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 1 3 + halign center_ref + valign bottom_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderDown" + Event_MouseLeave "OnMouseBorderDown" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingDown" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_left { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 1 + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 0 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderLeft" + Event_MouseLeave "OnMouseBorderLeft" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingLeft" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_right { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 1 + halign right_ref + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 0 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderRight" + Event_MouseLeave "OnMouseBorderRight" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingRight" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_up_left { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 3 + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderUpLeft" + Event_MouseLeave "OnMouseBorderUpLeft" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingUpLeft" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_up_right { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 3 + halign right_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderUpRight" + Event_MouseLeave "OnMouseBorderUpRight" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingUpRight" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_down_left { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 3 + valign bottom_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderDownLeft" + Event_MouseLeave "OnMouseBorderDownLeft" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingDownLeft" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_drag_down_right { + visible 0 + ignorepointer 0 + color 0 0 0 0 + size 3 3 + halign right_ref + valign bottom_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_ButtonWidget" + style rover_sim_colorable + { + ScriptParamsClass { + Event_MouseEnter "OnMouseBorderDownRight" + Event_MouseLeave "OnMouseBorderDownRight" + Event_Drag "OnStartResizing" + Event_Dragging "OnResizingDownRight" + Event_Drop "OnStopResizing" + Visible "m_State:CF_TypeConverter_BoolInvert" + } + } + } + PanelWidgetClass cf_window_border_up { + ignorepointer 1 + color 1 0 1 1 + size 1 3 + halign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 0 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderUColor" + } + } + } + PanelWidgetClass cf_window_border_down { + ignorepointer 1 + color 1 0 1 1 + size 1 3 + halign center_ref + valign bottom_ref + hexactpos 0 + vexactpos 0 + hexactsize 0 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderDColor" + } + } + } + PanelWidgetClass cf_window_border_left { + ignorepointer 1 + color 1 0 1 1 + size 3 1 + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 0 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderLColor" + } + } + } + PanelWidgetClass cf_window_border_right { + ignorepointer 1 + color 1 0 1 1 + size 3 1 + halign right_ref + valign center_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 0 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderRColor" + } + } + } + PanelWidgetClass cf_window_border_up_left { + ignorepointer 1 + color 1 0 1 1 + size 8 8 + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderULColor" + } + } + } + PanelWidgetClass cf_window_border_up_right { + ignorepointer 1 + color 1 0 1 1 + size 8 8 + halign right_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderURColor" + } + } + } + PanelWidgetClass cf_window_border_down_left { + ignorepointer 1 + color 1 0 1 1 + size 8 8 + valign bottom_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderDLColor" + } + } + } + PanelWidgetClass cf_window_border_down_right { + ignorepointer 1 + color 1 0 1 1 + size 8 8 + halign right_ref + valign bottom_ref + hexactpos 1 + vexactpos 1 + hexactsize 1 + vexactsize 1 + draggable 1 + scriptclass "CF_Widget" + style rover_sim_colorable + { + ScriptParamsClass { + Visible "m_State:CF_TypeConverter_BoolInvert" + Color "m_BorderDRColor" + } + } + } + } + { + ScriptParamsClass { + Model "CF_Window" + Event_MouseButtonDown "OnMouseButtonDown" + Event_Update "OnUpdate" + Visible "m_Visible" + Sort "m_Sort" + PositionX "m_PositionX" + PositionY "m_PositionY" + Width "m_Width" + Height "m_Height" + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/textures/arrow_raw.paa b/JM/CF/GUI/textures/arrow_raw.paa new file mode 100644 index 00000000..a224886d Binary files /dev/null and b/JM/CF/GUI/textures/arrow_raw.paa differ diff --git a/JM/CF/GUI/textures/imageset.edds b/JM/CF/GUI/textures/imageset.edds new file mode 100644 index 00000000..21377ce8 Binary files /dev/null and b/JM/CF/GUI/textures/imageset.edds differ diff --git a/JM/CF/GUI/textures/imageset.edds.meta b/JM/CF/GUI/textures/imageset.edds.meta new file mode 100644 index 00000000..6d2da517 --- /dev/null +++ b/JM/CF/GUI/textures/imageset.edds.meta @@ -0,0 +1,16 @@ +MetaFileClass { + Name "{3B699C54C62B9938}JM/CF/GUI/textures/imageset.edds" + Author "desktop-o6qatll" + ChangeDate -1341854970 + Configurations { + TGAResourceClass PC { + SourceFile "imageset.tga" + } + TGAResourceClass XBOX_ONE : PC { + } + TGAResourceClass PS4 : PC { + } + TGAResourceClass LINUX : PC { + } + } +} \ No newline at end of file diff --git a/JM/CF/GUI/textures/imageset.imageset b/JM/CF/GUI/textures/imageset.imageset new file mode 100644 index 00000000..260ceb39 --- /dev/null +++ b/JM/CF/GUI/textures/imageset.imageset @@ -0,0 +1,74 @@ +ImageSetClass { + Name "cf_imageset" + RefSize 1024 1024 + Textures { + ImageSetTextureClass { + mpix 1 + path "{3B699C54C62B9938}JM/CF/GUI/textures/imageset.edds" + } + } + Images { + ImageSetDefClass close_black { + Name "close_black" + Pos 0 0 + Size 25 25 + Flags 0 + } + ImageSetDefClass close_white { + Name "close_white" + Pos 0 25 + Size 25 25 + Flags 0 + } + ImageSetDefClass fullscreen_black { + Name "fullscreen_black" + Pos 25 0 + Size 25 25 + Flags 0 + } + ImageSetDefClass fullscreen_white { + Name "fullscreen_white" + Pos 25 25 + Size 25 25 + Flags 0 + } + ImageSetDefClass window_black { + Name "window_black" + Pos 50 0 + Size 25 25 + Flags 0 + } + ImageSetDefClass window_white { + Name "window_white" + Pos 50 25 + Size 25 25 + Flags 0 + } + ImageSetDefClass minimize_black { + Name "minimize_black" + Pos 75 0 + Size 25 25 + Flags 0 + } + ImageSetDefClass minimize_white { + Name "minimize_white" + Pos 75 25 + Size 25 25 + Flags 0 + } + ImageSetDefClass maximize_black { + Name "maximize_black" + Pos 100 0 + Size 25 25 + Flags 0 + } + ImageSetDefClass maximize_white { + Name "maximize_white" + Pos 100 25 + Size 25 25 + Flags 0 + } + } + Groups { + } +} \ No newline at end of file diff --git a/JM/CF/Scripts/1_Core/CommunityFramework/CF_KeyState.c b/JM/CF/Scripts/1_Core/CommunityFramework/CF_KeyState.c new file mode 100644 index 00000000..fe6e71e1 --- /dev/null +++ b/JM/CF/Scripts/1_Core/CommunityFramework/CF_KeyState.c @@ -0,0 +1,7 @@ +enum CF_KeyState +{ + NONE, + UP, + DOWN, + PRESS +}; \ No newline at end of file diff --git a/JM/CF/Scripts/1_Core/CommunityFramework/CF_String.c b/JM/CF/Scripts/1_Core/CommunityFramework/CF_String.c index 690eb662..73766ff1 100644 --- a/JM/CF/Scripts/1_Core/CommunityFramework/CF_String.c +++ b/JM/CF/Scripts/1_Core/CommunityFramework/CF_String.c @@ -108,14 +108,10 @@ class CF_String : string string PadStringFront(int length, CF_String padChar) { string newString = value; - length = newString.Length() - length; - if (length > 0) + while (newString.Length() < length) { - for (int index = 0; index < length; index++) - { - newString = padChar + newString; - } + newString = padChar + newString; } return newString; diff --git a/JM/CF/Scripts/1_Core/CommunityFramework/TypeConverter/CF_TypeConverter.c b/JM/CF/Scripts/1_Core/CommunityFramework/TypeConverter/CF_TypeConverter.c index 053ad006..f58baf69 100644 --- a/JM/CF/Scripts/1_Core/CommunityFramework/TypeConverter/CF_TypeConverter.c +++ b/JM/CF/Scripts/1_Core/CommunityFramework/TypeConverter/CF_TypeConverter.c @@ -95,7 +95,7 @@ class CF_TypeConverter static CF_TypeConverterBase Get(typename type) { #ifdef CF_TRACE_ENABLED - auto trace = CF_Trace_1("Get").Add(type); + auto trace = CF_Trace_1("CF_TypeConverter", "Get").Add(type); #endif CF_TypeConverterBase converter; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Collection.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Collection.c new file mode 100644 index 00000000..2037c50a --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Collection.c @@ -0,0 +1,38 @@ +class CF_Collection : Managed +{ + protected CF_TypeConverterBase m_Converter; + protected int m_Count; + + void CF_Collection() + { + } + + override string GetDebugName() + { + return "[" + this + "]"; + } + + /* + * @note Returns the same instance of Converter for every index, + * when called in sucession, the value is overwritten + */ + CF_TypeConverterBase GetConverter(int index) + { + return m_Converter; + } + + CF_TypeConverterBase GetConverter() + { + return m_Converter; + } + + void OverrideConverter(CF_TypeConverterBase converter = null) + { + m_Converter = converter; + } + + int Count() + { + return m_Count; + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Map.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Map.c new file mode 100644 index 00000000..35693646 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Map.c @@ -0,0 +1,163 @@ +class CF_Map : CF_Collection +{ + private ref map m_DataMap = new map(); + private ref array m_Keys = new array(); + private ref array m_Values = new array(); + private TValue m_NullValue; + + void CF_Map() + { + #ifdef COMPONENT_SYSTEM + CF_MVVM._CheckInit(); + #endif + + typename t = TValue; + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_0(this, string.Format("CF_Map<%1>", t)); + #endif + + m_Converter = CF_TypeConverter.Get(t); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + Count(); + for (int i = 0; i < Count(); i++) + { + str += " " + m_Keys[i] + ":"; + str += " " + m_Values[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "GetConverter").Add(index); + #endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Values[index]); + return m_Converter; + } + + override int Count() + { + return m_Values.Count(); + } + + TValue Get(TKey key) + { + int index = m_DataMap[key]; + if (!m_DataMap.Find(key, index)) return m_NullValue; + return m_Values[index]; + } + + bool Find(TKey key, out TValue val) + { + int idx; + if (m_DataMap.Find(key, idx)) + { + val = m_Values[idx]; + return true; + } + + return false; + } + + TValue GetElement(int index) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "GetElement").Add(index); + #endif + return m_Values[index]; + } + + TKey GetKey(int i) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "GetKey").Add(i); + #endif + return m_Keys[i]; + } + + void Set(TKey key, TValue value) + { + if (Contains(key)) + { + m_Values[m_DataMap[key]] = value; + } + else + { + int idx = m_Values.Count(); + m_Keys.Insert(key); + m_Values.Insert(value); + m_DataMap.Insert(key, idx); + } + } + + void Remove(TKey key) + { + int index = m_DataMap[key]; + + TKey replaced = m_Keys[m_Keys.Count() - 1]; + + m_Keys.Remove(index); + m_Values.Remove(index); + + m_DataMap.Remove(key); + + if (m_Keys.Count() > 0 && index < m_Keys.Count()) + { + m_DataMap[replaced] = index; + } + } + + void RemoveElement(int index) + { + Remove(GetKey(index)); + } + + bool Contains(TKey key) + { + return m_DataMap.Contains(key); + } + + void Insert(TKey key, TValue value) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "Insert").Add(key).Add(value); + #endif + + Set(key, value); + } + + void Clear() + { + m_Values.Clear(); + m_Keys.Clear(); + m_DataMap.Clear(); + } + + array GetKeyArray() + { + array result(); + result.Resize(m_Keys.Count()); + for (int i = 0; i < m_Keys.Count(); i++) + { + result[i] = m_Keys[i]; + } + return result; + } + + array GetValueArray() + { + array result(); + result.Resize(m_Values.Count()); + for (int i = 0; i < m_Values.Count(); i++) + { + result[i] = m_Values[i]; + } + return result; + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_PriorityQueue.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_PriorityQueue.c new file mode 100644 index 00000000..d2d4b140 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_PriorityQueue.c @@ -0,0 +1,59 @@ +class CF_PriorityQueue : CF_Collection +{ + protected ref Param2 m_Data[256]; + + void CF_PriorityQueue() + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Count; + for (int i = 0; i < m_Count; i++) + { + str += " " + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "GetConverter").Add(index); + #endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + void Enqueue(T item, Comparable priority) + { + m_Data[m_Count] = new Param2(item, priority); + m_Count++; + } + + T Dequeue() + { + int bestIndex = 0; + + for (int i = 0; i < m_Count; i++) + { + if (m_Data[i].param2 < m_Data[bestIndex].param2) + { + bestIndex = i; + } + } + + T bestItem = m_Data[bestIndex].param1; + + m_Count--; + + m_Data[bestIndex] = m_Data[m_Count]; + m_Data[m_Count] = null; + + return bestItem; + } +} \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Stack.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Stack.c new file mode 100644 index 00000000..f774e47f --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/CF_Stack.c @@ -0,0 +1,90 @@ +class CF_Stack : CF_Collection +{ + private T m_Data[256]; + + void CF_Stack() + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Count; + for (int i = 0; i < m_Count; i++) + { + str += " " + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { + #ifdef CF_TRACE_ENABLED + auto trace = CF_Trace_1(this, "GetConverter").Add(index); + #endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + T Pop() + { + T value; + + if (m_Count <= 0) + { + m_Count = 0; + } + else + { + value = m_Data[m_Count - 1]; + m_Count--; + } + + return value; + } + + T Peek() + { + return m_Data[m_Count - 1]; + } + + T Push(T value) + { + m_Data[m_Count] = value; + + m_Count++; + + return value; + } + + array ToArray() + { + array arr = new array(); + for (int i = 0; i < m_Count; i++) + arr.Insert(m_Data[i]); + return arr; + } + + void Clear() + { + m_Count = 0; + } + + T Get(int index) + { + return m_Data[index]; + } + + void Set(int index, T value) + { + m_Data[index] = value; + } + + override int Count() + { + return m_Count; + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionClearEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionClearEventArgs.c new file mode 100644 index 00000000..cd621b9f --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionClearEventArgs.c @@ -0,0 +1,12 @@ +class CF_CollectionClearEventArgs : CF_CollectionEventArgs +{ + void CF_CollectionClearEventArgs() + { + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionEventArgs.c new file mode 100644 index 00000000..5ca4d62d --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionEventArgs.c @@ -0,0 +1,8 @@ +class CF_CollectionEventArgs : CF_EventArgs +{ + override string GetDebugName() + { + string str = super.GetDebugName(); + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertAtEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertAtEventArgs.c new file mode 100644 index 00000000..876589b4 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertAtEventArgs.c @@ -0,0 +1,16 @@ +class CF_CollectionInsertAtEventArgs : CF_CollectionEventArgs +{ + int Index; + + void CF_CollectionInsertAtEventArgs(int index) + { + Index = index; + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Index=" + Index; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertEventArgs.c new file mode 100644 index 00000000..a034c7b8 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionInsertEventArgs.c @@ -0,0 +1,16 @@ +class CF_CollectionInsertEventArgs : CF_CollectionEventArgs +{ + int Index; + + void CF_CollectionInsertEventArgs(int index) + { + Index = index; + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Index=" + Index; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionRemoveEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionRemoveEventArgs.c new file mode 100644 index 00000000..94d3d237 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionRemoveEventArgs.c @@ -0,0 +1,16 @@ +class CF_CollectionRemoveEventArgs : CF_CollectionEventArgs +{ + int Index; + + void CF_CollectionRemoveEventArgs(int index) + { + Index = index; + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Index=" + Index; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSetEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSetEventArgs.c new file mode 100644 index 00000000..8e8e9c86 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSetEventArgs.c @@ -0,0 +1,16 @@ +class CF_CollectionSetEventArgs : CF_CollectionEventArgs +{ + int Index; + + void CF_CollectionSetEventArgs(int index) + { + Index = index; + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Index=" + Index; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSwapEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSwapEventArgs.c new file mode 100644 index 00000000..e28d87a9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/EventArgs/CF_CollectionSwapEventArgs.c @@ -0,0 +1,26 @@ +class CF_CollectionSwapEventArgs : CF_CollectionEventArgs +{ + int IndexA; + int IndexB; + + void CF_CollectionSwapEventArgs(int indexa, int indexb) + { + IndexA = indexa; + IndexB = indexb; + + if (IndexA > IndexB) + { + int temp = IndexA; + IndexA = IndexB; + IndexB = temp; + } + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " IndexA=" + IndexA; + str += " IndexB=" + IndexB; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/Stack.c b/JM/CF/Scripts/3_Game/CommunityFramework/Collections/Stack.c deleted file mode 100644 index ee743406..00000000 --- a/JM/CF/Scripts/3_Game/CommunityFramework/Collections/Stack.c +++ /dev/null @@ -1,69 +0,0 @@ -/* TODO: Move to Community Framework */ - -class __Stack -{ - private T _data[256]; - private int _count; - - void __Stack() - { - } - - T Pop() - { - T value; - - if ( _count <= 0 ) - { - _count = 0; - } else - { - value = _data[ _count - 1 ]; - _count--; - } - - return value; - } - - T Peek() - { - return _data[ _count - 1 ]; - } - - T Push( T value ) - { - _data[ _count ] = value; - - _count++; - - return value; - } - - array ToArray() - { - array arr = new array(); - for ( int i = 0; i < _count; i++ ) - arr.Insert(_data[i]); - return arr; - } - - void Clear() - { - _count = 0; - } - - T Get( int idx ) - { - return _data[idx]; - } - - void Set( int idx, T value ) - { - _data[idx] = value; - } - - int Count() - { - return _count; - } -}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/CommunityFramework.c b/JM/CF/Scripts/3_Game/CommunityFramework/CommunityFramework.c index e372468f..52a2f9c3 100644 --- a/JM/CF/Scripts/3_Game/CommunityFramework/CommunityFramework.c +++ b/JM/CF/Scripts/3_Game/CommunityFramework/CommunityFramework.c @@ -4,7 +4,6 @@ CGame CF_CreateGame() CreateGame(); CF._GameInit(); - return g_Game; } @@ -14,15 +13,49 @@ class CommunityFramework : ModStructure static CF_ObjectManager ObjectManager; static CF_XML XML; + static DayZGame Game() + { + #ifdef COMPONENT_SYSTEM + if (!g_Game) + { + CF_TypeConverterConstructor._Cleanup(); + CF_TypeConverterConstructor._Init(); + + CF_MVVM._Init(); + + #ifdef CF_WINDOWS + CF_Windows._Init(); + #endif + + CF_CreateGame(); + } + #endif + + return g_Game; + } + /** * @brief [Internal] CommunityFramework initilization for 3_Game * * @return void */ - static void _GameInit() + static void _GameInit(bool realInit = false) { + if (!realInit) Game(); + + CF_Windows._Init(); } + static void _MissionInit() + { + CF_Windows._MissionInit(); + } + + static void _MissionCleanup() + { + CF_Windows._MissionCleanup(); + } + /** * @brief [Internal] CommunityFramework cleanup * @@ -32,6 +65,17 @@ class CommunityFramework : ModStructure { ObjectManager._Cleanup(); XML._Cleanup(); + + CF_Windows._Cleanup(); + } + + static bool StringToBool(string str) + { + str.ToLower(); + str.Trim(); + if (str == "true") return true; + if (str == "false") return false; + return str.ToInt(); } /** @@ -67,7 +111,6 @@ class CommunityFramework : ModStructure class JM_CommunityFramework : CommunityFramework { - }; //-------------------------------------------------------- diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_Debug.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_Debug.c new file mode 100644 index 00000000..5ef67c32 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_Debug.c @@ -0,0 +1,427 @@ +class CF_Debug : CF_TimerBase +{ + static ref CF_DebugUI_Type s_Types; + + private static ref CF_DebugManager s_Manager; + + [CF_EventSubscriber(CF_Debug._Init, CF_LifecycleEvents.OnGameCreate)] + static void _Init() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0("CF_Debug", "_Init"); +#endif + + s_Types = new CF_DebugUI_Type(); + s_Manager = new CF_DebugManager(); + + SetAllowed(false); + } + + [CF_EventSubscriber(CF_Debug._Cleanup, CF_LifecycleEvents.OnGameDestroy)] + static void _Cleanup() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0("CF_Debug", "_Cleanup"); +#endif + + s_Types = null; + s_Manager = null; + } + + [CF_EventSubscriber(CF_Debug._MissionCleanup, CF_LifecycleEvents.OnMissionDestroy)] + static void _MissionCleanup() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0("CF_Debug", "_MissionCleanup"); +#endif + + SetAllowed(false); + } + + static Widget ShowManager(Widget parent = null) + { + return s_Manager.Open(parent); + } + + static void CloseManager() + { + s_Manager.Close(); + } + + static bool IsAllowed() + { + return s_Manager.IsAllowed(); + } + + static void SetAllowed(bool newState) + { + s_Manager.SetAllowed(newState); + } + + static void Create(Class instance, string title = "##") + { + s_Manager.Create(instance, title); + } + + static void Destroy(Class instance) + { + s_Manager.Destroy(instance); + } + + protected ref array m_Outputs = new array(); + + protected Class m_Instance; + protected string m_Name; + protected vector m_Position; + protected bool m_ViewInWorld; + protected bool m_CanViewInWorld; + + protected Class m_CurrentInstance; + + protected CF_DebugUI m_UI; + + /*private*/ void CF_Debug(Class instance, string name) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "CF_Debug"); +#endif + + m_Instance = instance; + SetName(name); + } + + void ~CF_Debug() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "~CF_Debug"); +#endif + } + + void SetName(string name) + { + m_Name = name; + + foreach (auto output : m_Outputs) + { + output.SetName(name); + } + + CF_MVVM.NotifyPropertyChanged(this, "m_Name"); + } + + string GetName() + { + return m_Name; + } + + /** + * @brief Sets the position within the world - always rotated to face the screen + * + * @note If attached root instance is an Entity, the position is in model space. Otherwise it is in world space. + */ + void SetPosition(vector value) + { + if (m_CurrentInstance != m_Instance) + return; + + m_CanViewInWorld = true; + + m_Position = value; + } + + vector GetPosition() + { + return m_Position; + } + + /** + * @brief Sets if the window should be viewed within the world + */ + void SetViewInWorld(bool viewInWorld) + { + m_ViewInWorld = viewInWorld; + } + + /** + * @brief Sets if the window can be viewed within the world + */ + void SetCanViewInWorld(bool canViewInWorld) + { + m_CanViewInWorld = canViewInWorld; + } + + /** + * @brief Return if the window can be viewed within the world + */ + bool CanViewInWorld() + { + return m_CanViewInWorld && m_ViewInWorld; + } + + /** + * @brief Return the owning instance of the debug + */ + Class GetInstance() + { + return m_Instance; + } + + void Add(string value) + { + foreach (auto output : m_Outputs) + { + output.Add(value); + } + } + + void Add(string name, int value) + { + foreach (auto output : m_Outputs) + { + output.Add(name, value); + } + } + + void Add(string name, bool value) + { + foreach (auto output : m_Outputs) + { + output.Add(name, value); + } + } + + void Add(string name, float value) + { + foreach (auto output : m_Outputs) + { + output.Add(name, value); + } + } + + void Add(string name, vector value) + { + foreach (auto output : m_Outputs) + { + output.Add(name, value); + } + } + + void Add(string name, string value) + { + foreach (auto output : m_Outputs) + { + output.Add(name, value); + } + } + + void ResetBuffer() + { + foreach (auto output : m_Outputs) + { + output.ResetBuffer(); + } + } + + void PushBuffer() + { + foreach (auto output : m_Outputs) + { + output.PushBuffer(); + } + } + + void IncrementTab() + { + foreach (auto output : m_Outputs) + { + output.IncrementTab(); + } + } + + void DecrementTab() + { + foreach (auto output : m_Outputs) + { + output.DecrementTab(); + } + } + + void Add(string name, int value, typename type) + { + Add(name, typename.EnumToString(type, value)); + } + + void Add(string name, int value, array values) + { + string vName = "INVALID"; + if (value >= 0 && value < values.Count()) + { + vName = values[value]; + } + + Add(name, vName); + } + + void Add(string name, Class value) + { + string _value = "" + value; + + Object obj; + if (Class.CastTo(obj, value)) + { + _value += "(" + obj.GetNetworkIDString() + ")"; + } + + Add(name, _value); + } + + /** + * @brief Calls the 'CF_DebugUI' method for the target Class, 'CF_DebugUI' must return true. + */ + void Add(Class value) + { + bool incremented; + + Class previous = m_CurrentInstance; + m_CurrentInstance = value; + + if (value != m_Instance) + { + incremented = true; + IncrementTab(); + Add("this", value); + } + + if (value) + { + IncrementTab(); + + bool functionCallSuccess = false; + functionCallSuccess = GetGame().GameScript.CallFunctionParams(value, "CF_OnDebugUpdate", functionCallSuccess, new Param2(this, CF_Debug.s_Types)); + + if (!functionCallSuccess) + { + typename type = value.Type(); + int count = type.GetVariableCount(); + for (int i = 0; i < count; i++) + { + string variableName = type.GetVariableName(i); + typename variableType = type.GetVariableType(i); + + CF_TypeConverterBase converter = CF_TypeConverter.Get(variableType); + if (converter.Read(value, i)) + { + Add(variableName, converter.GetString()); + } + } + } + + DecrementTab(); + } + + if (incremented) + { + DecrementTab(); + } + + m_CurrentInstance = previous; + } + + protected override void OnTick(float dt) + { + ResetBuffer(); + + Add(m_Instance); + + PushBuffer(); + } + + protected override void OnStart() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "OnStart"); +#endif + + super.OnStart(); + + CF_MVVM.NotifyPropertyChanged(this, "m_IsActive"); + } + + protected override void OnStop() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "OnStop"); +#endif + + super.OnStop(); + + CF_MVVM.NotifyPropertyChanged(this, "m_IsActive"); + } + + string GetLayoutFile() + { + return "JM/CF/GUI/layouts/debug/entry.layout"; + } + + void ShowWindow() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "ShowWindow"); +#endif + + if (m_UI) + { + return; + } + + Start(); + + CF_DebugUI ui = new CF_DebugUI(this, GetName()); + m_UI = ui; + m_Outputs.Insert(ui); + + CF_MVVM.NotifyPropertyChanged(this, "m_UI"); + } + + void CloseWindow() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "CloseWindow"); +#endif + + m_Outputs.RemoveItemUnOrdered(m_UI); + m_UI = null; + + CF_MVVM.NotifyPropertyChanged(this, "m_UI"); + + if (m_Outputs.Count() == 0) + { + Stop(); + } + } + + void Event_ToggleWindow(CF_ModelBase sender, CF_ChangeEventArgs args) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "Event_ToggleWindow").Add(sender).Add(args); +#endif + + if (m_UI) + { + CloseWindow(); + } + else + { + ShowWindow(); + } + } + + void Event_CloseWindow(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "Event_ToggleWindow").Add(sender).Add(args); +#endif + + CloseWindow(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugManager.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugManager.c new file mode 100644 index 00000000..89835ae9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugManager.c @@ -0,0 +1,128 @@ +class CF_DebugManager : CF_Model +{ + private autoptr CF_Map m_Instances; + private bool m_Allowed; + + private string m_InputCombo; + private bool m_InputState; + private bool m_CanChangeInputState; + + void CF_DebugManager() + { + m_Instances = new CF_Map(); + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/debug/panel.layout"; + } + + Widget Open(Widget parent) + { + auto vm = CF_MVVM.Create(this, GetLayoutFile(), parent); + UpdateInputState(); + return vm.GetWidget(); + } + + void Close() + { + CF_MVVM.Destroy(this); + } + + bool IsAllowed() + { + return m_Allowed; + } + + void SetAllowed(bool newState) + { + m_Allowed = newState; + } + + void Create(Class instance, string title = "##") + { + if (!m_Allowed || !instance) + return; + + title = ConvertTitle(instance, title); + + CF_Debug cf_debug; + if (m_Instances.Find(instance, cf_debug)) + { + cf_debug.SetName(title); + return; + } + + cf_debug = new CF_Debug(instance, title); + m_Instances.Insert(instance, cf_debug); + } + + void Destroy(Class instance) + { + m_Instances.Remove(instance); + } + + string ConvertTitle(Class instance, string title) + { + if (title != "##") + return title; + + string hex = "" + instance; + int previousIndex = hex.IndexOf("<"); + int index = -1; + while (previousIndex != -1) + { + index = previousIndex; + hex = hex.Substring(index + 1, hex.Length() - index - 1); + previousIndex = hex.IndexOf("<"); + } + hex = hex.Substring(0, hex.Length() - 1); + + title = instance.ClassName(); + + Object object; + if (Class.CastTo(object, instance)) + { + title = object.GetDisplayName(); + + if (GetGame().IsMultiplayer()) + { + title += " (" + object.GetNetworkIDString() + ")"; + } + } + + title += " (" + hex + ")"; + + return title; + } + + void UpdateInputState() + { + m_CanChangeInputState = CF_Windows.s_Count > 0; + m_InputState = CF_Windows.GetState() == CF_WindowsFocusState.WINDOW; + + m_InputCombo = ""; + UAInput input = CF_Windows.GetInput(); + + input.SelectAlternative(0); + + int count = input.BindKeyCount(); + for (int i = 0; i < count; i++) + { + m_InputCombo += GetUApi().GetButtonName(input.GetBindKey(i)); + if (i < count - 1) + m_InputCombo += " + "; + } + + NotifyPropertyChanged("m_InputCombo"); + NotifyPropertyChanged("m_InputState"); + NotifyPropertyChanged("m_CanChangeInputState"); + } + + void Event_ToggleCursor(CF_ModelBase model, CF_EventArgs args) + { + CF_Windows.FlipState(); + + UpdateInputState(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugOutput.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugOutput.c new file mode 100644 index 00000000..57eede6b --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugOutput.c @@ -0,0 +1,26 @@ +class CF_DebugOutput : CF_Model +{ + void CF_DebugOutput(CF_Debug parent, string name); + + void SetName(string name); + + void Add(string value); + + void Add(string name, int value); + + void Add(string name, bool value); + + void Add(string name, float value); + + void Add(string name, vector value); + + void Add(string name, string value); + + void IncrementTab(); + + void DecrementTab(); + + void ResetBuffer(); + + void PushBuffer(); +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI.c new file mode 100644 index 00000000..eb10609a --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI.c @@ -0,0 +1,184 @@ +class CF_DebugUI : CF_DebugOutput +{ + private CF_Debug m_Parent; + + private string m_Data; + private int m_TabDepth; + + private bool m_ViewInWorld; + private Widget TextFieldLocked; + + private autoptr CF_Window m_Window; + + void CF_DebugUI(CF_Debug parent, string name) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "CF_DebugUI"); +#endif + + m_Parent = parent; + +#ifndef COMPONENT_SYSTEM + m_Window = new CF_Window(name); + m_Window.SetTakesGameFocus(false); + m_Window.CreateWidgets(this, GetLayoutFile()); + + m_Window.OnClose.AddSubscriber(parent.Event_CloseWindow); +#endif + + ResetBuffer(); + +#ifdef COMPONENT_SYSTEM + Add("Hello", "World"); + Add("Item", "Apple"); + Add("X", 5.1); + Add("Y", 2); + Add("Orientation", Vector(0, 5.0, 20.0)); + IncrementTab(); + Add("Items", "START"); + IncrementTab(); + Add("Item", "Orange"); + DecrementTab(); + Add("Items", "END"); + DecrementTab(); + PushBuffer(); +#endif + } + + void ~CF_DebugUI() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "~CF_DebugUI"); +#endif + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/debug/debugui.layout"; + } + + override void SetName(string name) + { + m_Window.SetTitle(name); + } + + /** + * @brief Adds the value to the string. Formatted as "value" + */ + override void Add(string value) + { + m_Data += NewLine() + value; + } + + /** + * @brief Adds the name and value to the string. Formatted as "name: value" + */ + override void Add(string name, int value) + { + m_Data += NewLine() + name + ": " + value; + } + + /** + * @brief Adds the name and value to the string. Formatted as "name: value" + */ + override void Add(string name, bool value) + { + m_Data += NewLine() + name + ": " + value; + } + + /** + * @brief Adds the name and value to the string. Formatted as "name: value" + */ + override void Add(string name, float value) + { + m_Data += NewLine() + name + ": " + value; + } + + /** + * @brief Adds the name and value to the string. Formatted as "name: value" + */ + override void Add(string name, vector value) + { + m_Data += NewLine() + name + ": " + value[0] + ", " + value[1] + ", " + value[2]; + } + + /** + * @brief Adds the name and value to the string. Formatted as "name: value" + */ + override void Add(string name, string value) + { + m_Data += NewLine() + name + ": " + value; + } + + override void IncrementTab() + { + m_TabDepth++; + } + + override void DecrementTab() + { + m_TabDepth--; + } + + override void ResetBuffer() + { + m_Data = string.Empty; + m_TabDepth = 0; + } + + override void PushBuffer() + { + m_ViewInWorld = m_Parent.CanViewInWorld(); + + CF_MVVM.NotifyPropertyChanged(this, "m_Data"); + CF_MVVM.NotifyPropertyChanged(this, "m_ViewInWorld"); + +#ifndef COMPONENT_SYSTEM + if (m_ViewInWorld) + { + vector position = m_Parent.GetPosition(); + + Object obj; + if (Class.CastTo(obj, m_Parent.GetInstance())) + { + position = obj.ModelToWorld(position); + } + + position = GetGame().GetScreenPos(position); + if (position[2] <= 0.0) + { + m_Window.SetVisible(false); + } + else + { + m_Window.SetVisible(true); + } + + m_Window.SetPosition(position[0], position[1]); + + float sizeX, sizeY; + TextFieldLocked.GetScreenSize(sizeX, sizeY); + + m_Window.SetSize(sizeX, sizeY); + } +#endif + } + + private string Tab() + { + string tab = ""; + for (int i = 0; i < m_TabDepth; i++) + { + tab += " "; + } + return tab; + } + + private string NewLine() + { + if (m_Data == string.Empty) + return Tab(); + + return "\n" + Tab(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI_Type.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI_Type.c new file mode 100644 index 00000000..58d5c5c7 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/CF_DebugUI_Type.c @@ -0,0 +1,56 @@ +class CF_DebugUI_Type +{ + private ref map m_Types = new map(); + + void CF_DebugUI_Type() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "CF_DebugUI_Type"); +#endif + + OnRegisterTypes(); + } + + void Register(string type, bool enabled = false) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_1(this, "Get").Add(type).Add(enabled); +#endif + + Set(type, enabled); + } + + void Set(string type, bool enabled) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_1(this, "Get").Add(type).Add(enabled); +#endif + + if (m_Types.Contains(type)) + { + m_Types[type] = enabled; + return; + } + + m_Types.Insert(type, enabled); + } + + bool Get(string type) + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_1(this, "Get").Add(type); +#endif + + if (!m_Types.Contains(type)) + return false; + + return m_Types[type]; + } + + void OnRegisterTypes() + { +#ifdef CF_DEBUG_TRACE + auto trace = CF_Trace_0(this, "OnRegisterTypes"); +#endif + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionBase_Basic.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionBase_Basic.c new file mode 100644 index 00000000..09dd34cc --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionBase_Basic.c @@ -0,0 +1,10 @@ +modded class ActionBase_Basic +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionInput_Basic.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionInput_Basic.c new file mode 100644 index 00000000..4c26a9e9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ActionInput_Basic.c @@ -0,0 +1,10 @@ +modded class ActionInput_Basic +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/DayZGame.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/DayZGame.c new file mode 100644 index 00000000..77c6854a --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/DayZGame.c @@ -0,0 +1,10 @@ +modded class DayZGame +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ModStructure.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ModStructure.c new file mode 100644 index 00000000..d54b719d --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/ModStructure.c @@ -0,0 +1,10 @@ +modded class ModStructure +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayer.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayer.c new file mode 100644 index 00000000..0f82ea77 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayer.c @@ -0,0 +1,10 @@ +modded class SyncPlayer +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayerList.c b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayerList.c new file mode 100644 index 00000000..cb8cfeea --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Debug/Defaults/SyncPlayerList.c @@ -0,0 +1,10 @@ +modded class SyncPlayerList +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_MathExpression.c b/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_MathExpression.c index 27a3d114..568fa25e 100644 --- a/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_MathExpression.c +++ b/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_MathExpression.c @@ -4,7 +4,7 @@ class CF_MathExpression : CF_Expression int __Compile(array variables) { array dataStackStore(); - __Stack stack(); + CF_Stack stack(); CF_ExpressionFunctionDef funcDef; CF_ExpressionCompileToken compileToken; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_SQFExpression.c b/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_SQFExpression.c index d96fc3f2..1c4e541c 100644 --- a/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_SQFExpression.c +++ b/JM/CF/Scripts/3_Game/CommunityFramework/ExpressionVM/CF_SQFExpression.c @@ -3,7 +3,7 @@ class CF_SQFExpression : CF_Expression protected override int _Compile(array variables) { array dataStackStore(); - __Stack stack(); + CF_Stack stack(); ClearInstructions(); diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM.c new file mode 100644 index 00000000..14044404 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM.c @@ -0,0 +1,429 @@ +static autoptr CF_MVVM g_CF_MVVM = null; + +class CF_MVVM +{ + //! Do not directly use this variable, interface with the functions.. + /*private*/ static ref map s_ModelMap; + + static const int MVVM_UI_MENU_ID = 10042; + + static ref array s_Destroying; + +#ifdef COMPONENT_SYSTEM + static bool WB_NEXT_IN_SCRIPT = false; +#endif + + private void CF_MVVM() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "CF_MVVM"); +#endif + } + + [CF_EventSubscriber(CF_MVVM._Init, CF_LifecycleEvents.OnGameCreate)] + static void _Init() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(g_CF_MVVM, "_Init"); +#endif + + if (g_CF_MVVM) + return; + + s_ModelMap = new map(); + s_Destroying = new array(); + +#ifdef COMPONENT_SYSTEM + CF_Log.Level = CF_LogLevel.TRACE; +#endif + + g_CF_MVVM = new CF_MVVM(); + } + + [CF_EventSubscriber(CF_Windows._Cleanup, CF_LifecycleEvents.OnGameDestroy)] + static void _Cleanup() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(g_CF_MVVM, "_Cleanup"); +#endif + + s_ModelMap = null; + s_Destroying = null; + + g_CF_MVVM = null; + } + + static CF_MVVM_Linker GetPropertyCollection(CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "GetPropertyCollection").Add(model); +#endif + + return s_ModelMap[model]; + } + + /** + * @brief Creates a new View for the model. Returns existing view if it already exists for the model + */ + static CF_MVVM_Linker Create(CF_ModelBase model, string layout) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(g_CF_MVVM, "Create").Add(model).Add(layout); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + { + link = new CF_MVVM_Linker(); + s_ModelMap.Insert(model, link); + } + else if (link.IsValid()) + { + link.Relink(); + return link; + } + else + { + link.Unlink(); + } + +#ifdef COMPONENT_SYSTEM + CF_MVVM.WB_NEXT_IN_SCRIPT = true; +#endif + + Widget widget = GetGame().GetWorkspace().CreateWidgets(layout, null); + + if (!widget) + return null; + + CF_ViewModel view; + widget.GetScript(view); + + link.Link(view, model); + +#ifdef COMPONENT_SYSTEM + CF_MVVM.WB_NEXT_IN_SCRIPT = false; +#endif + + return link; + } + + /** + * @brief Creates a new View for the model. Returns existing view if it already exists for the model. Updates the parent widget + */ + static CF_MVVM_Linker Create(CF_ModelBase model, string layout, Widget parent) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_3(g_CF_MVVM, "Create").Add(model).Add(layout).Add(parent); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + { + link = new CF_MVVM_Linker(); + s_ModelMap.Insert(model, link); + } + else if (link.ChangeParent(parent)) + { + link.Relink(); + return link; + } + else + { + link.Unlink(); + } + + WorkspaceWidget wSpace = GetGame().GetWorkspace(); + // A mess to fix an issue in Workbench, can also substitute for loading screen support + if (wSpace == null) + { + wSpace = GetGame().GetLoadingWorkspace(); + if (!wSpace) + wSpace = CF.Game().GetWorkspace(); + if (!wSpace) + wSpace = CF.Game().GetLoadingWorkspace(); + + if (!wSpace) + return null; + } + +#ifdef COMPONENT_SYSTEM + CF_MVVM.WB_NEXT_IN_SCRIPT = true; +#endif + + Widget widget = wSpace.CreateWidgets(layout, parent); + if (!widget) + return null; + + CF_ViewModel view; + widget.GetScript(view); + + link.Link(view, model); + +#ifdef COMPONENT_SYSTEM + CF_MVVM.WB_NEXT_IN_SCRIPT = false; +#endif + + return link; + } + + static CF_MVVM_Linker Connect(CF_ModelBase model, Widget widget) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(g_CF_MVVM, "Connect").Add(model).Add(widget); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + { + link = new CF_MVVM_Linker(); + s_ModelMap.Insert(model, link); + } + +#ifdef COMPONENT_SYSTEM //! Workbench editing + if (!CF_MVVM.WB_NEXT_IN_SCRIPT) + { +#endif + + link.Unlink(); + +#ifdef COMPONENT_SYSTEM //! Workbench editing + } +#endif + + if (!widget) + return null; + + CF_ViewModel view; + widget.GetScript(view); + + link.Link(view, model); + + return link; + } + + static CF_MVVM_Linker Connect(CF_ModelBase model, CF_ViewModel view) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(g_CF_MVVM, "Connect").Add(model).Add(view); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + { + link = new CF_MVVM_Linker(); + s_ModelMap.Insert(model, link); + } + +#ifdef COMPONENT_SYSTEM //! Workbench editing + if (!CF_MVVM.WB_NEXT_IN_SCRIPT) + { +#endif + + link.Unlink(); + +#ifdef COMPONENT_SYSTEM //! Workbench editing + } +#endif + + link.Link(view, model); + + return link; + } + + static CF_ModelBase OpenMenu(string modelName) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "OpenMenu").Add(modelName); +#endif + + CF_ModelBase model = CF_ModelBase.Cast(modelName.ToType().Spawn()); + if (!model) + return null; + + return OpenMenu(model); + } + + static CF_ModelBase OpenMenu(typename modelType) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "OpenMenu").Add(modelType); +#endif + + CF_ModelBase model = CF_ModelBase.Cast(modelType.Spawn()); + if (!model) + return null; + + return OpenMenu(model); + } + + static CF_ModelBase OpenMenu(CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "OpenMenu").Add(model); +#endif + + if (!model) + return null; + + string layoutFile; + g_Script.CallFunction(model, "GetLayoutFile", layoutFile, null); + if (layoutFile == string.Empty) + return null; + + return OpenMenu(model, layoutFile); + } + + static CF_ModelBase OpenMenu(CF_ModelBase model, string layoutFile) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(g_CF_MVVM, "OpenMenu").Add(model).Add(layoutFile); +#endif + + if (!GetGame() || !model) + return null; + + CF_MVVM_Menu menu; + if (!Class.CastTo(menu, GetGame().GetUIManager().EnterScriptedMenu(CF_MVVM.MVVM_UI_MENU_ID, null))) + return null; + + menu.SetModel(model, layoutFile); + + return model; + } + + static void Destroy(CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "Destroy").Add(model); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + return; + + link.Unlink(); + } + + /** + * @note Make sure to call '_UnlockForDestroy' in return Linker + */ + static CF_MVVM_Linker _LockForDestroy(CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "Destroy").Add(model); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker link; + if (!s_ModelMap.Find(model, link)) + return null; + + link._LockForDestroy(); + + return link; + } + +/** + * @brief Fixes issue when script is recompiled while the layout file is opened. + * + * @note To only be using during Workbench editing of layout files. + */ +#ifdef COMPONENT_SYSTEM + static void _CheckInit() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(g_CF_MVVM, "_CheckInit"); +#endif + + if (s_ModelMap == null) + { + CF._GameInit(); + } + } +#endif + + static void NotifyPropertyChanged(CF_ModelBase model, string propertyName, CF_EventArgs args = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(g_CF_MVVM, "NotifyPropertyChanged").Add(model).Add(propertyName).Add(args); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker pc; + if (!s_ModelMap.Find(model, pc)) + return; + + if (args == null) + args = new CF_EventArgs(); + + pc.NotifyPropertyChanged(propertyName, args); + } + + static void NotifyPropertyChanged(CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(g_CF_MVVM, "NotifyPropertyChanged").Add(model); +#endif + +#ifdef COMPONENT_SYSTEM + if (s_ModelMap == null) + { + CF._GameInit(); + } +#endif + + CF_MVVM_Linker pc; + if (!s_ModelMap.Find(model, pc)) + return; + + pc.NotifyPropertyChanged(new CF_EventArgs()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Linker.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Linker.c new file mode 100644 index 00000000..c96643f6 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Linker.c @@ -0,0 +1,357 @@ +typedef array CF_TArrayProperties; + +class CF_MVVM_Linker +{ + ref CF_EventHandler OnDestroy = new CF_EventHandler(); + + autoptr CF_Map m_PropertyVariableMap; + autoptr CF_TArrayProperties m_Properties; + CF_ViewModel m_Root; + + CF_MVVM_Linker m_Parent; + autoptr array m_Children = new array(); + + int m_DestroyLockCount; + bool m_IsBeingDestroyed; + + void CF_MVVM_Linker() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "CF_MVVM_Linker"); +#endif + + m_PropertyVariableMap = new CF_Map(); + m_Properties = new CF_TArrayProperties(); + } + + void ~CF_MVVM_Linker() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "~CF_MVVM_Linker"); +#endif + + if (m_Parent) + { + m_Parent.RemoveChild(this); + } + + OnDestroy.Invoke(this); + } + + /** + * @note: To only be called by CF_ViewModel::NotifyPropertyChanged + */ + void _ViewChanged(string name, CF_MVVM_Property srcProperty, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_3(this, "_ViewChanged").Add(name).Add(srcProperty).Add(args); +#endif + + if (name == string.Empty) + return; + + CF_TArrayProperties properties; + if (!m_PropertyVariableMap.Find(name, properties)) + return; + + foreach (auto property : properties) + { + if (property == srcProperty) + continue; + property.OnModel(args); + } + } + + /** + * @note: To only be called by CF_ViewModel::NotifyPropertyChanged + */ + void _ViewChanged(CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "_ViewChanged").Add(args); +#endif + + for (int j = 0; j < m_PropertyVariableMap.Count(); j++) + { + CF_TArrayProperties properties = m_PropertyVariableMap.GetElement(j); + + foreach (auto property : properties) + { + property.OnView(args); + } + } + } + + void NotifyPropertyChanged(string name, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "NotifyPropertyChanged").Add(name).Add(args); +#endif + + if (name == string.Empty) + return; + + CF_TArrayProperties properties; + if (!m_PropertyVariableMap.Find(name, properties)) + return; + + foreach (auto property : properties) + { + property.OnModel(args); + } + } + + void NotifyPropertyChanged(CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "NotifyPropertyChanged").Add(args); +#endif + + for (int j = 0; j < m_PropertyVariableMap.Count(); j++) + { + CF_TArrayProperties properties = m_PropertyVariableMap.GetElement(j); + + foreach (auto property : properties) + { + property.OnModel(args); + } + } + } + + void Insert(CF_MVVM_Property property) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "Insert").Add(property); +#endif + + string variableName = property.GetVariableName(); + if (variableName == string.Empty) + return; + + CF_TArrayProperties properties = m_PropertyVariableMap[variableName]; + if (!properties) + properties = new CF_TArrayProperties(); + m_PropertyVariableMap[variableName] = properties; + + properties.Insert(property); + m_Properties.Insert(property); + } + + void Relink() + { + m_Root._SetRootLink(this); + } + + void Link(CF_ViewModel viewModel, CF_ModelBase model) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "Link").Add(viewModel).Add(model); +#endif + + m_Root = viewModel; + m_Root._RecursiveSetModel(model, this); + m_Root._SetRootLink(this); + + typename modelType = model.Type(); + int count = modelType.GetVariableCount(); + for (int i = 0; i < count; i++) + { + string variableName = modelType.GetVariableName(i); + typename variableType = modelType.GetVariableType(i); + + if (variableType.IsInherited(Widget)) + { + Insert(new CF_MVVM_WidgetProperty(viewModel, variableName)); + } + + CF_TArrayProperties properties; + if (!m_PropertyVariableMap.Find(variableName, properties)) + { + continue; + } + + auto typeConverter = CF_TypeConverter.Get(variableType); + + foreach (auto property : properties) + { + property.Link(model, variableType, typeConverter); + } + } + } + + bool IsValid() + { + return m_Root != null; + } + + void Unlink() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "Unlink"); +#endif + + m_IsBeingDestroyed = true; + + if (_IsLockedForDestroy()) + { + return; + } + + _Destroy(); + } + + void _Destroy() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "_Destroy"); +#endif + + m_PropertyVariableMap.Clear(); + m_Properties.Clear(); + + if (!m_Root) + { + return; + } + + if (m_Root.GetWidget()) + { + m_Root.GetWidget().Unlink(); + } + + m_Root = null; + } + + bool ChangeParent(Widget newParent) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "ChangeParent").Add(newParent); +#endif + + if (!m_Root) + return false; + + Widget widget = m_Root.GetWidget(); + Widget oldParent = widget.GetParent(); + + if (newParent == oldParent) + return true; + + OnDestroy.Invoke(this); + + if (oldParent && oldParent != newParent) + { + oldParent.RemoveChild(widget); + } + + if (newParent && oldParent != newParent) + { + newParent.AddChild(widget); + } + + return true; + } + + Widget GetWidget() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetWidget"); +#endif + + if (!m_Root) + { + return null; + } + + return m_Root.GetWidget(); + } + + bool _IsLockedForDestroy() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "_IsLockedForDestroy"); +#endif + + foreach (auto child : m_Children) + { + if (child._IsLockedForDestroy()) + { + return true; + } + } + + return m_DestroyLockCount > 0; + } + + void _LockForDestroy() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "_LockForDestroy"); +#endif + + m_DestroyLockCount++; + } + + void _UnlockForDestroy() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "_UnlockForDestroy"); +#endif + + m_DestroyLockCount--; + + if (m_DestroyLockCount < 0) + { + string className = "null"; + string debugName = ""; + if (m_Root.GetModel()) + { + className = m_Root.GetModel().ClassName(); + debugName = m_Root.GetModel().GetDebugName(); + } + + CF_Log.Warn("Destroy lock count reached below zero for %1 \"%2\"", className, debugName); + + m_DestroyLockCount = 0; + } + else if (!m_DestroyLockCount && m_IsBeingDestroyed) + { + _Destroy(); + } + } + + void AddChild(CF_MVVM_Linker child) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "AddChild").Add(child); +#endif + + if (child.m_Parent) + child.m_Parent.RemoveChild(child); + + m_Children.Insert(child); + child.m_Parent = this; + } + + void RemoveChild(CF_MVVM_Linker child) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "RemoveChild").Add(child); +#endif + + if (child.m_Parent != this) + { + return; + } + + for (int i = 0; i < m_Children.Count(); i++) + { + if (m_Children[i] == child) + { + child.m_Parent = null; + m_Children.Remove(i); + return; + } + } + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Menu.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Menu.c new file mode 100644 index 00000000..0a754f07 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_MVVM_Menu.c @@ -0,0 +1,39 @@ +class CF_MVVM_Menu : UIScriptedMenu +{ + private CF_MVVM_Linker m_Linker; + + private ref CF_ModelBase m_Model; + + override Widget Init() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "Init"); +#endif + + layoutRoot = GetGame().GetWorkspace().CreateWidget(FrameWidgetTypeID, 0, 0, 1, 1, WidgetFlags.VISIBLE, 0, 0, null); + return layoutRoot; + } + + void SetModel(CF_ModelBase model, string layoutFile) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "SetModel").Add(model).Add(layoutFile); +#endif + + m_Model = model; + + m_Linker = CF_MVVM.Create(m_Model, layoutFile, layoutRoot); + m_Linker.OnDestroy.AddSubscriber(RemoveModel); + } + + void RemoveModel() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "RemoveModel"); +#endif + + m_Linker.OnDestroy.RemoveSubscriber(RemoveModel); + + Close(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_Model.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_Model.c new file mode 100644 index 00000000..38578095 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_Model.c @@ -0,0 +1,54 @@ +/** + * @brief Simple typedef to keep track of what the base class is for models. + * Would like to use 'Class' in the future instead of 'Managed' + */ +typedef Managed CF_ModelBase; + +/** + * @brief + */ +class CF_Model : Managed +{ + void ~CF_Model() + { +#ifndef SERVER + CF_MVVM.Destroy(this); +#endif + } + + void NotifyPropertyChanged(string property, CF_EventArgs args = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "NotifyPropertyChanged").Add(property).Add(args); +#endif + + CF_MVVM.NotifyPropertyChanged(this, property, args); + } + + void NotifyPropertyChanged() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "NotifyPropertyChanged"); +#endif + + CF_MVVM.NotifyPropertyChanged(this); + } + + string GetLayoutFile() + { + return ""; + } + + override string GetDebugName() + { + return this.ToString(); + } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_ViewModel.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_ViewModel.c new file mode 100644 index 00000000..1a128f0f --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/CF_ViewModel.c @@ -0,0 +1,1501 @@ +class CF_ViewModel : ScriptedWidgetEventHandler +{ + reference string Model; + reference bool CreateModel = false; + reference string Children; + + reference string Event_Click; + reference string Event_ModalResult; + reference string Event_DoubleClick; + reference string Event_Select; + reference string Event_ItemSelected; + reference string Event_Focus; + reference string Event_FocusLost; + reference string Event_MouseEnter; + reference string Event_MouseLeave; + reference string Event_MouseWheel; + reference string Event_MouseButtonDown; + reference string Event_MouseButtonUp; + reference string Event_Controller; + reference string Event_KeyDown; + reference string Event_KeyUp; + reference string Event_KeyPress; + reference string Event_Change; + reference string Event_Drag; + reference string Event_Dragging; + reference string Event_DraggingOver; + reference string Event_Drop; + reference string Event_DropReceived; + reference string Event_Resize; + reference string Event_ChildAdd; + reference string Event_ChildRemove; + reference string Event_Update; + reference string Event_Show; + reference string Event_Hide; + reference string Event_Destroyed; + + protected Widget m_Widget; + + //#ifdef COMPONENT_SYSTEM + private ref CF_ModelBase m_WB_Model; + //#endif + + //! In-game, the ref count shouldn't be incremented. When the ref count == 0, then this view should be destroyed. + CF_ModelBase m_Model; + ref CF_MVVM_Linker m_Linker; + + //! Lifetimes are managed by the enfusion widgets + protected CF_ViewModel m_Parent = null; + protected ref set m_Children = new set(); + + protected autoptr map m_PropertiesSourceMap = new map(); + + protected bool m_ChangeEventFiring; + + void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + m_Widget = w; + + m_Widget.SetHandler(this); + + if (Model != string.Empty) + { + typename modelType = Model.ToType(); + if (modelType) + { +#ifdef COMPONENT_SYSTEM //! Workbench editing + if (!CF_MVVM.WB_NEXT_IN_SCRIPT) +#else + if (CreateModel) +#endif + { + Class.CastTo(m_WB_Model, modelType.Spawn()); + CF_MVVM.Connect(m_WB_Model, this); + } + } + else + { + Model = string.Empty; + } + } + + if (Model == string.Empty) + { + Widget parent = m_Widget.GetParent(); + while (parent != null) + { + CF_ViewModel view = null; + parent.GetScript(view); + if (view) + { + SetParent(view); + break; + } + + parent = parent.GetParent(); + } + } + } + + void ~CF_ViewModel() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "~CF_ViewModel"); +#endif + + if (!m_Parent) + { + CF_MVVM.s_ModelMap.Remove(m_Model); + } + } + + void NotifyPropertyChanged(string name, string source, CF_EventArgs args = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "NotifyPropertyChanged").Add(name).Add(args); +#endif + + if (!args) + { + args = new CF_EventArgs(); + } + + auto property = m_PropertiesSourceMap[source]; + if (!property) + { + return; + } + + property.OnView(args); + + m_Linker._ViewChanged(name, property, args); + } + + void NotifyPropertyChanged(CF_EventArgs args = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "NotifyPropertyChanged").Add(args); +#endif + + if (!args) + { + args = new CF_EventArgs(); + } + + m_Linker._ViewChanged(args); + } + + void _SetRootLink(CF_MVVM_Linker linker) + { + m_Linker = linker; + + Widget parent = m_Widget.GetParent(); + while (parent != null) + { + CF_ViewModel view = null; + parent.GetScript(view); + if (view) + { + view.m_Linker.AddChild(linker); + + break; + } + + parent = parent.GetParent(); + } + } + + void _RecursiveSetModel(CF_ModelBase model, CF_MVVM_Linker linker) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "_RecursiveSetModel").Add(model).Add(linker); +#endif + + m_Model = model; + m_Linker = linker; + + if (m_Model) + { + m_Widget.SetUserData(m_Model); + + GetProperties(); + + set children = GetChildren(); + for (int i = 0; i < children.Count(); i++) + { + children[i]._RecursiveSetModel(m_Model, m_Linker); + } + } + } + + protected void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + AddProperty(Children, "Children"); + } + + protected void AddProperty(inout string actual, string name) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "AddProperty").Add("Actual=" + actual + " Name=" + name); +#endif + + if (actual == string.Empty) + return; + + CF_MVVM_Property property = new CF_MVVM_Property(this, name); + actual = property.SetVariableName(actual); + + m_PropertiesSourceMap.Insert(name, property); + m_Linker.Insert(property); + } + + Widget GetChildWidgetAt(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetChildWidgetAt").Add(index); +#endif + + if (index == 0) + return null; + + Widget widget = m_Widget.GetChildren(); + for (int i = 1; i < index; i++) + { + widget = widget.GetSibling(); + if (!widget) + return null; + } + return widget; + } + + CF_ModelBase GetModel() + { + return m_Model; + } + + Widget GetWidget() + { + return m_Widget; + } + + set GetChildren() + { + return m_Children; + } + + void AddChild(CF_ViewModel child, bool modifyParent = true) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "AddChild").Add(child).Add(modifyParent); +#endif + + m_Children.Insert(child); + if (modifyParent) + child.SetParent(this, false); + } + + void RemoveChild(CF_ViewModel child, bool modifyParent = true) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "RemoveChild").Add(child).Add(modifyParent); +#endif + + for (int i = 0; i < m_Children.Count(); i++) + { + if (m_Children[i] == child) + { + if (modifyParent) + child.SetParent(null, false); + m_Children.Remove(i); + return; + } + } + } + + void SetParent(CF_ViewModel parent, bool modifyParent = true) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "SetParent").Add(parent).Add(modifyParent); +#endif + + //! if the parent remains unchanged, don't continue execution + if (m_Parent == parent) + return; + + //! remove us from the old parent if it exists + if (m_Parent) + m_Parent.RemoveChild(this, false); + + //! update the parent + m_Parent = parent; + + //! add us to the new parent. only called if the new parent didn't call this + if (m_Parent && modifyParent) + m_Parent.AddChild(this, false); + } + + /** + * @section Children + * + * @note + */ + void OnView_Children(CF_ModelBase sender, CF_EventArgs args) + { + // Handled automatically. + } + + void OnModel_Children(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children").Add(sender).Add(args.ClassName()); +#endif + + CF_ObservableCollection _collection; + EnScript.GetClassVar(m_Model, Children, 0, _collection); + if (!_collection) + return; + + switch (args.Type()) + { + case CF_CollectionInsertEventArgs: + { + OnModel_Children_Insert(_collection, CF_CollectionInsertEventArgs.Cast(args)); + return; + } + case CF_CollectionInsertAtEventArgs: + { + OnModel_Children_InsertAt(_collection, CF_CollectionInsertAtEventArgs.Cast(args)); + return; + } + case CF_CollectionClearEventArgs: + { + OnModel_Children_Clear(_collection, CF_CollectionClearEventArgs.Cast(args)); + return; + } + case CF_CollectionSetEventArgs: + { + OnModel_Children_Set(_collection, CF_CollectionSetEventArgs.Cast(args)); + return; + } + case CF_CollectionRemoveEventArgs: + { + OnModel_Children_Remove(_collection, CF_CollectionRemoveEventArgs.Cast(args)); + return; + } + case CF_CollectionSwapEventArgs: + { + OnModel_Children_Swap(_collection, CF_CollectionSwapEventArgs.Cast(args)); + return; + } + } + + OnModel_Children_InsertAll(_collection, args); + } + + void OnModel_Children_InsertAll(CF_ObservableCollection sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_InsertAll").Add(sender).Add(args); +#endif + + for (int i = 0; i < sender.Count(); i++) + { + CF_TypeConverterBase conv = sender.GetConverter(i); + if (!conv) + return; + + CF_ModelBase model = CF_ModelBase.Cast(conv.GetClass()); + + string layout; + g_Script.CallFunction(model, "GetLayoutFile", layout, null); + if (layout == string.Empty) + { + CF_Log.Error("Empty layout file provided."); + return; + } + + CF_MVVM.Create(model, layout, m_Widget); + } + } + + void OnModel_Children_Insert(CF_ObservableCollection sender, CF_CollectionInsertEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Insert").Add(sender).Add(args); +#endif + + CF_TypeConverterBase conv = sender.GetConverter(args.Index); + if (!conv) + return; + + CF_ModelBase model = CF_ModelBase.Cast(conv.GetClass()); + + string layout; + g_Script.CallFunction(model, "GetLayoutFile", layout, null); + if (layout == string.Empty) + { + CF_Log.Error("Empty layout file provided."); + return; + } + + CF_MVVM.Create(model, layout, m_Widget); + } + + void OnModel_Children_InsertAt(CF_ObservableCollection sender, CF_CollectionInsertAtEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_InsertAt").Add(sender).Add(args); +#endif + + CF_Log.Error("Function not implemented"); + } + + void OnModel_Children_Clear(CF_ObservableCollection sender, CF_CollectionClearEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Clear").Add(sender).Add(args); +#endif + + Widget child = m_Widget.GetChildren(); + while (child != null) + { + Widget current = child; + child = child.GetSibling(); + + CF_ModelBase model; + current.GetUserData(model); + if (model) + { + CF_MVVM.Destroy(model); + } + } + } + + void OnModel_Children_Set(CF_ObservableCollection sender, CF_CollectionSetEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Set").Add(sender).Add(args); +#endif + + CF_Log.Error("Function not implemented"); + } + + void OnModel_Children_Remove(CF_ObservableCollection sender, CF_CollectionRemoveEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Remove").Add(sender).Add(args); +#endif + + Widget widget = GetChildWidgetAt(args.Index); + if (!widget) + return; + + m_Widget.RemoveChild(widget); + } + + void OnModel_Children_Swap(CF_ObservableCollection sender, CF_CollectionSwapEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Swap").Add(sender).Add(args); +#endif + + CF_Log.Error("Function not implemented"); + } + + bool WhatChanged(out string name, out string variable) + { + return false; + } + + /** + * @section Events + * + * @note Continue is handled in the script widget instead of 'CF_ViewModel' as some + * events require reverse cancellation. For example, if 'Continue' is set to 'false' + * for 'OnChange' in 'CF_EditBoxWidget', then input must be prevented. + */ + bool OnClick(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnModalResult(CF_ModelBase sender, CF_ModalEventArgs args) { return !args.Continue; } + bool OnDoubleClick(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnSelect(CF_ModelBase sender, CF_SelectEventArgs args) { return !args.Continue; } + bool OnItemSelected(CF_ModelBase sender, CF_ItemSelectEventArgs args) { return !args.Continue; } + bool OnFocus(CF_ModelBase sender, CF_PositionEventArgs args) { return !args.Continue; } + bool OnFocusLost(CF_ModelBase sender, CF_PositionEventArgs args) { return !args.Continue; } + bool OnMouseEnter(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnMouseLeave(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnMouseWheel(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnMouseButtonDown(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnMouseButtonUp(CF_ModelBase sender, CF_MouseEventArgs args) { return !args.Continue; } + bool OnController(CF_ModelBase sender, CF_ControllerEventArgs args) { return !args.Continue; } + bool OnKeyDown(CF_ModelBase sender, CF_KeyEventArgs args) { return !args.Continue; } + bool OnKeyUp(CF_ModelBase sender, CF_KeyEventArgs args) { return !args.Continue; } + bool OnKeyPress(CF_ModelBase sender, CF_KeyEventArgs args) { return !args.Continue; } + bool OnChange(CF_ModelBase sender, CF_ChangeEventArgs args) { return !args.Continue; } + bool OnDrag(CF_ModelBase sender, CF_DragEventArgs args) { return !args.Continue; } + bool OnDragging(CF_ModelBase sender, CF_DragEventArgs args) { return !args.Continue; } + bool OnDraggingOver(CF_ModelBase sender, CF_DragEventArgs args) { return !args.Continue; } + bool OnDrop(CF_ModelBase sender, CF_DragEventArgs args) { return !args.Continue; } + bool OnDropReceived(CF_ModelBase sender, CF_DragEventArgs args) { return !args.Continue; } + bool OnResize(CF_ModelBase sender, CF_ResizeEventArgs args) { return !args.Continue; } + bool OnChildAdd(CF_ModelBase sender, CF_ChildEventArgs args) { return !args.Continue; } + bool OnChildRemove(CF_ModelBase sender, CF_ChildEventArgs args) { return !args.Continue; } + bool OnUpdate(CF_ModelBase sender, CF_ViewEventArgs args) { return !args.Continue; } + + override bool OnClick(Widget w, int x, int y, int button) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnClick").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = button; + + if (Event_Click != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Click, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnClick(this, args); + } + + override bool OnModalResult(Widget w, int x, int y, int code, int result) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnModalResult").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ModalEventArgs args = new CF_ModalEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Code = code; + args.Result = result; + + if (Event_ModalResult != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_ModalResult, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnModalResult(this, args); + } + + override bool OnDoubleClick(Widget w, int x, int y, int button) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDoubleClick").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = button; + + if (Event_DoubleClick != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_DoubleClick, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDoubleClick(this, args); + } + + override bool OnSelect(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnSelect").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_SelectEventArgs args = new CF_SelectEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + + if (Event_Select != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Select, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnSelect(this, args); + } + + override bool OnItemSelected(Widget w, int x, int y, int row, int column, int oldRow, int oldColumn) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnItemSelected").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ItemSelectEventArgs args = new CF_ItemSelectEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Row = row; + args.Column = column; + args.OldRow = oldRow; + args.OldColumn = oldColumn; + + if (Event_ItemSelected != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_ItemSelected, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnItemSelected(this, args); + } + + override bool OnFocus(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnFocus").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_PositionEventArgs args = new CF_PositionEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + + if (Event_Focus != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Focus, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnFocus(this, args); + } + + override bool OnFocusLost(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnFocusLost").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_PositionEventArgs args = new CF_PositionEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + + if (Event_FocusLost != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_FocusLost, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnFocusLost(this, args); + } + + override bool OnMouseEnter(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnMouseEnter").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = -1; + args.Type = 1; + + if (Event_MouseEnter != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_MouseEnter, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnMouseEnter(this, args); + } + + override bool OnMouseLeave(Widget w, Widget enterW, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnMouseLeave").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = -1; + args.Enter = enterW; + args.Type = 2; + + if (Event_MouseLeave != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_MouseLeave, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnMouseLeave(this, args); + } + + override bool OnMouseWheel(Widget w, int x, int y, int wheel) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnMouseWheel").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = -1; + args.Wheel = wheel; + + if (Event_MouseWheel != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_MouseWheel, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnMouseWheel(this, args); + } + + override bool OnMouseButtonDown(Widget w, int x, int y, int button) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnMouseButtonDown").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = button; + + if (Event_MouseButtonDown != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_MouseButtonDown, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnMouseButtonDown(this, args); + } + + override bool OnMouseButtonUp(Widget w, int x, int y, int button) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnMouseButtonUp").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_MouseEventArgs args = new CF_MouseEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Button = button; + + if (Event_MouseButtonUp != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_MouseButtonUp, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnMouseButtonUp(this, args); + } + + override bool OnController(Widget w, int control, int value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnController").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ControllerEventArgs args = new CF_ControllerEventArgs(); + args.Target = w; + args.Control = control; + args.Value = value; + + if (Event_Controller != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Controller, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnController(this, args); + } + + override bool OnKeyDown(Widget w, int x, int y, int key) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnKeyDown").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_KeyEventArgs args = new CF_KeyEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Key = key; + args.State = CF_KeyState.DOWN; + + if (Event_KeyDown != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_KeyDown, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnKeyDown(this, args); + } + + override bool OnKeyUp(Widget w, int x, int y, int key) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnKeyUp").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_KeyEventArgs args = new CF_KeyEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Key = key; + args.State = CF_KeyState.UP; + + if (Event_KeyUp != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_KeyUp, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnKeyUp(this, args); + } + + override bool OnKeyPress(Widget w, int x, int y, int key) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnKeyPress").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_KeyEventArgs args = new CF_KeyEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Key = key; + args.State = CF_KeyState.PRESS; + + if (Event_KeyPress != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_KeyPress, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnKeyPress(this, args); + } + + override bool OnChange(Widget w, int x, int y, bool finished) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnChange").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + if (w != m_Widget || m_ChangeEventFiring) + { + m_ChangeEventFiring = false; + + return false; + } + + m_ChangeEventFiring = true; + + CF_ChangeEventArgs args = new CF_ChangeEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Finished = finished; + + string name; + if (WhatChanged(name, args.What)) + { + NotifyPropertyChanged(args.What, name); + } + + if (Event_Change != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Change, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnChange(this, args); + } + + override bool OnDrag(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDrag").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_DragEventArgs args = new CF_DragEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Reciever = null; + + if (Event_Drag != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Drag, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDrag(this, args); + } + + override bool OnDragging(Widget w, int x, int y, Widget reciever) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDragging").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_DragEventArgs args = new CF_DragEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Reciever = reciever; + + if (Event_Dragging != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Dragging, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDragging(this, args); + } + + override bool OnDraggingOver(Widget w, int x, int y, Widget reciever) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDraggingOver").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_DragEventArgs args = new CF_DragEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Reciever = reciever; + + if (Event_DraggingOver != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_DraggingOver, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDraggingOver(this, args); + } + + override bool OnDrop(Widget w, int x, int y, Widget reciever) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDrop").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_DragEventArgs args = new CF_DragEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Reciever = reciever; + + if (Event_Drop != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Drop, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDrop(this, args); + } + + override bool OnDropReceived(Widget w, int x, int y, Widget reciever) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnDropReceived").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_DragEventArgs args = new CF_DragEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + args.Reciever = reciever; + + if (Event_DropReceived != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_DropReceived, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnDropReceived(this, args); + } + + override bool OnResize(Widget w, int x, int y) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnResize").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ResizeEventArgs args = new CF_ResizeEventArgs(); + args.Target = w; + args.X = x; + args.Y = y; + + if (Event_Resize != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Resize, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnResize(this, args); + } + + override bool OnChildAdd(Widget w, Widget child) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnChildAdd").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ChildEventArgs args = new CF_ChildEventArgs(); + args.Target = w; + args.Child = child; + args.Remove = false; + + if (Event_ChildAdd != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_ChildAdd, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnChildAdd(this, args); + } + + override bool OnChildRemove(Widget w, Widget child) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnChildRemove").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ChildEventArgs args = new CF_ChildEventArgs(); + args.Target = w; + args.Child = child; + args.Remove = true; + + if (Event_ChildRemove != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_ChildRemove, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnChildRemove(this, args); + } + + override bool OnUpdate(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnUpdate").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ViewEventArgs args = new CF_ViewEventArgs(); + args.Target = w; + + if (Event_Update != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Update, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return OnUpdate(this, args); + } + + bool OnShow(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnShow").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ViewEventArgs args = new CF_ViewEventArgs(); + args.Target = w; + + if (Event_Show != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Show, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return true; + } + + bool OnHide(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnHide").Add(w); +#endif + + if (!m_Linker) + { + return false; + } + + CF_ViewEventArgs args = new CF_ViewEventArgs(); + args.Target = w; + + if (Event_Hide != string.Empty) + { + m_Linker._LockForDestroy(); + + Param param = new Param2(null, args); + g_Script.CallFunctionParams(m_Model, Event_Hide, null, param); + + m_Linker._UnlockForDestroy(); + } + + if (!this) + { + return false; + } + + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableArray.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableArray.c new file mode 100644 index 00000000..2873bb83 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableArray.c @@ -0,0 +1,359 @@ +class CF_ObservableArray : CF_ObservableCollection +{ + private ref array m_Data = new array(); + + void CF_ObservableArray() + { +#ifdef COMPONENT_SYSTEM + CF_MVVM._CheckInit(); +#endif + + typename t = T; +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, string.Format("CF_ObservableArray<%1>", t)); +#endif + + OverrideConverter(); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Data.Count(); + for (int i = 0; i < m_Data.Count(); i++) + { + str += " " + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetConverter").Add(index); +#endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + override void OverrideConverter(CF_TypeConverterBase converter = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OverrideConverter").Add(converter); +#endif + + if (!converter) + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + return; + } + + m_Converter = converter; + } + + /*! + O(1) complexity. + \return Number of elements of the array + */ + override int Count() + { + return m_Data.Count(); + } + + /*! + Destroyes all elements of the array and sets the Count to 0. + The underlying memory of the array is not freed. + */ + override void Clear() + { + m_Data.Clear(); + + NotifyCollectionChanged(new CF_CollectionClearEventArgs()); + } + + /*! + Sets n-th element to given value. + */ + void Set(int n, T value) + { + m_Data.Set(n, value); + + NotifyCollectionChanged(new CF_CollectionSetEventArgs(n)); + } + + /*! + Tries to find the first occurance of given value in the array. + \return Index of the first occurance of `value` if found, -1 otherwise + */ + int Find(T value) + { + return m_Data.Find(value); + } + + /*! + \return Element at the index `n` + */ + T Get(int index) + { + return m_Data[index]; + } + + /*! + Inserts element at the end of array. + \param value + Element to be inserted + \return + Position at which element is inserted + */ + void Insert(T value) + { + int index = m_Data.Insert(value); + + NotifyCollectionChanged(new CF_CollectionInsertEventArgs(index)); + } + + /*! + Inserts element at certain position and moves all elements behind + this position by one. + \param value + Element to be inserted + \param index + Position at which element is inserted. Must be less than Array::GetCardinality() + \return + Number of elements after insertion + */ + int InsertAt(T value, int index) + { + int idx = m_Data.InsertAt(value, index); + + NotifyCollectionChanged(new CF_CollectionInsertAtEventArgs(index)); + + return idx; + } + + /** + \brief Inserts all elements from array + \param from \p array array from which all elements will be added + @code + TStringArray arr1 = new TStringArray; + arr1.Insert( "Dave" ); + arr1.Insert( "Mark" ); + arr1.Insert( "John" ); + + TStringArray arr2 = new TStringArray; + arr2.Insert( "Sarah" ); + arr2.Insert( "Cate" ); + + arr1.InsertAll(arr2); + + for ( int i = 0; i < arr1.Count(); i++ ) + { + Print( arr1.Get(i) ); + } + + delete arr2; + delete arr1; + + >> "Dave" + >> "Mark" + >> "John" + >> "Sarah" + >> "Cate" + @endcode + */ + void InsertAll(notnull array from) + { + m_Data.InsertAll(from); + } + + void InsertAll(notnull CF_ObservableArray from) + { + //m_Data.InsertAll(from.m_Data); + } + + /*! + Removes element from array. The empty position is replaced by + last element, so removal is quite fast but do not retain order. + \param index + Index of element to be removed + */ + void Remove(int index) + { + if (m_Data.Count() <= 1) + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(index)); + + m_Data.Remove(index); + + if (m_Data.Count() > 0 && index < m_Data.Count()) + NotifyCollectionChanged(new CF_CollectionSetEventArgs(index)); + } + + /*! + Removes element from array, but retain all elements ordered. It's + slower than Remove + \param index + Index of element to be removed + */ + void RemoveOrdered(int index) + { + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(index)); + + m_Data.RemoveOrdered(index); + } + + /*! + Resizes the array to given size. + If the `newSize` is lower than current Count overflowing objects are destroyed. + If the `newSize` is higher than current Count missing elements are initialized to zero (null). + */ + void Resize(int newSize) + { + m_Data.Resize(newSize); + } + + /*! + Swaps the contents of this and `other` arrays. + Does not involve copying of the elements. + */ + void Swap(notnull array other) + { + m_Data.Swap(other); + } + + /*! + Swaps the contents of this and `other` arrays. + Does not involve copying of the elements. + */ + void Swap(notnull CF_ObservableArray other) + { + //m_Data.Swap(other.m_Data); + } + + /*! + Sorts elements of array, depends on underlaying type. + */ + void Sort(bool reverse = false) + { + m_Data.Sort(reverse); + } + + /*! + Copies contents of `from` array to this array. + \return How many elements were copied + */ + int Copy(notnull array from) + { + return 0; //m_Data.Copy(from); + } + + int Copy(notnull CF_ObservableArray from) + { + return 0; //m_Data.Copy(from.m_Data); + } + + int Init(T init[]) + { + return m_Data.Init(init); + } + + void RemoveItem(T value) + { + m_Data.RemoveItem(value); + } + + void RemoveItemUnOrdered(T value) + { + m_Data.RemoveItemUnOrdered(value); + } + + bool IsValidIndex(int index) + { + return m_Data.IsValidIndex(index); + } + + /** + \brief Print all elements in array + \return \p void + @code + my_array.Debug(); + + >> "One" + >> "Two" + >> "Three" + @endcode + */ + void Debug() + { + m_Data.Debug(); + } + + /** + \brief Returns a random index of array. If Count is 0, return index is -1 . + \return \p int Random index of array + @code + Print( my_array.GetRandomIndex() ); + + >> 2 + @endcode + */ + int GetRandomIndex() + { + return m_Data.GetRandomIndex(); + } + + /** + \brief Returns a random element of array + \return \p int Random element of array + @code + Print( my_array.GetRandomElement() ); + + >> "Three" + @endcode + */ + T GetRandomElement() + { + return m_Data.GetRandomElement(); + } + + void SwapItems(int item1_index, int item2_index) + { + NotifyCollectionChanged(new CF_CollectionSwapEventArgs(item1_index, item2_index)); + + m_Data.SwapItems(item1_index, item2_index); + } + + void InsertArray(array other) + { + m_Data.InsertArray(other); + } + + void InsertArray(CF_ObservableArray other) + { + //m_Data.InsertArray(other.m_Data); + } + + void Invert() + { + m_Data.Invert(); + } + + /** + \brief Returns a index in array moved by specific number + \return \p int Moved index in this array + @code + Print( "Count: "+ my_array.Count() ); + Print( "Moved 1:"+ my_array.MoveIndex(2, 1) ); + Print( "Moved 3:"+ my_array.MoveIndex(2, 2) ); + + >> "Count: 4" + >> "Moved index 2 by 1: 3"; + >> "Moved index 2 by 2: 0"; + @endcode + */ + int MoveIndex(int curr_index, int move_number) + { + return m_Data.MoveIndex(curr_index, move_number); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableCollection.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableCollection.c new file mode 100644 index 00000000..352d3baf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableCollection.c @@ -0,0 +1,147 @@ +class CF_ObservableCollection : CF_Collection +{ + private int m_LinkCount; + private ref Param2 m_Links[16]; + + void Init(CF_ModelBase model, string prop) + { +#ifdef COMPONENT_SYSTEM + CF_MVVM._CheckInit(); +#endif + +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "Init").Add(model).Add(prop); +#endif + + m_Links[m_LinkCount] = new Param2(model, prop); + m_LinkCount++; + } + + void NotifyCollectionChanged(CF_CollectionEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "NotifyCollectionChanged").Add(args.GetDebugName()); +#endif + + for (int i = 0; i < m_LinkCount; i++) + { + CF_MVVM.NotifyPropertyChanged(m_Links[i].param1, m_Links[i].param2, args); + } + } + + void Clear() + { + } + + void SetInt(int index, int value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertInt(int value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + int GetInt(int index) + { + return GetConverter(index).GetInt(); + } + + void SetBool(int index, bool value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertBool(bool value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + bool GetBool(int index) + { + return GetConverter(index).GetBool(); + } + + void SetFloat(int index, float value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertFloat(float value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + float GetFloat(int index) + { + return GetConverter(index).GetFloat(); + } + + void SetVector(int index, vector value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertVector(vector value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + vector GetVector(int index) + { + return GetConverter(index).GetVector(); + } + + void SetString(int index, string value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertString(string value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + string GetString(int index) + { + return GetConverter(index).GetString(); + } + + void SetClass(int index, Class value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertClass(Class value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + Class GetClass(int index) + { + return GetConverter(index).GetClass(); + } + + void SetManaged(int index, Managed value) + { + Param params = new Param2(index, value); + g_Script.CallFunctionParams(this, "Set", null, params); + } + + void InsertManaged(Managed value) + { + g_Script.CallFunction(this, "Insert", null, value); + } + + Managed GetManaged(int index) + { + return GetConverter(index).GetManaged(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableMap.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableMap.c new file mode 100644 index 00000000..3e5a4826 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableMap.c @@ -0,0 +1,153 @@ +class CF_ObservableMap : CF_ObservableCollection +{ + private ref map m_DataMap = new map(); + private ref array m_Keys = new array(); + private ref array m_Values = new array(); + + void CF_ObservableMap() + { +#ifdef COMPONENT_SYSTEM + CF_MVVM._CheckInit(); +#endif + + OverrideConverter(); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Count; + for (int i = 0; i < m_Count; i++) + { + str += " " + m_Keys[i] + ":"; + str += " " + m_Values[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetConverter").Add(index); +#endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Values[index]); + return m_Converter; + } + + override void OverrideConverter(CF_TypeConverterBase converter = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OverrideConverter").Add(converter); +#endif + + if (!converter) + { + typename t = TValue; + m_Converter = CF_TypeConverter.Get(t); + return; + } + + m_Converter = converter; + } + + override int Count() + { + return m_Values.Count(); + } + + TValue Get(TKey key) + { + return m_Values[m_DataMap[key]]; + } + + bool Find(TKey key, out TValue val) + { + int idx; + if (m_DataMap.Find(key, idx)) + { + val = m_Values[idx]; + return true; + } + + return false; + } + + TValue GetElement(int index) + { + return m_Values[index]; + } + + TKey GetKey(int i) + { + return m_Keys[i]; + } + + void Set(TKey key, TValue value) + { + if (Contains(key)) + { + m_Values[m_DataMap[key]] = value; + NotifyCollectionChanged(new CF_CollectionSetEventArgs(m_DataMap[key])); + } + else + { + int idx = m_Values.Count(); + m_Keys.Insert(key); + m_Values.Insert(value); + m_DataMap.Insert(key, idx); + NotifyCollectionChanged(new CF_CollectionInsertEventArgs(m_DataMap[key])); + } + + m_Count = m_Keys.Count(); + } + + void Remove(TKey key) + { + int index = m_DataMap[key]; + + if (m_Keys.Count() <= 1) + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(index)); + + TKey replaced = m_Keys[m_Keys.Count() - 1]; + + m_Keys.Remove(index); + m_Values.Remove(index); + + m_DataMap.Remove(key); + + if (m_Keys.Count() > 0 && index < m_Keys.Count()) + { + m_DataMap[replaced] = index; + NotifyCollectionChanged(new CF_CollectionSetEventArgs(index)); + } + + m_Count = m_Keys.Count(); + } + + void RemoveElement(int index) + { + Remove(GetKey(index)); + } + + bool Contains(TKey key) + { + return m_DataMap.Contains(key); + } + + void Insert(TKey key, TValue value) + { + Set(key, value); + } + + override void Clear() + { + NotifyCollectionChanged(new CF_CollectionClearEventArgs()); + + m_Values.Clear(); + m_Keys.Clear(); + m_DataMap.Clear(); + + m_Count = 0; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservablePriorityQueue.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservablePriorityQueue.c new file mode 100644 index 00000000..25489448 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservablePriorityQueue.c @@ -0,0 +1,89 @@ +class CF_ObservablePriorityQueue : CF_ObservableCollection +{ + protected ref Param2 m_Data[256]; + + void CF_ObservablePriorityQueue() + { + typename t = T; +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, string.Format("CF_ObservablePriorityQueue<%1>", t)); +#endif + + OverrideConverter(); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Count; + for (int i = 0; i < m_Count; i++) + { + str += " " + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetConverter").Add(index); +#endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + override void OverrideConverter(CF_TypeConverterBase converter = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OverrideConverter").Add(converter); +#endif + + if (!converter) + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + return; + } + + m_Converter = converter; + } + + void Enqueue(T item, Comparable priority) + { + m_Data[m_Count] = new Param2(item, priority); + + NotifyCollectionChanged(new CF_CollectionInsertEventArgs(m_Count)); + + m_Count++; + } + + T Dequeue() + { + int bestIndex = 0; + + for (int i = 0; i < m_Count; i++) + { + if (m_Data[i].param2 < m_Data[bestIndex].param2) + { + bestIndex = i; + } + } + + T bestItem = m_Data[bestIndex].param1; + + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(bestIndex)); + + m_Count--; + + m_Data[bestIndex] = m_Data[m_Count]; + m_Data[m_Count] = null; + + if (bestIndex < m_Count && m_Count > 0) + { + NotifyCollectionChanged(new CF_CollectionSetEventArgs(bestIndex)); + } + + return bestItem; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableSortedArray.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableSortedArray.c new file mode 100644 index 00000000..efe17f70 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableSortedArray.c @@ -0,0 +1,129 @@ +class CF_ObservableSortedArray : CF_ObservableCollection +{ + private ref array m_Data = new array(); + private ref array m_Sort = new array(); + + void CF_ObservableSortedArray() + { +#ifdef COMPONENT_SYSTEM + CF_MVVM._CheckInit(); +#endif + + typename t = T; +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, string.Format("CF_ObservableArray<%1>", t)); +#endif + + OverrideConverter(); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Data.Count(); + for (int i = 0; i < m_Data.Count(); i++) + { + str += " " + m_Sort[i] + "=" + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetConverter").Add(index); +#endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + override void OverrideConverter(CF_TypeConverterBase converter = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OverrideConverter").Add(converter); +#endif + + if (!converter) + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + return; + } + + m_Converter = converter; + } + + override int Count() + { + return m_Data.Count(); + } + + override void Clear() + { + m_Data.Clear(); + + NotifyCollectionChanged(new CF_CollectionClearEventArgs()); + } + + void Insert(T value, int sort) + { + int index = 0; + while (index < m_Count) + { + if (sort >= m_Sort[index]) + { + break; + } + + index++; + } + + if (index >= m_Count) + { + index = m_Data.Insert(value); + if (index != m_Sort.Insert(sort)) + { + CF_Log.Error("Count mismatch"); + } + + NotifyCollectionChanged(new CF_CollectionInsertEventArgs(index)); + } + else + { + m_Count = m_Data.InsertAt(value, index); + if (m_Count != m_Sort.InsertAt(sort, index)) + { + CF_Log.Error("Count mismatch"); + } + + NotifyCollectionChanged(new CF_CollectionInsertAtEventArgs(index)); + } + + m_Count = m_Data.Count(); + } + + void Remove(int index) + { + if (m_Data.Count() <= 1) + { + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(index)); + } + + m_Data.RemoveOrdered(index); + m_Sort.RemoveOrdered(index); + + if (m_Data.Count() > 0 && index < m_Data.Count()) + { + NotifyCollectionChanged(new CF_CollectionSetEventArgs(index)); + } + + m_Count = m_Data.Count(); + } + + void Resize(int newSize) + { + m_Data.Resize(newSize); + m_Sort.Resize(newSize); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableStack.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableStack.c new file mode 100644 index 00000000..5cc517cf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Collections/CF_ObservableStack.c @@ -0,0 +1,120 @@ +class CF_ObservableStack : CF_ObservableCollection +{ + private T m_Data[256]; + private int m_Count; + + void CF_ObservableStack() + { + typename t = T; +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, string.Format("CF_ObservableStack<%1>", t)); +#endif + + OverrideConverter(); + } + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += "Count: " + m_Count; + for (int i = 0; i < m_Count; i++) + { + str += " " + m_Data[i]; + } + return str; + } + + override CF_TypeConverterBase GetConverter(int index) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "GetConverter").Add(index); +#endif + + g_Script.CallFunction(m_Converter, "Set", null, m_Data[index]); + return m_Converter; + } + + override void OverrideConverter(CF_TypeConverterBase converter = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OverrideConverter").Add(converter); +#endif + + if (!converter) + { + typename t = T; + m_Converter = CF_TypeConverter.Get(t); + return; + } + + m_Converter = converter; + } + + T Pop() + { + T value; + + if (m_Count <= 0) + { + m_Count = 0; + } + else + { + value = m_Data[m_Count - 1]; + + NotifyCollectionChanged(new CF_CollectionRemoveEventArgs(m_Count - 1)); + + m_Count--; + } + + return value; + } + + T Peek() + { + return m_Data[m_Count - 1]; + } + + T Push(T value) + { + m_Data[m_Count] = value; + + NotifyCollectionChanged(new CF_CollectionInsertEventArgs(m_Count)); + + m_Count++; + + return value; + } + + array ToArray() + { + array arr = new array(); + for (int i = 0; i < m_Count; i++) + arr.Insert(m_Data[i]); + return arr; + } + + override void Clear() + { + m_Count = 0; + + NotifyCollectionChanged(new CF_CollectionClearEventArgs()); + } + + T Get(int index) + { + return m_Data[index]; + } + + void Set(int index, T value) + { + m_Data[index] = value; + + NotifyCollectionChanged(new CF_CollectionSetEventArgs(index)); + } + + override int Count() + { + return m_Count; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Converters/CF_TypeConverter_BoolInvert.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Converters/CF_TypeConverter_BoolInvert.c new file mode 100644 index 00000000..454626b8 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Converters/CF_TypeConverter_BoolInvert.c @@ -0,0 +1,53 @@ +class CF_TypeConverter_BoolInvert : CF_TypeConverterInt +{ + override void SetInt(int value) + { + m_Value = value == 0; + } + + override int GetInt() + { + if (m_Value != 0) + return 0; + return 1; + } + + override void SetBool(bool value) + { + m_Value = value == 0; + } + + override bool GetBool() + { + return m_Value == 0; + } + + override void SetFloat(float value) + { + m_Value = value == 0.0; + } + + override float GetFloat() + { + return GetInt(); + } + + override void SetVector(vector value) + { + } + + override vector GetVector() + { + return vector.Zero; + } + + override void SetString(string value) + { + m_Value = CF.StringToBool(value) == false; + } + + override string GetString() + { + return "" + (!m_Value); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChangeEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChangeEventArgs.c new file mode 100644 index 00000000..60d804ce --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChangeEventArgs.c @@ -0,0 +1,13 @@ +class CF_ChangeEventArgs : CF_PositionEventArgs +{ + string What; + bool Finished; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " What=" + What; + str += " Finished=" + Finished; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChildEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChildEventArgs.c new file mode 100644 index 00000000..b61809b9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ChildEventArgs.c @@ -0,0 +1,13 @@ +class CF_ChildEventArgs : CF_PositionEventArgs +{ + Widget Child; + bool Remove; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Child=" + Child; + str += " Remove=" + Remove; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ControllerEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ControllerEventArgs.c new file mode 100644 index 00000000..f26dadd9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ControllerEventArgs.c @@ -0,0 +1,13 @@ +class CF_ControllerEventArgs : CF_ViewEventArgs +{ + int Control; + int Value; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Control=" + Control; + str += " Value=" + Value; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_DragEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_DragEventArgs.c new file mode 100644 index 00000000..cae75956 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_DragEventArgs.c @@ -0,0 +1,11 @@ +class CF_DragEventArgs : CF_PositionEventArgs +{ + Widget Reciever; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Reciever=" + Reciever; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ItemSelectEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ItemSelectEventArgs.c new file mode 100644 index 00000000..210ec1e6 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ItemSelectEventArgs.c @@ -0,0 +1,18 @@ +class CF_ItemSelectEventArgs : CF_PositionEventArgs +{ + int Row; + int Column; + + int OldRow; + int OldColumn; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Row=" + Row; + str += " Column=" + Column; + str += " OldRow=" + OldRow; + str += " OldColumn=" + OldColumn; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_KeyEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_KeyEventArgs.c new file mode 100644 index 00000000..d02def53 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_KeyEventArgs.c @@ -0,0 +1,13 @@ +class CF_KeyEventArgs : CF_PositionEventArgs +{ + int Key; + CF_KeyState State; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Key=" + Key; + str += " State=" + State; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ModalEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ModalEventArgs.c new file mode 100644 index 00000000..8946232b --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ModalEventArgs.c @@ -0,0 +1,13 @@ +class CF_ModalEventArgs : CF_PositionEventArgs +{ + int Code; + int Result; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Code=" + Code; + str += " Result=" + Result; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_MouseEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_MouseEventArgs.c new file mode 100644 index 00000000..5b5b6932 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_MouseEventArgs.c @@ -0,0 +1,32 @@ +class CF_MouseEventArgs : CF_PositionEventArgs +{ + /** + * @brief OnClick, OnDoubleClick, OnMouseButtonDown, OnMouseButtonUp + */ + int Button; + + /** + * @brief OnMouseLeave + */ + Widget Enter; + + /** + * @brief OnMouseWheel + */ + int Wheel; + + /** + * @brief 1 = Enter, 2 = Leave + */ + int Type; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Button=" + Button; + str += " Enter=" + Enter; + str += " Wheel=" + Wheel; + str += " Type=" + Type; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_PositionEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_PositionEventArgs.c new file mode 100644 index 00000000..a473fa1f --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_PositionEventArgs.c @@ -0,0 +1,13 @@ +class CF_PositionEventArgs : CF_ViewEventArgs +{ + int X; + int Y; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " X=" + X; + str += " Y=" + Y; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ResizeEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ResizeEventArgs.c new file mode 100644 index 00000000..98e36307 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ResizeEventArgs.c @@ -0,0 +1,3 @@ +class CF_ResizeEventArgs : CF_PositionEventArgs +{ +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_SelectEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_SelectEventArgs.c new file mode 100644 index 00000000..af0cd445 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_SelectEventArgs.c @@ -0,0 +1,3 @@ +class CF_SelectEventArgs : CF_PositionEventArgs +{ +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ViewEventArgs.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ViewEventArgs.c new file mode 100644 index 00000000..e9bb9828 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/EventArgs/CF_ViewEventArgs.c @@ -0,0 +1,13 @@ +class CF_ViewEventArgs : CF_EventArgs +{ + Widget Target; + bool Continue = true; + + override string GetDebugName() + { + string str = super.GetDebugName(); + str += " Target=" + Target; + str += " Continue=" + Continue; + return str; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Models/CF_TestModel.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Models/CF_TestModel.c new file mode 100644 index 00000000..b4a412e2 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Models/CF_TestModel.c @@ -0,0 +1,125 @@ + +/** + * @brief Inheriting from 'CF_Model' is not a requirement, must re-implement the 'GetLayoutFile' method. + */ +class CF_TestModel : CF_Model +{ + int Index; + + string TextInput = "Input?"; + bool BlockInput = false; + + string ButtonText = "Press??"; + + //ref CF_Dropdown Dropdown = new CF_Dropdown(); + + ref CF_ObservableArray Test = new CF_ObservableArray(); + + void CF_TestModel() + { + //Dropdown.Insert(new CF_TestColour(0xFFFF0000, "Red")); + //Dropdown.Insert(new CF_TestColour(0xFF00FF00, "Green")); + //Dropdown.Insert(new CF_TestColour(0xFF0000FF, "Blue")); + } + + void OpenWindow() + { + } + + void CloseWindow() + { + } + + void OnCheckboxChange(CF_ModelBase sender, CF_ChangeEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnCheckboxChange").Add(sender).Add(args.GetDebugName()); +#endif + + args.Continue = true; + } + + void OnChange(CF_ModelBase sender, CF_ChangeEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnChange").Add(sender).Add(args.GetDebugName()); +#endif + + args.Continue = BlockInput; + + ButtonText = TextInput; + NotifyPropertyChanged("ButtonText"); + } + + void OnClick(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnClick").Add(sender).Add(args.GetDebugName()); +#endif + + Index++; + + ButtonText = "Pressed " + Index + " times!"; + NotifyPropertyChanged("ButtonText"); + + // Dropdown.GetSelected() + CF_TestItemModel item = new CF_TestItemModel(this, null, Index); + Test.Insert(item); + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/mvvm/test.layout"; + } +}; + +class CF_TestColour : CF_Model +{ + int Hex; + + string Name; + + void CF_TestColour(int _hex, string _name) + { + Hex = _hex; + Name = _name; + } + + override string GetDebugName() + { + return Name; + } +}; + +class CF_TestItemModel : CF_Model +{ + string ButtonText = "NOT SET!"; + + ref CF_TestColour Colour; + + private CF_TestModel m_Parent; + + void CF_TestItemModel(CF_TestModel parent, CF_TestColour colour, int index) + { + m_Parent = parent; + + Colour = colour; + + ButtonText = "Press To Remove (" + index + ")"; + } + + void Remove(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "Remove").Add(sender).Add(args.GetDebugName()); +#endif + + int index = m_Parent.Test.Find(this); + m_Parent.Test.RemoveOrdered(index); + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/mvvm/testitem.layout"; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_Property.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_Property.c new file mode 100644 index 00000000..f9d9a67b --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_Property.c @@ -0,0 +1,412 @@ +class CF_MVVM_Property : CF_MVVM_PropertyBase +{ + protected CF_ModelBase m_Model; + protected CF_ViewModel m_ViewModel; + + protected CF_ObservableCollection m_Collection; + protected bool m_IsCollection; + + protected string m_Name; + protected string m_VariableName; + protected string m_ActualVariableName; + // Going 1 deep is more than enough. + + protected int m_VariableIndices[4]; + protected int m_IndexCount; + + protected string m_TypeConverterType; + protected ref CF_TypeConverterBase m_TypeConverter; + + void CF_MVVM_Property(CF_ViewModel handler, string name) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "CF_MVVM_Property").Add(handler).Add(name); +#endif + + m_ViewModel = handler; + m_Name = name; + } + + string SetVariableName(string variableName) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetVariableName").Add(variableName); +#endif + + m_IndexCount = -1; + m_VariableName = variableName; + + int colonSeperator = m_VariableName.IndexOf(":"); + if (colonSeperator != -1) + { + m_VariableName = variableName.Substring(0, colonSeperator); + m_TypeConverterType = variableName.Substring(colonSeperator + 1, variableName.Length() - colonSeperator - 1); + } + + m_ActualVariableName = m_VariableName; + + if (m_VariableName.IndexOf(".") == -1) + { + m_IndexCount = 0; + } + + return m_VariableName; + } + + string GetVariableName() + { + return m_VariableName; + } + + string GetName() + { + return m_Name; + } + + override string GetDebugName() + { + string str = "[" + ClassName() + "] "; + str += "Name=" + m_Name; + str += ", "; + str += "VariableName=" + m_VariableName; + str += ", "; + str += "IsCollection=" + m_IsCollection; + str += ", "; + str += "Collection=" + m_Collection; + str += ", "; + str += "Model=" + m_Model; + str += ", "; + str += "ViewModel=" + m_ViewModel; + str += ", "; + str += "TypeConverterType=" + m_TypeConverterType; + return str; + } + + void Link(CF_ModelBase model, typename variableType, CF_TypeConverterBase typeConverter) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_3(this, "Link").Add(/*model*/"").Add(/*variableType*/"").Add(/*typeConverter*/""); +#endif + + m_Model = model; + m_TypeConverter = typeConverter; + + m_IsCollection = variableType.IsInherited(CF_ObservableCollection); + if (m_IsCollection) + { + OnModel(new CF_EventArgs()); + + return; + } + + CF_TypeConverterBase typeConverterOverride; + if (m_TypeConverterType != string.Empty && Class.CastTo(typeConverterOverride, m_TypeConverterType.ToType().Spawn())) + { + m_TypeConverter = typeConverterOverride; + } + + EnScript.SetClassVar(m_ViewModel, "_" + m_Name, 0, this); + + OnModel(new CF_EventArgs()); + } + + void OnView(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnView").Add(args); +#endif + + if (m_IndexCount == -1) + AcquireIndices(); + + Param param = new Param2(m_Model, args); + g_Script.CallFunctionParams(m_ViewModel, "OnView_" + m_Name, null, param); + } + + void OnModel(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnModel").Add(args); +#endif + + if (m_IndexCount == -1) + AcquireIndices(); + + CF_EventArgs eventOverride = args; + + if (m_IsCollection) + { + CF_ObservableCollection _collection = CF_ObservableCollection.Cast(GetClass()); + + EnScript.SetClassVar(m_ViewModel, "_" + m_Name, 0, _collection); + + if (!args.Type().IsInherited(CF_CollectionEventArgs)) + { + if (_collection == m_Collection) + return; + + //UPDATE: will continue to notify, even if unlinked + // the previous instance may still be alive, if so, make sure it doesn't notify from now on + //if (m_Collection) + //{ + // m_Collection.Init(null); + //} + + if (_collection) + { + _collection.Init(m_Model, m_VariableName); + + CF_TypeConverterBase typeConverter = _collection.GetConverter(); + if (!typeConverter) + { + CF_Log.Error("Collection '%1.%2' has no assigned type converter!", "" + m_Model, m_VariableName); + return; + } + + CF_TypeConverterBase replacingTypeConverter; + if (m_TypeConverterType != string.Empty && Class.CastTo(replacingTypeConverter, m_TypeConverterType.ToType().Spawn())) + { + if (replacingTypeConverter.IsInherited(typeConverter.Type())) + { + _collection.OverrideConverter(replacingTypeConverter); + } + else + { + CF_Log.Warn("Overriding type converter '%1' doesn't inherit from '%2'. Using '%2'.", replacingTypeConverter.GetDebugName(), typeConverter.GetDebugName()); + } + } + } + + // The variable is no longer set to an instance, override event to reset UI + if (!_collection) + eventOverride = new CF_CollectionClearEventArgs(); + } + + m_Collection = _collection; + } + + Param param = new Param2(m_Model, eventOverride); + g_Script.CallFunctionParams(m_ViewModel, "OnModel_" + m_Name, null, param); + } + + override bool IsDefault() + { + return false; + } + + void AcquireIndices() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "AcquireIndices"); +#endif + + array tokens(); + m_VariableName.Split(".", tokens); + + typename type = m_Model.Type(); + + m_IndexCount = tokens.Count() - 1; + + for (int i = 0; i < m_IndexCount; i++) + { + bool success = false; + for (int j = 0; j < type.GetVariableCount(); j++) + { + if (type.GetVariableName(j) == tokens[i]) + { + m_VariableIndices[i] = j; + + type = type.GetVariableType(j); + + success = true; + + break; // break bad + } + } + + // couldn't find sub variable + if (!success) + return; + } + + m_ActualVariableName = tokens[m_IndexCount]; + } + + void Write() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "Write"); +#endif + + typename type = m_Model.Type(); + Class cls = m_Model; + + for (int i = 0; i < m_IndexCount; i++) + { + int idx = m_VariableIndices[i]; + type.GetVariableValue(cls, idx, cls); + type = type.GetVariableType(idx); + } + + m_TypeConverter.Write(cls, m_ActualVariableName); + } + + void Read() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "Read"); +#endif + + typename type = m_Model.Type(); + Class cls = m_Model; + + for (int i = 0; i < m_IndexCount; i++) + { + int idx = m_VariableIndices[i]; + type.GetVariableValue(cls, idx, cls); + type = type.GetVariableType(idx); + } + + m_TypeConverter.Read(cls, m_ActualVariableName); + } + + override void SetInt(int value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetInt").Add(value); +#endif + + m_TypeConverter.SetInt(value); + Write(); + } + + override int GetInt() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetInt"); +#endif + + Read(); + return m_TypeConverter.GetInt(); + } + + override void SetBool(bool value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetBool").Add(value); +#endif + + m_TypeConverter.SetBool(value); + Write(); + } + + override bool GetBool() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetBool"); +#endif + + Read(); + return m_TypeConverter.GetBool(); + } + + override void SetFloat(float value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetFloat").Add(value); +#endif + + m_TypeConverter.SetFloat(value); + Write(); + } + + override float GetFloat() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetFloat"); +#endif + + Read(); + return m_TypeConverter.GetFloat(); + } + + override void SetVector(vector value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetVector").Add(value); +#endif + + m_TypeConverter.SetVector(value); + Write(); + } + + override vector GetVector() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetVector"); +#endif + + Read(); + return m_TypeConverter.GetVector(); + } + + override void SetString(string value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetString").Add(value); +#endif + + m_TypeConverter.SetString(value); + Write(); + } + + override string GetString() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetString"); +#endif + + Read(); + return m_TypeConverter.GetString(); + } + + override void SetClass(Class value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetClass").Add(value); +#endif + + m_TypeConverter.SetClass(value); + Write(); + } + + override Class GetClass() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetClass"); +#endif + + Read(); + return m_TypeConverter.GetClass(); + } + + override void SetManaged(Managed value) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetManaged").Add(value); +#endif + + m_TypeConverter.SetManaged(value); + Write(); + } + + override Managed GetManaged() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetManaged"); +#endif + + Read(); + return m_TypeConverter.GetManaged(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_PropertyBase.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_PropertyBase.c new file mode 100644 index 00000000..0602eec8 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_PropertyBase.c @@ -0,0 +1,38 @@ +static ref CF_MVVM_PropertyBase g_CF_MVVM_DefaultProperty = new CF_MVVM_PropertyBase(); + +static CF_MVVM_PropertyBase CF_MVVM_GetDefaultProperty() +{ +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0("CF_MVVM_GetDefaultProperty"); +#endif + + if (!g_CF_MVVM_DefaultProperty) + g_CF_MVVM_DefaultProperty = new CF_MVVM_PropertyBase(); + return g_CF_MVVM_DefaultProperty; +} + +class CF_MVVM_PropertyBase : CF_TypeConverterBase +{ + bool IsDefault() + { + return true; + } + + override bool Read(Class instance, string variableName) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "Read").Add(instance).Add(variableName); +#endif + + return false; + } + + override bool Write(Class instance, string variableName) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "Write").Add(instance).Add(variableName); +#endif + + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_SubProperty.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_SubProperty.c new file mode 100644 index 00000000..e7621e14 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_SubProperty.c @@ -0,0 +1,38 @@ +class CF_MVVM_SubProperty : CF_MVVM_Property +{ + protected CF_ModelBase m_SubModel; + + void CF_MVVM_SubProperty(CF_ViewModel handler, string name) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "CF_MVVM_SubProperty").Add(handler).Add(name); +#endif + } + + void SetSubModel(CF_ModelBase subModel) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "SetSubModel").Add(subModel); +#endif + + m_SubModel = subModel; + } + + override void OnView(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnView").Add(args); +#endif + + g_Script.CallFunctionParams(m_SubModel, "OnView_" + m_Name, null, new Param2(m_Model, args)); + } + + override void OnModel(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnModel").Add(args); +#endif + + g_Script.CallFunctionParams(m_SubModel, "OnModel_" + m_Name, null, new Param2(m_Model, args)); + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_WidgetProperty.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_WidgetProperty.c new file mode 100644 index 00000000..3db70a6c --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/Properties/CF_MVVM_WidgetProperty.c @@ -0,0 +1,46 @@ +class CF_MVVM_WidgetProperty : CF_MVVM_Property +{ + void CF_MVVM_WidgetProperty(CF_ViewModel handler, string name) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "CF_MVVM_WidgetProperty").Add(handler).Add(name); +#endif + + SetVariableName(name); + } + + override void Link(CF_ModelBase model, typename variableType, CF_TypeConverterBase typeConverter) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_3(this, "Link").Add(/*model*/"").Add(/*variableType*/"").Add(/*typeConverter*/""); +#endif + + Widget widget = m_ViewModel.GetWidget(); + if (widget && widget.GetName() != m_VariableName) + widget = widget.FindAnyWidget(m_VariableName); + if (!widget) + return; + + if (!widget.IsInherited(variableType)) + { + CF_Log.Error("Widget '%1' was not of type '%2' in model '%3'.", "" + widget.ClassName(), variableType.ToString(), "" + model); + return; + } + + EnScript.SetClassVar(model, m_VariableName, 0, widget); + } + + override void OnView(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnView").Add(args); +#endif + } + + override void OnModel(/*notnull*/ CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnModel").Add(args); +#endif + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/TODO b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/TODO new file mode 100644 index 00000000..e69de29b diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_BaseListboxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_BaseListboxWidget.c new file mode 100644 index 00000000..e3c1b0cf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_BaseListboxWidget.c @@ -0,0 +1,67 @@ +class CF_BaseListboxWidget : CF_UIWidget +{ + reference string NumberItems; + reference string Selected; + + protected BaseListboxWidget _BaseListboxWidget; + protected CF_MVVM_PropertyBase _NumberItems = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Selected = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(NumberItems, "NumberItems"); + AddProperty(Selected, "Selected"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_BaseListboxWidget, w); + } + + void OnView_NumberItems(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_NumberItems").Add(sender).Add(args); +#endif + + _NumberItems.SetInt(_BaseListboxWidget.GetNumItems()); + } + + void OnModel_NumberItems(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_NumberItems").Add(sender).Add(args); +#endif + + OnView_NumberItems(m_Model, args); + } + + void OnView_Selected(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Selected").Add(sender).Add(args); +#endif + + _Selected.SetInt(_BaseListboxWidget.GetSelectedRow()); + } + + void OnModel_Selected(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Selected").Add(sender).Add(args); +#endif + + _BaseListboxWidget.SelectRow(_Selected.GetInt()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ButtonWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ButtonWidget.c new file mode 100644 index 00000000..86b95d93 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ButtonWidget.c @@ -0,0 +1,169 @@ +class CF_ButtonWidget : CF_UIWidget +{ + reference string State; + reference string Text; + reference string TextOffsetX; + reference string TextOffsetY; + reference string TextHorizontalAlignment; + reference string TextVerticalAlignment; + reference string TextProportion; + + protected ButtonWidget _ButtonWidget; + protected CF_MVVM_PropertyBase _State = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Text = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOffsetX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOffsetY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextHorizontalAlignment = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextVerticalAlignment = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextProportion = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(State, "State"); + AddProperty(Text, "Text"); + AddProperty(TextOffsetX, "TextOffsetX"); + AddProperty(TextOffsetY, "TextOffsetY"); + AddProperty(TextHorizontalAlignment, "TextHorizontalAlignment"); + AddProperty(TextVerticalAlignment, "TextVerticalAlignment"); + AddProperty(TextProportion, "TextProportion"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_ButtonWidget, w); + } + + void OnView_State(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_State").Add(sender).Add(args); +#endif + + _State.SetBool(_ButtonWidget.GetState()); + } + + void OnModel_State(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_State").Add(sender).Add(args); +#endif + + _ButtonWidget.SetState(_State.GetBool()); + } + + void OnView_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Text").Add(sender).Add(args); +#endif + } + + void OnModel_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Text").Add(sender).Add(args); +#endif + + _ButtonWidget.SetText(_Text.GetString()); + } + + void OnView_TextOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOffsetX").Add(sender).Add(args); +#endif + } + + void OnModel_TextOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOffsetX").Add(sender).Add(args); +#endif + + _ButtonWidget.SetTextOffset(_TextOffsetX.GetFloat(), _TextOffsetY.GetFloat()); + } + + void OnView_TextOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOffsetY").Add(sender).Add(args); +#endif + } + + void OnModel_TextOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOffsetY").Add(sender).Add(args); +#endif + + _ButtonWidget.SetTextOffset(_TextOffsetX.GetFloat(), _TextOffsetY.GetFloat()); + } + + void OnView_TextHorizontalAlignment(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextHorizontalAlignment").Add(sender).Add(args); +#endif + } + + void OnModel_TextHorizontalAlignment(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextHorizontalAlignment").Add(sender).Add(args); +#endif + + _ButtonWidget.SetTextHorizontalAlignment(_TextHorizontalAlignment.GetInt()); + } + + void OnView_TextVerticalAlignment(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextVerticalAlignment").Add(sender).Add(args); +#endif + } + + void OnModel_TextVerticalAlignment(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextVerticalAlignment").Add(sender).Add(args); +#endif + + _ButtonWidget.SetTextVerticalAlignment(_TextVerticalAlignment.GetInt()); + } + + void OnView_TextProportion(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextProportion").Add(sender).Add(args); +#endif + + _TextProportion.SetInt(_ButtonWidget.GetTextProportion()); + } + + void OnModel_TextProportion(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextProportion").Add(sender).Add(args); +#endif + + _ButtonWidget.SetTextProportion(_TextProportion.GetInt()); + } + + override bool WhatChanged(out string name, out string variable) + { + name = "State"; + variable = State; + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CanvasWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CanvasWidget.c new file mode 100644 index 00000000..0e7aef83 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CanvasWidget.c @@ -0,0 +1,62 @@ +class CF_CanvasLine : CF_ModelBase +{ + float x1; + float y1; + float x2; + float y2; + float width; + int color; +}; + +class CF_CanvasWidget : CF_Widget +{ + reference string Lines; + + protected CanvasWidget _CanvasWidget; + protected CF_ObservableCollection _Lines; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Lines, "Lines"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_CanvasWidget, w); + } + + void OnView_Lines(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Lines").Add(sender).Add(args); +#endif + } + + //! Automatically updated from Collection events so 'NotifyProperty' isn't needed to be called. + void OnModel_Lines(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Lines").Add(sender).Add(args); +#endif + + _CanvasWidget.Clear(); + for (int i = 0; i < _Lines.Count(); i++) + { + CF_CanvasLine line; + if (!Class.CastTo(line, _Lines.GetClass(i))) + break; + _CanvasWidget.DrawLine(line.x1, line.y1, line.x2, line.y2, line.width, line.color); + } + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CheckBoxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CheckBoxWidget.c new file mode 100644 index 00000000..ea3e83fe --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_CheckBoxWidget.c @@ -0,0 +1,72 @@ +class CF_CheckBoxWidget : CF_UIWidget +{ + reference string Text; + reference string Checked; + + protected CheckBoxWidget _CheckBoxWidget; + protected CF_MVVM_PropertyBase _Text = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Checked = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Text, "Text"); + AddProperty(Checked, "Checked"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_CheckBoxWidget, w); + } + + void OnView_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Text").Add(sender).Add(args); +#endif + } + + void OnModel_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Text").Add(sender).Add(args); +#endif + + _CheckBoxWidget.SetText(_Text.GetString()); + } + + void OnView_Checked(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Checked").Add(sender).Add(args); +#endif + + _Checked.SetBool(_CheckBoxWidget.IsChecked()); + } + + void OnModel_Checked(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Checked").Add(sender).Add(args); +#endif + + _CheckBoxWidget.SetChecked(_Checked.GetBool()); + } + + override bool WhatChanged(out string name, out string variable) + { + name = "Checked"; + variable = Checked; + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_EditBoxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_EditBoxWidget.c new file mode 100644 index 00000000..341aefad --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_EditBoxWidget.c @@ -0,0 +1,53 @@ +class CF_EditBoxWidget : CF_UIWidget +{ + reference string Text; + + protected EditBoxWidget _EditBoxWidget; + protected CF_MVVM_PropertyBase _Text = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Text, "Text"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_EditBoxWidget, w); + } + + void OnView_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Text").Add(sender).Add(args); +#endif + + _Text.SetString(_EditBoxWidget.GetText()); + } + + void OnModel_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Text").Add(sender).Add(args); +#endif + + _EditBoxWidget.SetText(_Text.GetString()); + } + + override bool WhatChanged(out string name, out string variable) + { + name = "Text"; + variable = Text; + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_FrameWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_FrameWidget.c new file mode 100644 index 00000000..5891f434 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_FrameWidget.c @@ -0,0 +1,57 @@ +class CF_FrameWidget : CF_Widget +{ + reference string SubModel; + reference string SubLayoutOverride; + + protected ref CF_ModelBase _SubModel; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(SubModel, "SubModel"); + } + + void OnView_SubModel(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_SubModel").Add(sender).Add(args); +#endif + + // Never called. + } + + void OnModel_SubModel(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_SubModel").Add(sender).Add(args); +#endif + + CF_ModelBase _model; + EnScript.GetClassVar(m_Model, SubModel, 0, _model); + + if (_SubModel == _model) + return; + + _SubModel = _model; + + if (_SubModel != null) + { + string layoutPath = SubLayoutOverride; + if (layoutPath == string.Empty) + { + g_Script.CallFunction(_SubModel, "GetLayoutFile", layoutPath, null); + } + + CF_MVVM.Create(_SubModel, layoutPath, _Widget); + } + else if (_SubModel) + { + CF_MVVM.Destroy(_SubModel); + } + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_GridSpacerWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_GridSpacerWidget.c new file mode 100644 index 00000000..8beb2f3d --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_GridSpacerWidget.c @@ -0,0 +1,3 @@ +class CF_GridSpacerWidget : CF_SpacerWidget +{ +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_HtmlWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_HtmlWidget.c new file mode 100644 index 00000000..17b58490 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_HtmlWidget.c @@ -0,0 +1,44 @@ +class CF_HtmlWidget : CF_TextWidget +{ + reference string File; + + protected HtmlWidget _HtmlWidget; + protected CF_MVVM_PropertyBase _File = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(File, "File"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_HtmlWidget, w); + } + + void OnView_File(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_File").Add(sender).Add(args); +#endif + } + + void OnModel_File(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_File").Add(sender).Add(args); +#endif + + _HtmlWidget.LoadFile(_File.GetString()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ImageWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ImageWidget.c new file mode 100644 index 00000000..99344b7e --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ImageWidget.c @@ -0,0 +1,126 @@ +class CF_ImageWidget : CF_Widget +{ + reference string Index; + reference string File; + reference string MaskFile; + reference string MaskProgress; + reference string MaskTransitionWidth; + + protected ImageWidget _ImageWidget; + protected CF_MVVM_PropertyBase _Index = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _File = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _MaskFile = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _MaskProgress = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _MaskTransitionWidth = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Index, "Index"); + AddProperty(File, "File"); + AddProperty(MaskFile, "MaskFile"); + AddProperty(MaskProgress, "MaskProgress"); + AddProperty(MaskTransitionWidth, "MaskTransitionWidth"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_ImageWidget, w); + } + + void OnView_Index(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Index").Add(sender).Add(args); +#endif + + _Index.SetInt(_ImageWidget.GetImage()); + } + + void OnModel_Index(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Index").Add(sender).Add(args); +#endif + + _ImageWidget.SetImage(_Index.GetInt()); + } + + void OnView_File(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_File").Add(sender).Add(args); +#endif + } + + void OnModel_File(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_File").Add(sender).Add(args); +#endif + + _ImageWidget.LoadImageFile(_Index.GetInt(), _File.GetString()); + } + + void OnView_MaskFile(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_MaskFile").Add(sender).Add(args); +#endif + } + + void OnModel_MaskFile(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_MaskFile").Add(sender).Add(args); +#endif + + _ImageWidget.LoadMaskTexture(_MaskFile.GetString()); + } + + void OnView_MaskProgress(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_MaskProgress").Add(sender).Add(args); +#endif + + _MaskProgress.SetFloat(_ImageWidget.GetMaskProgress()); + } + + void OnModel_MaskProgress(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_MaskProgress").Add(sender).Add(args); +#endif + + _ImageWidget.SetMaskProgress(_MaskProgress.GetFloat()); + } + + void OnView_MaskTransitionWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_MaskTransitionWidth").Add(sender).Add(args); +#endif + + _MaskTransitionWidth.SetFloat(_ImageWidget.GetMaskTransitionWidth()); + } + + void OnModel_MaskTransitionWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_MaskTransitionWidth").Add(sender).Add(args); +#endif + + _ImageWidget.SetMaskTransitionWidth(_MaskTransitionWidth.GetFloat()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ItemPreviewWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ItemPreviewWidget.c new file mode 100644 index 00000000..9bcae06b --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ItemPreviewWidget.c @@ -0,0 +1,147 @@ +class CF_ItemPreviewWidget : CF_Widget +{ + reference string Item; + reference string View; + reference string ModelOrientation; + reference string ModelPosition; + reference string ForceFlipEnable; + reference string ForceFlip; + + protected ItemPreviewWidget _ItemPreviewWidget; + protected CF_MVVM_PropertyBase _Item = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _View = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ModelOrientation = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ModelPosition = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ForceFlipEnable = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ForceFlip = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Item, "Item"); + AddProperty(View, "View"); + AddProperty(ModelOrientation, "ModelOrientation"); + AddProperty(ModelPosition, "ModelPosition"); + AddProperty(ForceFlipEnable, "ForceFlipEnable"); + AddProperty(ForceFlip, "ForceFlip"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_ItemPreviewWidget, w); + } + + void OnView_Item(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Item").Add(sender).Add(args); +#endif + + _Item.SetClass(_ItemPreviewWidget.GetItem()); + } + + void OnModel_Item(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Item").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetItem(EntityAI.Cast(_Item.GetClass())); + } + + void OnView_View(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_View").Add(sender).Add(args); +#endif + + _View.SetInt(_ItemPreviewWidget.GetView()); + } + + void OnModel_View(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_View").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetView(_View.GetInt()); + } + + void OnView_ModelOrientation(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnViewModel_Orientation").Add(sender).Add(args); +#endif + + _ModelOrientation.SetVector(_ItemPreviewWidget.GetModelOrientation()); + } + + void OnModel_ModelOrientation(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ModelOrientation").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetModelOrientation(_ModelOrientation.GetVector()); + } + + void OnView_ModelPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ModelPosition").Add(sender).Add(args); +#endif + + _ModelPosition.SetVector(_ItemPreviewWidget.GetModelPosition()); + } + + void OnModel_ModelPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ModelPosition").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetModelPosition(_ModelPosition.GetVector()); + } + + void OnView_ForceFlipEnable(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ForceFlipEnable").Add(sender).Add(args); +#endif + } + + void OnModel_ForceFlipEnable(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ForceFlipEnable").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetForceFlipEnable(_ForceFlipEnable.GetBool()); + } + + void OnView_ForceFlip(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ForceFlip").Add(sender).Add(args); +#endif + } + + void OnModel_ForceFlip(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ForceFlip").Add(sender).Add(args); +#endif + + _ItemPreviewWidget.SetForceFlip(_ForceFlip.GetBool()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MapWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MapWidget.c new file mode 100644 index 00000000..6f389dd9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MapWidget.c @@ -0,0 +1,104 @@ +class CF_MapUserMark : CF_ModelBase +{ + vector Position; + string Text; + int Color; + string TexturePath; +}; + +class CF_MapWidget : CF_BaseListboxWidget +{ + reference string UserMarks; + reference string CenterPosition; + reference string Scale; + + protected MapWidget _MapWidget; + protected CF_ObservableCollection _UserMarks; + protected CF_MVVM_PropertyBase _CenterPosition = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Scale = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(UserMarks, "UserMarks"); + AddProperty(CenterPosition, "CenterPosition"); + AddProperty(Scale, "Scale"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_MapWidget, w); + } + + void OnView_UserMarks(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_UserMarks").Add(sender).Add(args); +#endif + + OnModel_UserMarks(sender, args); + } + + void OnModel_UserMarks(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_UserMarks").Add(sender).Add(args); +#endif + + _MapWidget.ClearUserMarks(); + for (int i = 0; i < _UserMarks.Count(); i++) + { + CF_MapUserMark userMark; + if (!Class.CastTo(userMark, _UserMarks.GetClass(i))) + break; + + _MapWidget.AddUserMark(userMark.Position, userMark.Text, userMark.Color, userMark.TexturePath); + } + } + + void OnView_CenterPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_CenterPosition").Add(sender).Add(args); +#endif + + _CenterPosition.SetVector(_MapWidget.GetMapPos()); + } + + void OnModel_CenterPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_CenterPosition").Add(sender).Add(args); +#endif + + _MapWidget.SetMapPos(_CenterPosition.GetVector()); + } + + void OnView_Scale(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Scale").Add(sender).Add(args); +#endif + + _Scale.SetFloat(_MapWidget.GetScale()); + } + + void OnModel_Scale(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Scale").Add(sender).Add(args); +#endif + + _MapWidget.SetScale(_Scale.GetFloat()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineEditBoxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineEditBoxWidget.c new file mode 100644 index 00000000..5b883fe9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineEditBoxWidget.c @@ -0,0 +1,85 @@ +class CF_MultilineEditBoxWidget : CF_TextWidget +{ + reference string CarriageLine; + reference string CarriagePosition; + + protected MultilineEditBoxWidget _MultilineEditBoxWidget; + protected CF_MVVM_PropertyBase _CarriageLine = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _CarriagePosition = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(CarriageLine, "CarriageLine"); + AddProperty(CarriagePosition, "CarriagePosition"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_MultilineEditBoxWidget, w); + } + + override void OnView_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Text").Add(sender).Add(args); +#endif + + string value; + _MultilineEditBoxWidget.GetText(value); + _Text.SetString(value); + } + + void OnView_CarriageLine(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_CarriageLine").Add(sender).Add(args); +#endif + + _CarriageLine.SetInt(_MultilineEditBoxWidget.GetCarriageLine()); + } + + void OnModel_CarriageLine(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_CarriageLine").Add(sender).Add(args); +#endif + + OnView_CarriageLine(m_Model, args); + } + + void OnView_CarriagePosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_CarriagePosition").Add(sender).Add(args); +#endif + + _CarriagePosition.SetInt(_MultilineEditBoxWidget.GetCarriagePos()); + } + + void OnModel_CarriagePosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_CarriagePosition").Add(sender).Add(args); +#endif + + OnView_CarriagePosition(m_Model, args); + } + + override bool WhatChanged(out string name, out string variable) + { + name = "Text"; + variable = Text; + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineTextWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineTextWidget.c new file mode 100644 index 00000000..1487029c --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_MultilineTextWidget.c @@ -0,0 +1,14 @@ +class CF_MultilineTextWidget : CF_TextWidget +{ + protected MultilineTextWidget _MultilineTextWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_MultilineTextWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PanelWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PanelWidget.c new file mode 100644 index 00000000..6b7b786b --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PanelWidget.c @@ -0,0 +1,3 @@ +class CF_PanelWidget : CF_FrameWidget +{ +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PlayerPreviewWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PlayerPreviewWidget.c new file mode 100644 index 00000000..05751a7d --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_PlayerPreviewWidget.c @@ -0,0 +1,107 @@ +class CF_PlayerPreviewWidget : CF_Widget +{ + reference string Player; + reference string HandItem; + reference string ModelOrientation; + reference string ModelPosition; + + protected PlayerPreviewWidget _PlayerPreviewWidget; + protected CF_MVVM_PropertyBase _Player = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _HandItem = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ModelOrientation = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ModelPosition = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Player, "Player"); + AddProperty(HandItem, "HandItem"); + AddProperty(ModelOrientation, "ModelOrientation"); + AddProperty(ModelPosition, "ModelPosition"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_PlayerPreviewWidget, w); + } + + void OnView_Player(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Player").Add(sender).Add(args); +#endif + + _Player.SetClass(_PlayerPreviewWidget.GetDummyPlayer()); + } + + void OnModel_Player(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Player").Add(sender).Add(args); +#endif + + _PlayerPreviewWidget.SetPlayer(DayZPlayer.Cast(_Player.GetClass())); + } + + void OnView_HandItem(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_HandItem").Add(sender).Add(args); +#endif + } + + void OnModel_HandItem(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_HandItem").Add(sender).Add(args); +#endif + + _PlayerPreviewWidget.UpdateItemInHands(EntityAI.Cast(_HandItem.GetClass())); + } + + void OnView_ModelOrientation(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ModelOrientation").Add(sender).Add(args); +#endif + + _ModelOrientation.SetVector(_PlayerPreviewWidget.GetModelOrientation()); + } + + void OnModel_ModelOrientation(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ModelOrientation").Add(sender).Add(args); +#endif + + _PlayerPreviewWidget.SetModelOrientation(_ModelOrientation.GetVector()); + } + + void OnView_ModelPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ModelPosition").Add(sender).Add(args); +#endif + + _ModelPosition.SetVector(_PlayerPreviewWidget.GetModelPosition()); + } + + void OnModel_ModelPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ModelPosition").Add(sender).Add(args); +#endif + + _PlayerPreviewWidget.SetModelPosition(_ModelPosition.GetVector()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ProgressBarWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ProgressBarWidget.c new file mode 100644 index 00000000..d4fd5cbd --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ProgressBarWidget.c @@ -0,0 +1,14 @@ +class CF_ProgressBarWidget : CF_SimpleProgressBarWidget +{ + protected ProgressBarWidget _ProgressBarWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_ProgressBarWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RTTextureWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RTTextureWidget.c new file mode 100644 index 00000000..53234edf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RTTextureWidget.c @@ -0,0 +1,14 @@ +class CF_RTTextureWidget : CF_UIWidget +{ + protected RTTextureWidget _RTTextureWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_RTTextureWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RenderTargetWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RenderTargetWidget.c new file mode 100644 index 00000000..2408e0ad --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RenderTargetWidget.c @@ -0,0 +1,14 @@ +class CF_RenderTargetWidget : CF_UIWidget +{ + protected RenderTargetWidget _RenderTargetWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_RenderTargetWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RichTextWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RichTextWidget.c new file mode 100644 index 00000000..385bd5ff --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_RichTextWidget.c @@ -0,0 +1,124 @@ +class CF_RichTextWidget : CF_TextWidget +{ + reference string ContentHeight; + reference string ContentOffset; + reference string ContentSnapToLine; + reference string LineWidths; + + protected RichTextWidget _RichTextWidget; + protected CF_MVVM_PropertyBase _ContentHeight = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ContentOffset = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ContentSnapToLine = CF_MVVM_GetDefaultProperty(); + protected CF_ObservableCollection _LineWidths; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(ContentHeight, "ContentHeight"); + AddProperty(ContentOffset, "ContentOffset"); + AddProperty(ContentSnapToLine, "ContentSnapToLine"); + AddProperty(LineWidths, "LineWidths"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_RichTextWidget, w); + } + + override void OnModel_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Text").Add(sender).Add(args); +#endif + + super.OnModel_Text(sender, args); + + NotifyPropertyChanged(LineWidths, "LineWidths"); + } + + void OnView_ContentHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentHeight").Add(sender).Add(args); +#endif + + _ContentHeight.SetFloat(_RichTextWidget.GetContentHeight()); + } + + void OnModel_ContentHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentHeight").Add(sender).Add(args); +#endif + + OnView_ContentHeight(m_Model, args); + } + + void OnView_ContentOffset(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentOffset").Add(sender).Add(args); +#endif + + _ContentOffset.SetFloat(_RichTextWidget.GetContentOffset()); + } + + void OnModel_ContentOffset(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentOffset").Add(sender).Add(args); +#endif + + _RichTextWidget.SetContentOffset(_ContentSnapToLine.GetFloat(), _ContentSnapToLine.GetBool()); + } + + void OnView_ContentSnapToLine(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentSnapToLine").Add(sender).Add(args); +#endif + + OnModel_ContentSnapToLine(sender, args); + } + + void OnModel_ContentSnapToLine(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentSnapToLine").Add(sender).Add(args); +#endif + + _RichTextWidget.SetContentOffset(_ContentSnapToLine.GetFloat(), _ContentSnapToLine.GetBool()); + } + + void OnView_LineWidths(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_LineWidths").Add(sender).Add(args); +#endif + + _LineWidths.Clear(); + for (int i = 0; i < _RichTextWidget.GetNumLines(); i++) + { + _LineWidths.InsertFloat(_RichTextWidget.GetLineWidth(i)); + } + } + + void OnModel_LineWidths(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_LineWidths").Add(sender).Add(args); +#endif + + OnView_LineWidths(m_Model, args); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ScrollWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ScrollWidget.c new file mode 100644 index 00000000..aae4de96 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_ScrollWidget.c @@ -0,0 +1,180 @@ +class CF_ScrollWidget : CF_SpacerBaseWidget +{ + reference string ScrollbarWidth; + reference string ContentWidth; + reference string ContentHeight; + reference string HorizontalScrollPosition; + reference string VerticalScrollPosition; + reference string HorizontalScrollStep; + reference string VerticalScrollStep; + + protected ScrollWidget _ScrollWidget; + protected CF_MVVM_PropertyBase _ScrollbarWidth = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ContentWidth = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ContentHeight = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _HorizontalScrollPosition = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _VerticalScrollPosition = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _HorizontalScrollStep = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _VerticalScrollStep = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(ScrollbarWidth, "ScrollbarWidth"); + AddProperty(ContentWidth, "ContentWidth"); + AddProperty(ContentHeight, "ContentHeight"); + AddProperty(HorizontalScrollPosition, "HorizontalScrollPosition"); + AddProperty(VerticalScrollPosition, "VerticalScrollPosition"); + AddProperty(HorizontalScrollStep, "HorizontalScrollStep"); + AddProperty(VerticalScrollStep, "VerticalScrollStep"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_ScrollWidget, w); + } + + void OnView_ScrollbarWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ScrollbarWidth").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, ScrollbarWidth, 0, _ScrollWidget.GetScrollbarWidth()); + } + + void OnModel_ScrollbarWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ScrollbarWidth").Add(sender).Add(args); +#endif + + OnView_ScrollbarWidth(m_Model, args); + } + + void OnView_ContentWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentWidth").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, ContentWidth, 0, _ScrollWidget.GetContentWidth()); + } + + void OnModel_ContentWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentWidth").Add(sender).Add(args); +#endif + + OnView_ContentWidth(m_Model, args); + } + + void OnView_ContentHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentHeight").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, ContentHeight, 0, _ScrollWidget.GetContentHeight()); + } + + void OnModel_ContentHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentHeight").Add(sender).Add(args); +#endif + + OnView_ContentHeight(m_Model, args); + } + + void OnView_HorizontalScrollPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_HorizontalScrollPosition").Add(sender).Add(args); +#endif + + float _value = _ScrollWidget.GetHScrollPos(); + EnScript.SetClassVar(m_Model, HorizontalScrollPosition, 0, _value); + } + + void OnModel_HorizontalScrollPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_HorizontalScrollPosition").Add(sender).Add(args); +#endif + + float _value; + EnScript.GetClassVar(m_Model, HorizontalScrollPosition, 0, _value); + _ScrollWidget.HScrollToPos(_value); + } + + void OnView_VerticalScrollPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_VerticalScrollPosition").Add(sender).Add(args); +#endif + + float _value = _ScrollWidget.GetVScrollPos(); + EnScript.SetClassVar(m_Model, VerticalScrollPosition, 0, _value); + } + + void OnModel_VerticalScrollPosition(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_VerticalScrollPosition").Add(sender).Add(args); +#endif + + float _value; + EnScript.GetClassVar(m_Model, VerticalScrollPosition, 0, _value); + _ScrollWidget.VScrollToPos(_value); + } + + void OnView_HorizontalScrollStep(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_HorizontalScrollStep").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, HorizontalScrollStep, 0, _HorizontalScrollStep); + } + + void OnModel_HorizontalScrollStep(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_HorizontalScrollStep").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, HorizontalScrollStep, 0, _HorizontalScrollStep); + //_ScrollWidget.HScrollStep(_HorizontalScrollStep); + } + + void OnView_VerticalScrollStep(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_VerticalScrollStep").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, VerticalScrollStep, 0, _VerticalScrollStep); + } + + void OnModel_VerticalScrollStep(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_VerticalScrollStep").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, VerticalScrollStep, 0, _VerticalScrollStep); + //_ScrollWidget.VScrollStep(_VerticalScrollStep); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleListboxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleListboxWidget.c new file mode 100644 index 00000000..f509bb7a --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleListboxWidget.c @@ -0,0 +1,14 @@ +class CF_SimpleListboxWidget : CF_BaseListboxWidget +{ + protected SimpleListboxWidget _SimpleListboxWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_SimpleListboxWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleProgressBarWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleProgressBarWidget.c new file mode 100644 index 00000000..191bd7bf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SimpleProgressBarWidget.c @@ -0,0 +1,91 @@ +class CF_SimpleProgressBarWidget : CF_UIWidget +{ + reference string Min; + reference string Max; + reference string Current; + + protected SimpleProgressBarWidget _SimpleProgressBarWidget; + protected CF_MVVM_PropertyBase _Min = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Max = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Current = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Min, "Min"); + AddProperty(Max, "Max"); + AddProperty(Current, "Current"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_SimpleProgressBarWidget, w); + } + + void OnView_Min(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Min").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Min, 0, _SimpleProgressBarWidget.GetMin()); + } + + void OnModel_Min(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Min").Add(sender).Add(args); +#endif + + OnView_Min(m_Model, args); + } + + void OnView_Max(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Max").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Max, 0, _SimpleProgressBarWidget.GetMax()); + } + + void OnModel_Max(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Max").Add(sender).Add(args); +#endif + + OnView_Max(m_Model, args); + } + + void OnView_Current(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Current").Add(sender).Add(args); +#endif + + float _value = _SimpleProgressBarWidget.GetCurrent(); + EnScript.SetClassVar(m_Model, Current, 0, _value); + } + + void OnModel_Current(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Current").Add(sender).Add(args); +#endif + + float _value; + EnScript.GetClassVar(m_Model, Current, 0, _value); + _SimpleProgressBarWidget.SetCurrent(_value); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SliderWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SliderWidget.c new file mode 100644 index 00000000..9bd5efa3 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SliderWidget.c @@ -0,0 +1,95 @@ +class CF_SliderWidget : CF_UIWidget +{ + reference string Min; + reference string Max; + reference string Current; + + protected SliderWidget _SliderWidget; + protected CF_MVVM_PropertyBase _Min = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Max = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Current = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Min, "Min"); + AddProperty(Max, "Max"); + AddProperty(Current, "Current"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_SliderWidget, w); + } + + void OnView_Min(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Min").Add(sender).Add(args); +#endif + + _Min.SetInt(_SliderWidget.GetMin()); + } + + void OnModel_Min(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Min").Add(sender).Add(args); +#endif + + //OnView_Min(m_Model, args); + } + + void OnView_Max(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Max").Add(sender).Add(args); +#endif + + _Max.SetInt(_SliderWidget.GetMax()); + } + + void OnModel_Max(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Max").Add(sender).Add(args); +#endif + + //OnView_Max(m_Model, args); + } + + void OnView_Current(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Current").Add(sender).Add(args); +#endif + + _Current.SetFloat(_SliderWidget.GetCurrent()); + } + + void OnModel_Current(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Current").Add(sender).Add(args); +#endif + + _SliderWidget.SetCurrent(_Current.GetFloat()); + } + + override bool WhatChanged(out string name, out string variable) + { + name = "Current"; + variable = Current; + return true; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerBaseWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerBaseWidget.c new file mode 100644 index 00000000..8d06d9d7 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerBaseWidget.c @@ -0,0 +1,89 @@ +class CF_SpacerBaseWidget : CF_UIWidget +{ + protected SpacerBaseWidget _SpacerBaseWidget; + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_SpacerBaseWidget, w); + } + + override void OnModel_Children_InsertAt(CF_ObservableCollection sender, CF_CollectionInsertAtEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_InsertAt").Add(sender).Add(args); +#endif + + CF_TypeConverterBase conv = sender.GetConverter(args.Index); + if (!conv) + return; + + CF_ModelBase model = CF_ModelBase.Cast(conv.GetClass()); + + string layout; + g_Script.CallFunction(model, "GetLayoutFile", layout, null); + + CF_MVVM.Create(model, layout); + if (args.Index == sender.Count()) + return; + + Widget widget = CF_MVVM.GetPropertyCollection(model).GetWidget(); + if (!widget) + return; + + Widget append = GetChildWidgetAt(args.Index); + _SpacerBaseWidget.AddChildAfter(widget, append); + } + + override void OnModel_Children_Set(CF_ObservableCollection sender, CF_CollectionSetEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Set").Add(sender).Add(args); +#endif + + CF_TypeConverterBase conv = sender.GetConverter(args.Index); + if (!conv) + return; + + CF_ModelBase model = CF_ModelBase.Cast(conv.GetClass()); + + string layout; + g_Script.CallFunction(model, "GetLayoutFile", layout, null); + + CF_MVVM.Create(model, layout); + + Widget widget = CF_MVVM.GetPropertyCollection(model).GetWidget(); + if (!widget) + return; + + Widget append = GetChildWidgetAt(args.Index); + _SpacerBaseWidget.AddChildAfter(widget, append); + _SpacerBaseWidget.RemoveChild(append); + } + + override void OnModel_Children_Swap(CF_ObservableCollection sender, CF_CollectionSwapEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Children_Swap").Add(sender).Add(args); +#endif + + if (args.IndexA == args.IndexB) + return; + + Widget widgetA = GetChildWidgetAt(args.IndexA); + Widget widgetB = GetChildWidgetAt(args.IndexB); + + Widget widgetA_B = GetChildWidgetAt(args.IndexA - 1); + Widget widgetB_B = GetChildWidgetAt(args.IndexB - 1); + + _SpacerBaseWidget.RemoveChild(widgetA); + _SpacerBaseWidget.RemoveChild(widgetB); + + _SpacerBaseWidget.AddChildAfter(widgetB, widgetA_B); + _SpacerBaseWidget.AddChildAfter(widgetA, widgetB_B); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerWidget.c new file mode 100644 index 00000000..ccf21bdf --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_SpacerWidget.c @@ -0,0 +1,73 @@ +class CF_SpacerWidget : CF_SpacerBaseWidget +{ + reference string ContentAlignmentHorizontal; + reference string ContentAlignmentVertical; + + protected SpacerWidget _SpacerWidget; + protected CF_MVVM_PropertyBase _ContentAlignmentHorizontal = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ContentAlignmentVertical = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(ContentAlignmentHorizontal, "ContentAlignmentHorizontal"); + AddProperty(ContentAlignmentVertical, "ContentAlignmentVertical"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_SpacerWidget, w); + } + + void OnView_ContentAlignmentHorizontal(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentAlignmentHorizontal").Add(sender).Add(args); +#endif + + int _contentAlignmentH = _SpacerWidget.GetContentAlignmentH(); + EnScript.SetClassVar(m_Model, ContentAlignmentHorizontal, 0, _contentAlignmentH); + } + + void OnModel_ContentAlignmentHorizontal(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentAlignmentHorizontal").Add(sender).Add(args); +#endif + + int _contentAlignmentH; + EnScript.GetClassVar(m_Model, ContentAlignmentHorizontal, 0, _contentAlignmentH); + _SpacerWidget.SetContentAlignmentH(_contentAlignmentH); + } + + void OnView_ContentAlignmentVertical(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ContentAlignmentVertical").Add(sender).Add(args); +#endif + + int _contentAlignmentV = _SpacerWidget.GetContentAlignmentV(); + EnScript.SetClassVar(m_Model, ContentAlignmentVertical, 0, _contentAlignmentV); + } + + void OnModel_ContentAlignmentVertical(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ContentAlignmentVertical").Add(sender).Add(args); +#endif + + int _contentAlignmentV; + EnScript.GetClassVar(m_Model, ContentAlignmentVertical, 0, _contentAlignmentV); + _SpacerWidget.SetContentAlignmentV(_contentAlignmentV); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextListboxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextListboxWidget.c new file mode 100644 index 00000000..e8664c5a --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextListboxWidget.c @@ -0,0 +1,82 @@ +class CF_TextListboxItem : CF_ModelBase +{ + string Text; + Class Data; + int Color; +}; + +class CF_TextListboxWidget : CF_BaseListboxWidget +{ + reference string Items; + + protected TextListboxWidget _TextListboxWidget; + protected ref CF_ObservableCollection _Items; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Items, "Items"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_TextListboxWidget, w); + } + + void OnView_Items(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Items").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Items, 0, _Items); + } + + void OnModel_Items(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Items").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, Items, 0, _Items); + + CF_TextListboxItem selectedItem; + int selectedRow = _TextListboxWidget.GetSelectedRow(); + if (selectedRow != -1) + { + _TextListboxWidget.GetItemData(selectedRow, 0, selectedItem); + } + + selectedRow = -1; + + _TextListboxWidget.ClearItems(); + + for (int i = 0; i < _Items.Count(); i++) + { + CF_TextListboxItem item; + if (!Class.CastTo(item, _Items.GetConverter(i).GetClass())) + break; + + _TextListboxWidget.AddItem(item.Text, item, 0); + _TextListboxWidget.SetItemColor(i, 0, item.Color); + + if (selectedItem && selectedItem == item) + { + selectedRow = i; + } + } + + _TextListboxWidget.SelectRow(i); + NotifyPropertyChanged(Selected, "Selected"); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextWidget.c new file mode 100644 index 00000000..b8aca90e --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_TextWidget.c @@ -0,0 +1,428 @@ +class CF_TextWidget : CF_Widget +{ + reference string Text; + reference string TextSpacingHorizontal; + reference string TextSpacingVertical; + reference string TextExactSize; + reference string TextOffsetX; + reference string TextOffsetY; + reference string TextOutlineSize; + reference string TextOutlineColor; + reference string TextShadowSize; + reference string TextShadowColor; + reference string TextShadowOpacity; + reference string TextShadowOffsetX; + reference string TextShadowOffsetY; + reference string TextItalic; + reference string TextBold; + reference string TextSizeX; + reference string TextSizeY; + reference string TextProportion; + + protected TextWidget _TextWidget; + protected CF_MVVM_PropertyBase _Text = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextSpacingHorizontal = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextSpacingVertical = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextExactSize = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOffsetX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOffsetY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOutlineSize = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOutlineColor = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowSize = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowColor = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOpacity = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOffsetX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOffsetY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextItalic = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextBold = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextSizeX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextSizeY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextProportion = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Text, "Text"); + AddProperty(TextSpacingHorizontal, "TextSpacingHorizontal"); + AddProperty(TextSpacingVertical, "TextSpacingVertical"); + AddProperty(TextExactSize, "TextExactSize"); + AddProperty(TextOffsetX, "TextOffsetX"); + AddProperty(TextOffsetY, "TextOffsetY"); + AddProperty(TextOutlineSize, "TextOutlineSize"); + AddProperty(TextOutlineColor, "TextOutlineColor"); + AddProperty(TextShadowSize, "TextShadowSize"); + AddProperty(TextShadowColor, "TextShadowColor"); + AddProperty(TextShadowOpacity, "TextShadowOpacity"); + AddProperty(TextShadowOffsetX, "TextShadowOffsetX"); + AddProperty(TextShadowOffsetY, "TextShadowOffsetY"); + AddProperty(TextItalic, "TextItalic"); + AddProperty(TextBold, "TextBold"); + AddProperty(TextSizeX, "TextSizeX"); + AddProperty(TextSizeY, "TextSizeY"); + AddProperty(TextProportion, "TextProportion"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_TextWidget, w); + } + + void OnView_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Text").Add(sender).Add(args); +#endif + + OnModel_Text(sender, args); + } + + void OnModel_Text(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Text").Add(sender).Add(args); +#endif + + _TextWidget.SetText(_Text.GetString()); + } + + void OnView_TextSpacingHorizontal(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextSpacingHorizontal").Add(sender).Add(args); +#endif + + OnModel_TextSpacingHorizontal(sender, args); + } + + void OnModel_TextSpacingHorizontal(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextSpacingHorizontal").Add(sender).Add(args); +#endif + + _TextWidget.SetTextSpacing(_TextSpacingHorizontal.GetInt(), _TextSpacingVertical.GetInt()); + } + + void OnView_TextSpacingVertical(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextSpacingVertical").Add(sender).Add(args); +#endif + + OnModel_TextSpacingVertical(sender, args); + } + + void OnModel_TextSpacingVertical(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextSpacingVertical").Add(sender).Add(args); +#endif + + _TextWidget.SetTextSpacing(_TextSpacingHorizontal.GetInt(), _TextSpacingVertical.GetInt()); + } + + void OnView_TextExactSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextExactSize").Add(sender).Add(args); +#endif + + OnModel_TextExactSize(sender, args); + } + + void OnModel_TextExactSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextExactSize").Add(sender).Add(args); +#endif + + _TextWidget.SetTextExactSize(_TextExactSize.GetInt()); + } + + void OnView_TextOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOffsetX").Add(sender).Add(args); +#endif + + OnModel_TextOffsetX(sender, args); + } + + void OnModel_TextOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOffsetX").Add(sender).Add(args); +#endif + + _TextWidget.SetTextOffset(_TextOffsetX.GetInt(), _TextOffsetY.GetInt()); + } + + void OnView_TextOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOffsetY").Add(sender).Add(args); +#endif + + OnModel_TextOffsetY(sender, args); + } + + void OnModel_TextOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOffsetY").Add(sender).Add(args); +#endif + + _TextWidget.SetTextOffset(_TextOffsetX.GetInt(), _TextOffsetY.GetInt()); + } + + void OnView_TextOutlineSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOutlineSize").Add(sender).Add(args); +#endif + + _TextOutlineSize.SetInt(_TextWidget.GetOutlineSize()); + } + + void OnModel_TextOutlineSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOutlineSize").Add(sender).Add(args); +#endif + + _TextWidget.SetOutline(_TextOutlineSize.GetInt(), _TextWidget.GetOutlineColor()); + } + + void OnView_TextOutlineColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOutlineColor").Add(sender).Add(args); +#endif + + _TextOutlineColor.SetInt(_TextWidget.GetOutlineColor()); + } + + void OnModel_TextOutlineColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOutlineColor").Add(sender).Add(args); +#endif + + _TextWidget.SetOutline(_TextWidget.GetOutlineSize(), _TextOutlineColor.GetInt()); + } + + void OnView_TextShadowSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowSize").Add(sender).Add(args); +#endif + + _TextShadowSize.SetFloat(_TextWidget.GetShadowSize()); + } + + void OnModel_TextShadowSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowSize").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextWidget.SetShadow(_TextShadowSize.GetInt(), _TextWidget.GetShadowColor(), _TextWidget.GetShadowOpacity(), _sx, _sy); + } + + void OnView_TextShadowColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowColor").Add(sender).Add(args); +#endif + + _TextShadowColor.SetInt(_TextWidget.GetShadowColor()); + } + + void OnModel_TextShadowColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowColor").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextWidget.SetShadow(_TextWidget.GetShadowSize(), _TextShadowColor.GetInt(), _TextWidget.GetShadowOpacity(), _sx, _sy); + } + + void OnView_TextShadowOpacity(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOpacity").Add(sender).Add(args); +#endif + + _TextShadowOpacity.SetFloat(_TextWidget.GetShadowOpacity()); + } + + void OnModel_TextShadowOpacity(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOpacity").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextWidget.SetShadow(_TextWidget.GetShadowSize(), _TextWidget.GetShadowColor(), _TextShadowOpacity.GetFloat(), _sx, _sy); + } + + void OnView_TextShadowOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOffsetX").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextShadowOffsetX.SetFloat(_sx); + } + + void OnModel_TextShadowOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOffsetX").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextWidget.SetShadow(_TextWidget.GetShadowSize(), _TextWidget.GetShadowColor(), _TextWidget.GetShadowOpacity(), _TextShadowOffsetX.GetFloat(), _sy); + } + + void OnView_TextShadowOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOffsetY").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextShadowOffsetY.SetFloat(_sy); + } + + void OnModel_TextShadowOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOffsetY").Add(sender).Add(args); +#endif + + float _sx, _sy; + _TextWidget.GetShadowOffset(_sx, _sy); + + _TextWidget.SetShadow(_TextWidget.GetShadowSize(), _TextWidget.GetShadowColor(), _TextWidget.GetShadowOpacity(), _sx, _TextShadowOffsetY.GetFloat()); + } + + void OnView_TextItalic(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextItalic").Add(sender).Add(args); +#endif + + _TextItalic.SetBool(_TextWidget.GetItalic()); + } + + void OnModel_TextItalic(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextItalic").Add(sender).Add(args); +#endif + + _TextWidget.SetItalic(_TextItalic.GetBool()); + } + + void OnView_TextBold(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextBold").Add(sender).Add(args); +#endif + + _TextBold.SetBool(_TextWidget.GetBold()); + } + + void OnModel_TextBold(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextBold").Add(sender).Add(args); +#endif + + _TextWidget.SetBold(_TextBold.GetBool()); + } + + void OnView_TextSizeX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextSizeX").Add(sender).Add(args); +#endif + + int _x, _y; + _TextWidget.GetTextSize(_x, _y); + _TextSizeX.SetInt(_x); + } + + void OnModel_TextSizeX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextSizeX").Add(sender).Add(args); +#endif + + OnView_TextSizeX(m_Model, args); + } + + void OnView_TextSizeY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextSizeY").Add(sender).Add(args); +#endif + + int _x, _y; + _TextWidget.GetTextSize(_x, _y); + _TextSizeY.SetInt(_y); + } + + void OnModel_TextSizeY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextSizeY").Add(sender).Add(args); +#endif + + OnView_TextSizeY(m_Model, args); + } + + void OnView_TextProportion(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextProportion").Add(sender).Add(args); +#endif + + _TextProportion.SetFloat(_TextWidget.GetTextProportion()); + } + + void OnModel_TextProportion(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextProportion").Add(sender).Add(args); +#endif + + _TextWidget.SetTextProportion(_TextProportion.GetFloat()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_UIWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_UIWidget.c new file mode 100644 index 00000000..c535caba --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_UIWidget.c @@ -0,0 +1,235 @@ +class CF_UIWidget : CF_Widget +{ + reference string TextColor; + reference string TextOutlineSize; + reference string TextOutlineColor; + reference string TextShadowSize; + reference string TextShadowColor; + reference string TextShadowOpacity; + reference string TextShadowOffsetX; + reference string TextShadowOffsetY; + reference string TextItalic; + reference string TextBold; + + protected UIWidget _UIWidget; + protected CF_MVVM_PropertyBase _TextColor = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOutlineSize = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextOutlineColor = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowSize = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowColor = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOpacity = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOffsetX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextShadowOffsetY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextItalic = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _TextBold = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(TextColor, "TextColor"); + AddProperty(TextOutlineSize, "TextOutlineSize"); + AddProperty(TextOutlineColor, "TextOutlineColor"); + AddProperty(TextShadowSize, "TextShadowSize"); + AddProperty(TextShadowColor, "TextShadowColor"); + AddProperty(TextShadowOpacity, "TextShadowOpacity"); + AddProperty(TextShadowOffsetX, "TextShadowOffsetX"); + AddProperty(TextShadowOffsetY, "TextShadowOffsetY"); + AddProperty(TextItalic, "TextItalic"); + AddProperty(TextBold, "TextBold"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_UIWidget, w); + } + + void OnView_TextColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextColor").Add(sender).Add(args); +#endif + + OnModel_TextColor(sender, args); + } + + void OnModel_TextColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextColor").Add(sender).Add(args); +#endif + + _UIWidget.SetTextColor(_TextColor.GetInt()); + } + + void OnView_TextOutlineSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOutlineSize").Add(sender).Add(args); +#endif + + _TextOutlineSize.SetFloat(_UIWidget.GetTextOutlineSize()); + } + + void OnModel_TextOutlineSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOutlineSize").Add(sender).Add(args); +#endif + + _UIWidget.SetTextOutline(_TextOutlineSize.GetFloat(), _UIWidget.GetTextOutlineColor()); + } + + void OnView_TextOutlineColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextOutlineColor").Add(sender).Add(args); +#endif + + _TextOutlineColor.SetFloat(_UIWidget.GetTextOutlineColor()); + } + + void OnModel_TextOutlineColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextOutlineColor").Add(sender).Add(args); +#endif + + _UIWidget.SetTextOutline(_UIWidget.GetTextOutlineSize(), _TextOutlineColor.GetFloat()); + } + + void OnView_TextShadowSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowSize").Add(sender).Add(args); +#endif + + _TextShadowSize.SetFloat(_UIWidget.GetTextShadowSize()); + } + + void OnModel_TextShadowSize(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowSize").Add(sender).Add(args); +#endif + + _UIWidget.SetTextShadow(_TextShadowSize.GetFloat(), _UIWidget.GetTextShadowColor(), _UIWidget.GetTextShadowOpacity(), _UIWidget.GetTextShadowOffsetX(), _UIWidget.GetTextShadowOffsetY()); + } + + void OnView_TextShadowColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowColor").Add(sender).Add(args); +#endif + + _TextShadowColor.SetFloat(_UIWidget.GetTextShadowColor()); + } + + void OnModel_TextShadowColor(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowColor").Add(sender).Add(args); +#endif + + _UIWidget.SetTextShadow(_UIWidget.GetTextShadowSize(), _TextShadowColor.GetFloat(), _UIWidget.GetTextShadowOpacity(), _UIWidget.GetTextShadowOffsetX(), _UIWidget.GetTextShadowOffsetY()); + } + + void OnView_TextShadowOpacity(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOpacity").Add(sender).Add(args); +#endif + + _TextShadowOpacity.SetFloat(_UIWidget.GetTextShadowOpacity()); + } + + void OnModel_TextShadowOpacity(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOpacity").Add(sender).Add(args); +#endif + + _UIWidget.SetTextShadow(_UIWidget.GetTextShadowSize(), _UIWidget.GetTextShadowColor(), _TextShadowOpacity.GetFloat(), _UIWidget.GetTextShadowOffsetX(), _UIWidget.GetTextShadowOffsetY()); + } + + void OnView_TextShadowOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOffsetX").Add(sender).Add(args); +#endif + + _TextShadowOffsetX.SetFloat(_UIWidget.GetTextShadowOffsetX()); + } + + void OnModel_TextShadowOffsetX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOffsetX").Add(sender).Add(args); +#endif + + _UIWidget.SetTextShadow(_UIWidget.GetTextShadowSize(), _UIWidget.GetTextShadowColor(), _UIWidget.GetTextShadowOpacity(), _TextShadowOffsetX.GetFloat(), _UIWidget.GetTextShadowOffsetY()); + } + + void OnView_TextShadowOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextShadowOffsetY").Add(sender).Add(args); +#endif + + _TextShadowOffsetY.SetFloat(_UIWidget.GetTextShadowOffsetY()); + } + + void OnModel_TextShadowOffsetY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextShadowOffsetY").Add(sender).Add(args); +#endif + + _UIWidget.SetTextShadow(_UIWidget.GetTextShadowSize(), _UIWidget.GetTextShadowColor(), _UIWidget.GetTextShadowOpacity(), _UIWidget.GetTextShadowOffsetX(), _TextShadowOffsetY.GetFloat()); + } + + void OnView_TextItalic(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextItalic").Add(sender).Add(args); +#endif + + _TextItalic.SetBool(_UIWidget.GetTextItalic()); + } + + void OnModel_TextItalic(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextItalic").Add(sender).Add(args); +#endif + + _UIWidget.SetTextItalic(_TextItalic.GetBool()); + } + + void OnView_TextBold(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_TextBold").Add(sender).Add(args); +#endif + + _TextBold.SetBool(_UIWidget.GetTextBold()); + } + + void OnModel_TextBold(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_TextBold").Add(sender).Add(args); +#endif + + _UIWidget.SetTextBold(_TextBold.GetBool()); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_VideoWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_VideoWidget.c new file mode 100644 index 00000000..98d115ff --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_VideoWidget.c @@ -0,0 +1,97 @@ +class CF_VideoPath +{ + string Path; + int SoundScene; +}; + +class CF_VideoWidget : CF_Widget +{ + reference string Path; + reference string Command; + reference string Subtitles; + + protected VideoWidget _VideoWidget; + protected ref CF_VideoPath _Path = new CF_VideoPath(); + protected VideoCommand _Command; + protected bool _Subtitles; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Path, "Path"); + AddProperty(Command, "Command"); + AddProperty(Subtitles, "Subtitles"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_VideoWidget, w); + } + + void OnView_Path(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Path").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Path, 0, _Path); + } + + void OnModel_Path(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Path").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, Path, 0, _Path); + _VideoWidget.LoadVideo(_Path.Path, _Path.SoundScene); + } + + void OnView_Command(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Command").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Command, 0, _Command); + } + + void OnModel_Command(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Command").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, Command, 0, _Command); + _VideoWidget.Play(_Command); + } + + void OnView_Subtitles(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Subtitles").Add(sender).Add(args); +#endif + + EnScript.SetClassVar(m_Model, Subtitles, 0, _Subtitles); + } + + void OnModel_Subtitles(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Subtitles").Add(sender).Add(args); +#endif + + EnScript.GetClassVar(m_Model, Subtitles, 0, _Subtitles); + _VideoWidget.DisableSubtitles(_Subtitles); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_Widget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_Widget.c new file mode 100644 index 00000000..32e0ed15 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_Widget.c @@ -0,0 +1,601 @@ +/** + * Base class for widget properties + */ + +class CF_Widget : CF_ViewModel +{ + reference string Name; // [R/W] + reference string Visible; // [R/W] + reference string Enabled; // [R/W] + reference string Flags; // [R/W] + reference string Sort; // [R/W] + reference string Position; // [R/W] + reference string PositionX; // [R/W] + reference string PositionY; // [R/W] + reference string Size; // [R/W] + reference string Width; // [R/W] + reference string Height; // [R/W] + reference string ScreenPositionX; // [R/W] + reference string ScreenPositionY; // [R/W] + reference string ScreenWidth; // [R] + reference string ScreenHeight; // [R] + reference string Color; // [R/W] + reference string Roll; // [R/W] + reference string Pitch; // [R/W] + reference string Yaw; // [R/W] + reference string Alpha; // [R/W] + + protected Widget _Widget; + protected CF_MVVM_PropertyBase _Name = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Visible = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Enabled = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Flags = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Sort = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Position = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _PositionX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _PositionY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Size = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Width = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Height = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ScreenPositionX = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ScreenPositionY = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ScreenWidth = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _ScreenHeight = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Color = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Roll = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Pitch = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Yaw = CF_MVVM_GetDefaultProperty(); + protected CF_MVVM_PropertyBase _Alpha = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Name, "Name"); + AddProperty(Visible, "Visible"); + AddProperty(Enabled, "Enabled"); + AddProperty(Flags, "Flags"); + AddProperty(Sort, "Sort"); + AddProperty(PositionX, "PositionX"); + AddProperty(PositionY, "PositionY"); + AddProperty(Width, "Width"); + AddProperty(Height, "Height"); + AddProperty(ScreenPositionX, "ScreenPositionX"); + AddProperty(ScreenPositionY, "ScreenPositionY"); + AddProperty(ScreenWidth, "ScreenWidth"); + AddProperty(ScreenHeight, "ScreenHeight"); + AddProperty(Color, "Color"); + AddProperty(Roll, "Roll"); + AddProperty(Pitch, "Pitch"); + AddProperty(Yaw, "Yaw"); + AddProperty(Alpha, "Alpha"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_Widget, w); + } + + void OnView_Name(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Name").Add(sender).Add(args); +#endif + + _Name.SetString(_Widget.GetName()); + } + + void OnModel_Name(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Name").Add(sender).Add(args); +#endif + + _Widget.SetName(_Name.GetString()); + } + + void OnView_Visible(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Visible").Add(sender).Add(args); +#endif + + _Visible.SetBool(_Widget.IsVisible()); + } + + void OnModel_Visible(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Visible").Add(sender).Add(args); +#endif + + _Widget.Show(_Visible.GetBool()); + } + + void OnView_Enabled(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Enabled").Add(sender).Add(args); +#endif + + OnView_Enabled(sender, args); + } + + void OnModel_Enabled(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Enabled").Add(sender).Add(args); +#endif + + _Widget.Enable(_Enabled.GetBool()); + } + + void OnView_Flags(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Flags").Add(sender).Add(args); +#endif + + _Flags.SetInt(_Widget.GetFlags()); + } + + void OnModel_Flags(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Flags").Add(sender).Add(args); +#endif + + _Widget.ClearFlags(_Widget.GetFlags(), false); + _Widget.SetFlags(_Flags.GetInt()); + } + + void OnView_Sort(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Sort").Add(sender).Add(args); +#endif + + _Sort.SetInt(_Widget.GetSort()); + } + + void OnModel_Sort(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Sort").Add(sender).Add(args); +#endif + + _Widget.SetSort(_Sort.GetInt()); + } + + void OnView_Position(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Position").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetPos(_positionX, _positionY); + + _Position.SetVector(Vector(_positionX, _positionY, 0)); + } + + void OnModel_Position(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Position").Add(sender).Add(args); +#endif + + vector position = _Position.GetVector(); + + _Widget.SetPos(position[0], position[1]); + + NotifyPropertyChanged(PositionX, "PositionX"); + NotifyPropertyChanged(PositionY, "PositionY"); + } + + void OnView_PositionX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_PositionX").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetPos(_positionX, _positionY); + + _PositionX.SetFloat(_positionX); + } + + void OnModel_PositionX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_PositionX").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetPos(_positionX, _positionY); + + _Widget.SetPos(_PositionX.GetFloat(), _positionY); + } + + void OnView_PositionY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_PositionY").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetPos(_positionX, _positionY); + + _PositionY.SetFloat(_positionY); + } + + void OnModel_PositionY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_PositionY").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetPos(_positionX, _positionY); + + _Widget.SetPos(_positionX, _PositionY.GetFloat()); + } + + void OnView_Size(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Size").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetSize(_width, _height); + + _Size.SetVector(Vector(_width, _height, 0)); + } + + void OnModel_Size(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Size").Add(sender).Add(args); +#endif + + vector size = _Size.GetVector(); + + _Widget.SetSize(size[0], size[1]); + + NotifyPropertyChanged(Width, "Width"); + NotifyPropertyChanged(Height, "Height"); + } + + void OnView_Width(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Width").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetSize(_width, _height); + + _Width.SetFloat(_width); + } + + void OnModel_Width(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Width").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetSize(_width, _height); + + _Widget.SetSize(_Width.GetFloat(), _height); + } + + void OnView_Height(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Height").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetSize(_width, _height); + + _Height.SetFloat(_height); + } + + void OnModel_Height(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Height").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetSize(_width, _height); + + _Widget.SetSize(_width, _Height.GetFloat()); + } + + void OnView_ScreenPositionX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ScreenPositionX").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetScreenPos(_positionX, _positionY); + + _ScreenPositionX.SetFloat(_positionX); + } + + void OnModel_ScreenPositionX(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ScreenPositionX").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetScreenPos(_positionX, _positionY); + _positionX = _PositionX.GetFloat(); + + if ((_Widget.GetFlags() & WidgetFlags.HEXACTPOS) != 0) + { + float temp; + + float posAdd = 0; + float posMul = 0; + Widget parent = _Widget.GetParent(); + if (parent) + { + _Widget.GetScreenPos(posAdd, temp); + _Widget.GetScreenSize(posMul, temp); + } + _positionX = posAdd + (posMul * _positionX); + } + + _Widget.SetPos(_positionX, _positionY); + } + + void OnView_ScreenPositionY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ScreenPositionY").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetScreenPos(_positionX, _positionY); + + _ScreenPositionY.SetFloat(_positionY); + } + + void OnModel_ScreenPositionY(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ScreenPositionY").Add(sender).Add(args); +#endif + + float _positionX; + float _positionY; + _Widget.GetScreenPos(_positionX, _positionY); + _positionY = _PositionY.GetFloat(); + + if ((_Widget.GetFlags() & WidgetFlags.VEXACTPOS) != 0) + { + float temp; + + float posAdd = 0; + float posMul = 0; + Widget parent = _Widget.GetParent(); + if (parent) + { + _Widget.GetScreenPos(temp, posAdd); + _Widget.GetScreenSize(temp, posMul); + } + _positionY = posAdd + (posMul * _positionY); + } + + _Widget.SetPos(_positionX, _positionY); + } + + void OnView_ScreenWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ScreenWidth").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetScreenSize(_width, _height); + + _ScreenWidth.SetFloat(_width); + } + + void OnModel_ScreenWidth(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ScreenWidth").Add(sender).Add(args); +#endif + + OnView_ScreenWidth(m_Model, args); + } + + void OnView_ScreenHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_ScreenHeight").Add(sender).Add(args); +#endif + + float _width; + float _height; + _Widget.GetScreenSize(_width, _height); + + _ScreenHeight.SetFloat(_height); + } + + void OnModel_ScreenHeight(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_ScreenHeight").Add(sender).Add(args); +#endif + + OnView_ScreenHeight(m_Model, args); + } + + void OnView_Color(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Color").Add(sender).Add(args); +#endif + + _Color.SetInt(_Widget.GetColor()); + } + + void OnModel_Color(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Color").Add(sender).Add(args); +#endif + + _Widget.SetColor(_Color.GetInt()); + } + + void OnView_Roll(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Roll").Add(sender).Add(args); +#endif + + OnModel_Roll(sender, args); + } + + void OnModel_Roll(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Roll").Add(sender).Add(args); +#endif + + _Widget.SetRotation(_Roll.GetFloat(), _Pitch.GetFloat(), _Yaw.GetFloat()); + } + + void OnView_Pitch(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Pitch").Add(sender).Add(args); +#endif + + OnModel_Pitch(sender, args); + } + + void OnModel_Pitch(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Pitch").Add(sender).Add(args); +#endif + + _Widget.SetRotation(_Roll.GetFloat(), _Pitch.GetFloat(), _Yaw.GetFloat()); + } + + void OnView_Yaw(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Yaw").Add(sender).Add(args); +#endif + + OnModel_Yaw(sender, args); + } + + void OnModel_Yaw(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Yaw").Add(sender).Add(args); +#endif + + _Widget.SetRotation(_Roll.GetFloat(), _Pitch.GetFloat(), _Yaw.GetFloat()); + } + + void OnView_Alpha(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Alpha").Add(sender).Add(args); +#endif + + _Alpha.SetInt(_Widget.GetAlpha()); + } + + void OnModel_Alpha(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Alpha").Add(sender).Add(args); +#endif + + _Widget.SetAlpha(_Alpha.GetInt()); + } + + override bool OnResize(CF_ModelBase sender, CF_ResizeEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnResize").Add(sender).Add(args); +#endif + + //NotifyPropertyChanged(Size, "Size"); + + //NotifyPropertyChanged(Width, "Width"); + //NotifyPropertyChanged(Height, "Height"); + + //NotifyPropertyChanged(ScreenWidth, "ScreenWidth"); + //NotifyPropertyChanged(ScreenHeight, "ScreenHeight"); + + return super.OnResize(sender, args); + } + + override bool OnUpdate(CF_ModelBase sender, CF_ViewEventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnUpdate").Add(sender).Add(args); +#endif + + //NotifyPropertyChanged(Position, "Position"); + //NotifyPropertyChanged(PositionX, "PositionX"); + //NotifyPropertyChanged(PositionY, "PositionY"); + + //NotifyPropertyChanged(ScreenPositionX, "ScreenPositionX"); + //NotifyPropertyChanged(ScreenPositionY, "ScreenPositionY"); + + if (_Widget) + { + bool visible = _Widget.IsVisible(); + if (!_Visible.IsDefault() && _Visible.GetBool() != visible) + { + _Visible.SetBool(visible); + + if (visible) + OnShow(m_Widget); + else + OnHide(m_Widget); + } + } + + return super.OnUpdate(sender, args); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_WrapSpacerWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_WrapSpacerWidget.c new file mode 100644 index 00000000..84fb2dd9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_WrapSpacerWidget.c @@ -0,0 +1,23 @@ +class CF_WrapSpacerWidget : CF_SpacerWidget +{ + protected WrapSpacerWidget _WrapSpacerWidget; + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_1(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_WrapSpacerWidget, w); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_XComboBoxWidget.c b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_XComboBoxWidget.c new file mode 100644 index 00000000..a1ea6970 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/MVVM/ViewModels/CF_XComboBoxWidget.c @@ -0,0 +1,77 @@ +class CF_XComboBoxWidget : CF_UIWidget +{ + reference string Selected; + reference string Items; + + protected XComboBoxWidget _XComboBoxWidget; + protected CF_ObservableCollection _Items; + protected CF_MVVM_PropertyBase _Selected = CF_MVVM_GetDefaultProperty(); + + override void GetProperties() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "GetProperties"); +#endif + + super.GetProperties(); + + AddProperty(Selected, "Selected"); + AddProperty(Items, "Items"); + } + + override void OnWidgetScriptInit(Widget w) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnWidgetScriptInit").Add(w); +#endif + + super.OnWidgetScriptInit(w); + Class.CastTo(_XComboBoxWidget, w); + } + + void OnView_Selected(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Selected").Add(sender).Add(args); +#endif + + _Selected.SetFloat(_XComboBoxWidget.GetCurrentItem()); + } + + void OnModel_Selected(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Selected").Add(sender).Add(args); +#endif + + _XComboBoxWidget.SetCurrentItem(_Selected.GetFloat()); + } + + void OnView_Items(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnView_Items").Add(sender).Add(args); +#endif + + OnModel_Items(sender, args); + } + + void OnModel_Items(CF_ModelBase sender, CF_EventArgs args) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "OnModel_Items").Add(sender).Add(args); +#endif + + int selected = _XComboBoxWidget.GetCurrentItem(); + + _XComboBoxWidget.ClearAll(); + for (int i = 0; i < _Items.Count(); i++) + { + _XComboBoxWidget.AddItem(_Items.GetString(i)); + } + + _XComboBoxWidget.SetCurrentItem(selected); + + NotifyPropertyChanged(Selected, "Selected"); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Module/CF_ModuleGame.c b/JM/CF/Scripts/3_Game/CommunityFramework/Module/CF_ModuleGame.c index f5cb1596..7ab0b10e 100644 --- a/JM/CF/Scripts/3_Game/CommunityFramework/Module/CF_ModuleGame.c +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Module/CF_ModuleGame.c @@ -7,7 +7,14 @@ class CF_ModuleGame : CF_ModuleCore int m_CF_RPC_Minimum; int m_CF_RPC_Maximum; - + + void ~CF_ModuleGame() + { +#ifndef SERVER + CF_MVVM.Destroy(this); +#endif + } + /** * @brief Binds a module function to an input * @@ -165,6 +172,42 @@ class CF_ModuleGame : CF_ModuleCore void OnRPC(Class sender, CF_EventArgs args); void OnVariablesSynchronized(Class sender, CF_EventArgs args); + + void Open(Widget parent = null) + { + string layout = GetLayoutFile(); + if (layout == string.Empty) return; + + CF_MVVM.Create(this, layout, parent); + } + + void Close() + { + CF_MVVM.Destroy(this); + } + + void NotifyPropertyChanged(string property, CF_EventArgs args = null) + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_2(this, "NotifyPropertyChanged").Add(property).Add(args); +#endif + + CF_MVVM.NotifyPropertyChanged(this, property, args); + } + + void NotifyPropertyChanged() + { +#ifdef CF_MVVM_TRACE + auto trace = CF_Trace_0(this, "NotifyPropertyChanged"); +#endif + + CF_MVVM.NotifyPropertyChanged(this); + } + + string GetLayoutFile() + { + return string.Empty; + } }; typedef CF_ModuleGame CF_Module; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Dropdown.c b/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Dropdown.c new file mode 100644 index 00000000..b4e68af3 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Dropdown.c @@ -0,0 +1,180 @@ +class CF_DropdownBase : CF_Model +{ + override string GetLayoutFile() + { + return ""; + } + + string GetPopupLayoutFile() + { + return ""; + } + + string GetElementLayoutFile() + { + return ""; + } +}; + +class CF_Dropdown : CF_DropdownBase +{ + ref CF_ObservableArray m_Elements; + + ref CF_DropdownElement m_Selected; + + autoptr CF_DropdownPopup m_Popup; + + void CF_Dropdown(CF_ObservableArray elements = null) + { + m_Elements = elements; + if (!m_Elements) + { + m_Elements = new CF_ObservableArray(); + } + + m_Selected = new CF_DropdownElement(); + m_Selected.Init(null, this, GetElementLayoutFile()); + } + + void Insert(T item) + { + m_Elements.Insert(item); + } + + void SetSelected(T selected) + { + m_Selected.m_Data = selected; + + if (m_Popup) m_Popup.SetSelected(m_Selected); + } + + T GetSelected() + { + return m_Selected.m_Data; + } + + void OnToggle(CF_ModelBase sender, CF_EventArgs args) + { + if (m_Popup) Close(); + else Open(); + } + + void Open() + { + if (m_Popup) return; + + m_Popup = new CF_DropdownPopup(); + m_Popup.Init(this, GetPopupLayoutFile(), GetElementLayoutFile()); + m_Popup.OnDestroy.AddSubscriber(OnClose); + NotifyPropertyChanged("m_Popup"); + } + + void Close() + { + if (!m_Popup) return; + + delete m_Popup; + } + + void OnClose(Class sender, CF_EventArgs args) + { + m_Popup = null; + NotifyPropertyChanged("m_Popup"); + } +}; + +class CF_DropdownElementBase : CF_Model +{ + void Init(Class data, CF_DropdownBase dropdown, string layoutFile); + + void SetSelected(bool selected); +}; + +class CF_DropdownElement : CF_DropdownElementBase +{ + T m_Data; + bool m_Selected; + + CF_Dropdown m_Dropdown; + + string m_LayoutFile; + + override void Init(Class data, CF_DropdownBase dropdown, string layoutFile) + { + Class.CastTo(m_Dropdown, dropdown); + Class.CastTo(m_Data, data); + + m_LayoutFile = layoutFile; + } + + override string GetLayoutFile() + { + return m_LayoutFile; + } + + void OnClick(CF_ModelBase sender, CF_EventArgs args) + { + m_Dropdown.SetSelected(m_Data); + } + + override void SetSelected(bool selected) + { + m_Selected = selected; + NotifyPropertyChanged("m_Selected"); + } +}; + +class CF_DropdownPopupBase : CF_Popup +{ + void Init(CF_DropdownBase dropdown, string popupLayoutFile, string elementLayoutFile); + + void SetSelected(Class selected); +}; + +class CF_DropdownPopup : CF_DropdownPopupBase +{ + ref CF_ObservableMap m_Elements; + + CF_Dropdown m_Dropdown; + + string m_LayoutFile; + + override void Init(CF_DropdownBase dropdown, string popupLayoutFile, string elementLayoutFile) + { + Class.CastTo(m_Dropdown, dropdown); + + m_LayoutFile = popupLayoutFile; + + m_Elements = new CF_ObservableMap(); + + int count = m_Dropdown.m_Elements.Count(); + for (int i = 0; i < count; i++) + { + T item = m_Dropdown.m_Elements[i]; + auto element = new CF_DropdownElement(); + element.Init(item, m_Dropdown, elementLayoutFile); + m_Elements.Insert(item, element); + } + } + + override string GetLayoutFile() + { + return m_LayoutFile; + } + + override void SetSelected(Class selected) + { + for (int i = 0; i < m_Elements.Count(); i++) + { + auto element = CF_DropdownElement.Cast(m_Elements.GetElement(i)); + + if (element.m_Data == selected) + { + element.SetSelected(true); + continue; + } + + element.SetSelected(false); + } + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Popup.c b/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Popup.c new file mode 100644 index 00000000..c154c3f4 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Popup/CF_Popup.c @@ -0,0 +1,61 @@ +class CF_Popup : CF_Model +{ + // Ensures that only 1 root popup exists at a time + private static autoptr CF_Popup s_Instance; + + ref CF_EventHandler OnDestroy = new CF_EventHandler(); + + private bool m_WasMouseDown; + + private Widget popup_root; + private float m_PositionX; + private float m_PositionY; + + void CF_Popup() + { + s_Instance = this; + + CF_Timer.Create(this, "OnUpdate"); + CF_MVVM.Create(this, GetLayoutFile()); + } + + void ~CF_Popup() + { + OnDestroy.Invoke(this); + } + + static bool IsOpen() + { + return s_Instance != null; + } + + void OnUpdate(Class sender, CF_EventArgs args) + { + bool isMouseDown = (GetMouseState(MouseState.LEFT) & MB_PRESSED_MASK) != 0; + + if (isMouseDown && m_WasMouseDown != isMouseDown) + { + bool closePopup = true; + + Widget widget = GetWidgetUnderCursor(); + while (widget != null) + { + if (widget == popup_root) + { + closePopup = false; + break; + } + + widget = widget.GetParent(); + } + + if (closePopup) + { + s_Instance = null; + return; + } + } + + m_WasMouseDown = isMouseDown; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_Timer.c b/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_Timer.c new file mode 100644 index 00000000..754b5e6e --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_Timer.c @@ -0,0 +1,30 @@ +class CF_Timer : CF_TimerBase +{ + protected Managed m_Owner; + protected string m_Function; + + static CF_Timer Create(Managed instance, string function, float interval = 0.0) + { + if (instance == null) return null; + + CF_Timer timer = new CF_Timer(); + timer.m_Owner = instance; + timer.m_Function = function; + timer.m_duration = interval; + + return timer; + } + + protected override void OnTick(float dt) + { + if (m_Owner == null) + { + Destroy(); + return; + } + + Param params = new Param2(this, new CF_EventUpdateArgs(dt)); + + GetGame().GameScript.CallFunctionParams(m_Owner, m_Function, NULL, params); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_TimerBase.c b/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_TimerBase.c new file mode 100644 index 00000000..ed83c654 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Timer/CF_TimerBase.c @@ -0,0 +1,83 @@ +class CF_TimerBase : TimerBase +{ + static ref array s_GlobalTimers = new array(); + + protected bool m_IsDestroyed; + + void CF_TimerBase() + { + m_duration = 0; + m_loop = true; + m_time = 0; + m_running = false; + m_timerQueue = g_Game.GetTimerQueue(CALL_CATEGORY_SYSTEM); + + s_GlobalTimers.Insert(this); + + Start(); + } + + void ~CF_TimerBase() + { + Destroy(); + } + + protected override void SetRunning(bool running) + { + if (m_running == running) + { + return; + } + + super.SetRunning(running); + + if (m_running) + { + OnStart(); + } + else + { + OnStop(); + } + } + + protected override void Tick(float timeslice) + { + m_time += timeslice; + + if (m_time >= m_duration) + { + OnTick(m_time); + + m_time = 0; + } + } + + void Start() + { + SetRunning(true); + } + + void Destroy() + { + if (m_IsDestroyed) return; + + m_IsDestroyed = true; + + Stop(); + + s_GlobalTimers.RemoveItem(this); + } + + protected void OnTick(float dt) + { + } + + protected void OnStart() + { + } + + protected void OnStop() + { + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Window.c b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Window.c new file mode 100644 index 00000000..87fbe304 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Window.c @@ -0,0 +1,977 @@ +class CF_Window : CF_Model +{ + autoptr CF_EventHandler OnClose = new CF_EventHandler(); + + autoptr CF_EventHandler OnFocus = new CF_EventHandler(); + autoptr CF_EventHandler OnUnfocus = new CF_EventHandler(); + + static const int STATE_NONE = 0; + static const int STATE_FULLSCREEN = 1; + static const int STATE_MINIMIZED = 2; + + // Attached + private CF_ModelBase m_Model; + + // Sorting + private CF_Window m_Prev; + private CF_Window m_Next; + private int m_Sort; + + // Widgets + Widget cf_window; + Widget cf_window_client; + + // Title Bar + private ref CF_ObservableSortedArray m_TitleBarButtons = new CF_ObservableSortedArray(); + private float m_TitleBarHeight = 25; + private float m_BorderWidth = 2; + + private CF_WindowButton m_CloseButton; + private CF_WindowButton m_MinimizeButton; + private CF_WindowButton m_MinimizeRestoreButton; + private CF_WindowButton m_MaximizeButton; + private CF_WindowButton m_MaximizeRestoreButton; + + // Properties + private bool m_Visible; + private bool m_Destroy; + + private float m_PositionX; + private float m_PositionY; + + private float m_Width; + private float m_Height; + private float m_MinimumWidth; + private float m_MinimumHeight; + private float m_MaximumWidth; + private float m_MaximumHeight; + + private int m_BorderColor; + private int m_BorderHoverColor; + private int m_BorderDragColor; + + private string m_Title; + + private bool m_TakesGameFocus; + + // State + private int m_State; + + private bool m_IsFocused; + private bool m_WasFocused; + + private float m_ContentWidth; + private float m_ContentHeight; + + private float m_PreviousPositionX; + private float m_PreviousPositionY; + private float m_PreviousWidth; + private float m_PreviousHeight; + + // Dragging/Resizing + private float m_DragOffsetX; + private float m_DragOffsetY; + private float m_ResizeStartX; + private float m_ResizeStartY; + + private int m_BorderUColor; + private int m_BorderDColor; + private int m_BorderLColor; + private int m_BorderRColor; + private int m_BorderULColor; + private int m_BorderURColor; + private int m_BorderDLColor; + private int m_BorderDRColor; + + void CF_Window(string title = "Window", int width = 400, int height = 400) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_3(this, "CF_Window").Add(title).Add(width).Add(height); +#endif + + m_Visible = true; + + m_CloseButton = CreateButton("set:cf_imageset image:close_white", 10000); + m_CloseButton.OnClick.AddSubscriber(this.OnCloseButtonClicked); + m_CloseButton.SetVisible(true); + + m_MaximizeButton = CreateButton("set:cf_imageset image:fullscreen_white", 9000); + m_MaximizeButton.OnClick.AddSubscriber(this.OnMaximizeButtonClicked); + m_MaximizeButton.SetVisible(true); + + m_MaximizeRestoreButton = CreateButton("set:cf_imageset image:window_white", 9000); + m_MaximizeRestoreButton.OnClick.AddSubscriber(this.OnMaximizeRestoreButtonClicked); + m_MaximizeRestoreButton.SetVisible(false); + + m_MinimizeButton = CreateButton("set:cf_imageset image:minimize_white", 8000); + m_MinimizeButton.OnClick.AddSubscriber(this.OnMinimizeButtonClicked); + m_MinimizeButton.SetVisible(true); + + m_MinimizeRestoreButton = CreateButton("set:cf_imageset image:maximize_white", 8000); + m_MinimizeRestoreButton.OnClick.AddSubscriber(this.OnMinimizeRestoreButtonClicked); + m_MinimizeRestoreButton.SetVisible(false); + + m_MinimumWidth = m_BorderWidth + m_BorderWidth + 100; + m_MinimumHeight = m_BorderWidth + m_BorderWidth + m_TitleBarHeight; + + m_MaximumWidth = 10000; + m_MaximumHeight = 10000; + + m_BorderColor = ARGB(0, 0, 0, 0); + m_BorderHoverColor = ARGB(150, 255, 0, 255); + m_BorderDragColor = ARGB(255, 255, 0, 255); + + m_TakesGameFocus = true; + + Add(); + + CF_MVVM.Create(this, GetLayoutFile(), CF_Windows._GetContainer()); + + SetTitle(title); + SetState(STATE_NONE); + SetPosition(0, 0); + SetSize(width, height); + } + + void ~CF_Window() + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_0(this, "~CF_Window"); +#endif + + OnClose.Invoke(this); + + Remove(); + + if (m_Model) + { + CF_MVVM.Destroy(m_Model); + } + } + + Widget GetWidgetRoot() + { + // compat with old COT + return null; + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/windows/window.layout"; + } + + CF_Window GetNext() + { + return m_Next; + } + + CF_Window GetPrev() + { + return m_Prev; + } + + Widget CreateWidgets(string layoutFile) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "CreateWidgets").Add(layoutFile); +#endif + + Widget child = cf_window_client.GetChildren(); + while (child != null) + { + Widget temp = child; + child = child.GetSibling(); + temp.Unlink(); + } + + WorkspaceWidget wSpace = GetGame().GetWorkspace(); + // A mess to fix an issue in Workbench, can also substitute for loading screen support + if (wSpace == null) + { + wSpace = GetGame().GetLoadingWorkspace(); + if (!wSpace) + wSpace = CF.Game().GetWorkspace(); + if (!wSpace) + wSpace = CF.Game().GetLoadingWorkspace(); + + if (!wSpace) + return null; + } + + Widget newContent = wSpace.CreateWidgets(layoutFile, cf_window_client); + if (!newContent) + return null; + + newContent.ClearFlags(WidgetFlags.HEXACTSIZE | WidgetFlags.VEXACTSIZE); + newContent.SetPos(0, 0); + newContent.SetSize(1, 1); + return newContent; + } + + Widget CreateWidgets(CF_ModelBase model, string layoutFile) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "CreateWidgets").Add(model).Add(layoutFile); +#endif + + Widget child = cf_window_client.GetChildren(); + while (child != null) + { + Widget temp = child; + child = child.GetSibling(); + temp.Unlink(); + } + + m_Model = model; + + Widget newContent = CF_MVVM.Create(m_Model, layoutFile, cf_window_client).GetWidget(); + if (!newContent) + return null; + + newContent.ClearFlags(WidgetFlags.HEXACTSIZE | WidgetFlags.VEXACTSIZE); + newContent.SetPos(0, 0); + newContent.SetSize(1, 1); + return newContent; + } + + Widget CreateWidgets(CF_ModelBase model) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "CreateWidgets").Add(model); +#endif + + if (!model) + return null; + + string layout; + g_Script.CallFunction(model, "GetLayoutFile", layout, null); + return CreateWidgets(model, layout); + } + + void SetTitle(string title) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetTitle").Add(title); +#endif + + m_Title = title; + + NotifyPropertyChanged("m_Title"); + } + + string GetTitle() + { + return m_Title; + } + + void SetVisible(bool visible) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetVisible").Add(visible); +#endif + + m_Visible = visible; + + NotifyPropertyChanged("m_Visible"); + } + + bool IsVisible() + { + return m_Visible; + } + + void SetTakesGameFocus(bool takes) + { + m_TakesGameFocus = takes; + } + + bool DoesTakeGameFocus() + { + return m_TakesGameFocus; + } + + void SetModel(CF_ModelBase model) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetModel").Add(model); +#endif + + if (model != m_Model) + { + m_Model = model; + + CreateWidgets(m_Model); + + //NotifyPropertyChanged("m_Model"); + } + } + + CF_ModelBase GetModel() + { + return m_Model; + } + + void SetState(int state) + { + switch (state) + { + case STATE_NONE: + m_MinimizeButton.SetVisible(true); + m_MinimizeRestoreButton.SetVisible(false); + + m_MaximizeButton.SetVisible(true); + m_MaximizeRestoreButton.SetVisible(false); + + RemoveState(m_State); + + break; + case STATE_FULLSCREEN: + m_MaximizeButton.SetVisible(false); + m_MaximizeRestoreButton.SetVisible(true); + + m_MinimizeButton.SetVisible(true); + m_MinimizeRestoreButton.SetVisible(false); + + if (state == m_State) + break; + + m_PreviousWidth = m_Width; + m_PreviousHeight = m_Height; + + m_PreviousPositionX = m_PositionX; + m_PreviousPositionY = m_PositionY; + + int w, h; + GetScreenSize(w, h); + + SetSize(w, h); + SetPosition(0, 0); + + break; + case STATE_MINIMIZED: + m_MinimizeButton.SetVisible(false); + m_MinimizeRestoreButton.SetVisible(true); + + m_MaximizeButton.SetVisible(true); + m_MaximizeRestoreButton.SetVisible(false); + + if (state == m_State) + break; + + m_PreviousWidth = m_Width; + m_PreviousHeight = m_Height; + + SetSize(m_PreviousWidth, 0); + + break; + } + + m_State = state; + NotifyPropertyChanged("m_State"); + } + + void RemoveState(int state) + { + switch (state) + { + case STATE_NONE: + break; + case STATE_FULLSCREEN: + SetSize(m_PreviousWidth, m_PreviousHeight); + SetPosition(m_PreviousPositionX, m_PreviousPositionY); + + break; + case STATE_MINIMIZED: + SetSize(m_PreviousWidth, m_PreviousHeight); + + break; + } + } + + void UpdateFocus(bool focused) + { + m_IsFocused = focused; + if (m_IsFocused == m_WasFocused) + { + return; + } + + m_WasFocused = m_IsFocused; + + if (m_IsFocused) + { + OnFocus.Invoke(this, null); + } + else + { + SetFocus(null); + + OnUnfocus.Invoke(this, null); + } + } + + void SetPosition(float x, float y) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetPosition").Add(x).Add(y); +#endif + + m_PositionX = x; + m_PositionY = y; + + NotifyPropertyChanged("m_PositionX"); + NotifyPropertyChanged("m_PositionY"); + } + + void SetContentSize(float x, float y) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetContentSize").Add(x).Add(y); +#endif + + SetSize(x + (m_BorderWidth + m_BorderWidth), y + (m_BorderWidth + m_BorderWidth + m_TitleBarHeight)); + } + + void SetSize(float x, float y) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_1(this, "SetSize").Add(x).Add(y); +#endif + + m_Width = x; + m_Height = y; + + if (m_Width < m_MinimumWidth) + m_Width = m_MinimumWidth; + else if (m_Width > m_MaximumWidth) + m_Width = m_MaximumWidth; + + if (m_Height < m_MinimumHeight) + m_Height = m_MinimumHeight; + else if (m_Height > m_MaximumHeight) + m_Height = m_MaximumHeight; + + m_ContentWidth = m_Width - (m_BorderWidth + m_BorderWidth); + m_ContentHeight = m_Height - (m_BorderWidth + m_BorderWidth + m_TitleBarHeight); + + NotifyPropertyChanged("m_Width"); + NotifyPropertyChanged("m_Height"); + NotifyPropertyChanged("m_ContentWidth"); + NotifyPropertyChanged("m_ContentHeight"); + } + + CF_WindowButton CreateButton(string image, int priority) + { + CF_WindowButton button = new CF_WindowButton(image); + m_TitleBarButtons.Insert(button, priority); + return button; + } + + void Destroy() + { + m_Destroy = true; + } + + bool IsDestroying() + { + return m_Destroy; + } + + void OnMinimizeRestoreButtonClicked(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnMinimizeRestoreButtonClicked").Add(sender).Add(args); +#endif + + SetState(STATE_NONE); + } + + void OnMinimizeButtonClicked(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnMinimizeButtonClicked").Add(sender).Add(args); +#endif + + SetState(STATE_MINIMIZED); + } + + void OnMaximizeRestoreButtonClicked(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnMaximizeRestoreButtonClicked").Add(sender).Add(args); +#endif + + SetState(STATE_NONE); + } + + void OnMaximizeButtonClicked(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnMaximizeButtonClicked").Add(sender).Add(args); +#endif + + SetState(STATE_FULLSCREEN); + } + + void OnCloseButtonClicked(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnCloseButtonClicked").Add(sender).Add(args); +#endif + + Destroy(); + } + + void OnMouseButtonDown(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnMouseButtonDown").Add(sender).Add(args); +#endif + + BringTop(); + } + + void OnDrag(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnDrag").Add(sender).Add(args); +#endif + + if (m_State == STATE_FULLSCREEN) + { + float newX = args.X - (m_PreviousWidth * 0.5); + if (newX < 0) + newX = 0; + else if (newX > m_Width) + newX = m_Width - m_PreviousWidth; + + SetSize(m_PreviousWidth, m_PreviousHeight); + SetPosition(newX, 0); + + m_State = STATE_NONE; + SetState(STATE_NONE); + } + + m_DragOffsetX = args.X - m_PositionX; + m_DragOffsetY = args.Y - m_PositionY; + } + + void OnDragging(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnDragging").Add(sender).Add(args); +#endif + + SetPosition(args.X - m_DragOffsetX, args.Y - m_DragOffsetY); + } + + void OnStartResizing(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnStartResizing").Add(sender).Add(args); +#endif + + m_ResizeStartX = args.X; + m_ResizeStartY = args.Y; + + m_PreviousWidth = m_Width; + m_PreviousHeight = m_Height; + + m_PreviousPositionX = m_PositionX; + m_PreviousPositionY = m_PositionY; + } + + void OnStopResizing(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnStartResizing").Add(sender).Add(args); +#endif + + SetFocus(null); + } + + void OnResizingUp(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeY = m_PreviousHeight - (args.Y - m_ResizeStartY); + float newPosY = m_PreviousPositionY + (args.Y - m_ResizeStartY); + if (newPosY + m_MinimumHeight > m_PreviousPositionY + m_PreviousHeight) + { + newPosY = m_PreviousPositionY + m_PreviousHeight; + } + + SetSize(m_PreviousWidth, newSizeY); + SetPosition(m_PreviousPositionX, newPosY); + + ResetBorder(); + m_BorderUColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderUColor"); + } + + void OnResizingDown(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeY = m_PreviousHeight + (args.Y - m_ResizeStartY); + SetSize(m_PreviousWidth, newSizeY); + + ResetBorder(); + m_BorderDColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderDColor"); + } + + void OnResizingLeft(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth - (args.X - m_ResizeStartX); + float newPosX = m_PreviousPositionX + (args.X - m_ResizeStartX); + SetSize(newSizeX, m_PreviousHeight); + SetPosition(newPosX, m_PreviousPositionY); + + ResetBorder(); + m_BorderLColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderLColor"); + } + + void OnResizingRight(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth + (args.X - m_ResizeStartX); + SetSize(newSizeX, m_PreviousHeight); + + ResetBorder(); + m_BorderRColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderRColor"); + } + + void OnResizingUpLeft(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth - (args.X - m_ResizeStartX); + float newPosX = m_PreviousPositionX + (args.X - m_ResizeStartX); + float newSizeY = m_PreviousHeight - (args.Y - m_ResizeStartY); + float newPosY = m_PreviousPositionY + (args.Y - m_ResizeStartY); + + SetSize(newSizeX, newSizeY); + SetPosition(newPosX, newPosY); + + ResetBorder(); + m_BorderULColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderULColor"); + } + + void OnResizingUpRight(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth + (args.X - m_ResizeStartX); + float newSizeY = m_PreviousHeight - (args.Y - m_ResizeStartY); + float newPosY = m_PreviousPositionY + (args.Y - m_ResizeStartY); + + SetSize(newSizeX, newSizeY); + SetPosition(m_PreviousPositionX, newPosY); + + ResetBorder(); + m_BorderURColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderURColor"); + } + + void OnResizingDownLeft(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth - (args.X - m_ResizeStartX); + float newPosX = m_PreviousPositionX + (args.X - m_ResizeStartX); + float newSizeY = m_PreviousHeight + (args.Y - m_ResizeStartY); + + SetSize(newSizeX, newSizeY); + SetPosition(newPosX, m_PreviousPositionY); + + ResetBorder(); + m_BorderDLColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderDLColor"); + } + + void OnResizingDownRight(CF_ModelBase sender, CF_DragEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "OnResizingUp").Add(sender).Add(args); +#endif + + float newSizeX = m_PreviousWidth + (args.X - m_ResizeStartX); + float newSizeY = m_PreviousHeight + (args.Y - m_ResizeStartY); + + SetSize(newSizeX, newSizeY); + + ResetBorder(); + m_BorderDRColor = m_BorderDragColor; + NotifyPropertyChanged("m_BorderDRColor"); + } + + void OnMouseBorderUp(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderUColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderUColor"); + } + } + + void OnMouseBorderDown(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderDColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderDColor"); + } + } + + void OnMouseBorderLeft(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderLColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderLColor"); + } + } + + void OnMouseBorderRight(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderRColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderRColor"); + } + } + + void OnMouseBorderUpLeft(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderULColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderULColor"); + } + } + + void OnMouseBorderUpRight(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderURColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderURColor"); + } + } + + void OnMouseBorderDownLeft(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderDLColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderDLColor"); + } + } + + void OnMouseBorderDownRight(CF_ModelBase sender, CF_MouseEventArgs args) + { + ResetBorder(); + + if (args.Type == 1) + { + m_BorderDRColor = m_BorderHoverColor; + NotifyPropertyChanged("m_BorderDRColor"); + } + } + + void ResetBorder() + { + m_BorderUColor = m_BorderColor; + m_BorderDColor = m_BorderColor; + m_BorderLColor = m_BorderColor; + m_BorderRColor = m_BorderColor; + m_BorderULColor = m_BorderColor; + m_BorderURColor = m_BorderColor; + m_BorderDLColor = m_BorderColor; + m_BorderDRColor = m_BorderColor; + + NotifyPropertyChanged("m_BorderUColor"); + NotifyPropertyChanged("m_BorderDColor"); + NotifyPropertyChanged("m_BorderLColor"); + NotifyPropertyChanged("m_BorderRColor"); + NotifyPropertyChanged("m_BorderULColor"); + NotifyPropertyChanged("m_BorderURColor"); + NotifyPropertyChanged("m_BorderDLColor"); + NotifyPropertyChanged("m_BorderDRColor"); + } + + /*private*/ void _SetSort(int sort) + { + m_Sort = sort; + NotifyPropertyChanged("m_Sort"); + } + + private CF_Window Add() + { + CF_Window _this = this; + + if (!CF_Windows.s_Head) + { + CF_Windows.s_Head = _this; + CF_Windows.s_Tail = _this; + } + else + { + m_Next = CF_Windows.s_Head; + CF_Windows.s_Head.m_Prev = _this; + CF_Windows.s_Head = _this; + } + + return _this; + } + + private CF_Window Insert(CF_Window previous) + { + CF_Window _this = this; + + if (!previous) + { + m_Prev = null; + m_Next = CF_Windows.s_Head; + CF_Windows.s_Head.m_Prev = _this; + CF_Windows.s_Head = _this; + } + else if (!previous.m_Next) + { + m_Next = null; + m_Prev = CF_Windows.s_Tail; + CF_Windows.s_Tail.m_Next = _this; + CF_Windows.s_Tail = _this; + } + else + { + m_Prev = previous; + m_Next = m_Prev.m_Next; + m_Next.m_Prev = this; + m_Prev.m_Next = this; + } + + return _this; + } + + private CF_Window Remove() + { + CF_Window _this = this; + + if (m_Next) + { + m_Next.m_Prev = m_Prev; + } + else + { + CF_Windows.s_Tail = m_Prev; + } + + if (m_Prev) + { + m_Prev.m_Next = m_Next; + } + else + { + CF_Windows.s_Head = m_Next; + } + + m_Prev = null; + m_Next = null; + + return _this; + } + + void BringUp() + { + CF_Window _this = this; + + CF_Window prev = null; + if (m_Prev) + prev = m_Prev.m_Prev; + + if (m_Prev || m_Next) + { + // Incrementing the reference count, so this window doesn't get destroyed. + _this = Remove(); + } + else + return; + + Insert(prev); + + return; + } + + void BringDown() + { + CF_Window _this = this; + + CF_Window prev = m_Next; + + if (m_Prev || m_Next) + { + // Incrementing the reference count, so this window doesn't get destroyed. + _this = Remove(); + } + else + return; + + Insert(prev); + + return; + } + + void BringTop() + { + CF_Window _this = this; + + if (CF_Windows.s_Head == _this) + return; + + if (m_Prev || m_Next) + { + // Incrementing the reference count, so this window doesn't get destroyed. + _this = Remove(); + } + else + return; + + Add(); + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_WindowButton.c b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_WindowButton.c new file mode 100644 index 00000000..85770af9 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_WindowButton.c @@ -0,0 +1,39 @@ +class CF_WindowButton : CF_Model +{ + autoptr CF_EventHandler OnClick = new CF_EventHandler(); + + private string m_Image; + private bool m_IsVisible; + + void CF_WindowButton(string image) + { + m_Image = image; + m_IsVisible = true; + } + + bool IsVisible() + { + return m_IsVisible; + } + + void SetVisible(bool visible) + { + m_IsVisible = visible; + + NotifyPropertyChanged("m_IsVisible"); + } + + void OnClickButton(CF_ModelBase sender, CF_MouseEventArgs args) + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_2(this, "Toggle").Add(sender).Add(args); +#endif + + OnClick.Invoke(this, args); + } + + override string GetLayoutFile() + { + return "JM/CF/GUI/layouts/windows/button.layout"; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Windows.c b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Windows.c new file mode 100644 index 00000000..b0ad4211 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/Window/CF_Windows.c @@ -0,0 +1,302 @@ +static autoptr CF_Windows g_CF_Windows; + +enum CF_WindowsFocusState +{ + WORLD = 0, + WINDOW +}; + +enum CF_WindowsInputState +{ + RELEASE = 0, + PRESS +}; + +class CF_Windows : Managed +{ + static CF_Window s_Head; + static CF_Window s_Tail; + + static int s_Count; + + private static Widget s_Container; + + private static UAInput s_ToggleInput; + private static CF_WindowsFocusState s_PreservedState; + + private static CF_WindowsFocusState s_State; + private static CF_WindowsFocusState s_PreviousState; + + private static bool s_Override; + private static CF_WindowsFocusState s_OverrideState; + + private static CF_WindowsInputState s_InputState; + private static CF_WindowsInputState s_PreviousInputState; + private static bool s_InputForcingLossOfFocus; + + private void CF_Windows() + { +#ifndef NO_GUI + CF_Timer.Create(this, "Update"); +#endif + } + + static void _Init() + { + if (g_CF_Windows) + return; + + g_CF_Windows = new CF_Windows(); + } + + static void _Cleanup() + { +#ifdef CF_WINDOWS_TRACE + auto trace = CF_Trace_0(g_CF_Windows, "_Cleanup"); +#endif + + g_CF_Windows = null; + } + + static void _MissionInit() + { + Print("_MissionInit"); + +#ifdef SERVER + return; +#endif + + s_ToggleInput = GetUApi().GetInputByName("UACFToggleWindowMode"); + + if (s_Container) + return; + + s_Container = GetGame().GetWorkspace().CreateWidgets("JM/CF/GUI/layouts/windows/container.layout", null); + } + + static void _MissionCleanup() + { + s_Container.Unlink(); + } + + static Widget _GetContainer() + { + return s_Container; + } + + static bool IsWidgetWindowRoot(Widget widget) + { + CF_Window window = s_Tail; + while (window != null) + { + if (widget == window.cf_window) + { + return true; + } + + window = window.GetPrev(); + } + + return false; + } + + static UAInput GetInput() + { + return s_ToggleInput; + } + + static void SetState(CF_WindowsFocusState state) + { + s_PreservedState = state; + } + + static CF_WindowsFocusState GetState() + { + return s_PreservedState; + } + + static void FlipState() + { + if (s_PreservedState == CF_WindowsFocusState.WORLD) + { + s_PreservedState = CF_WindowsFocusState.WINDOW; + return; + } + + s_PreservedState = CF_WindowsFocusState.WORLD; + } + + static void OverrideInputState(bool pOverride, CF_WindowsFocusState pState = CF_WindowsFocusState.WORLD) + { + s_Override = pOverride; + s_OverrideState = pState; + } + + void Update(Class sender, CF_EventArgs args) + { +#ifdef SERVER + return; +#endif + + if (!s_Container) + { + if (GetDayZGame() && !GetDayZGame().IsLoading()) + { + _MissionInit(); + } + + return; + } + + s_Count = 0; + + CF_Window window = s_Tail; + while (window != null) + { + if (window.GetPrev()) + { + window.UpdateFocus(false); + } + + auto prev = window.GetPrev(); + if (window.IsDestroying()) + { + delete window; + } + else + { + window._SetSort(s_Count++); + } + + window = prev; + } + + if (s_ToggleInput && s_ToggleInput.LocalPress()) // Flip the state when the key is pressed + { + FlipState(); + } + + if (s_InputForcingLossOfFocus) // Left mouse button pressed in the world + { + s_State = CF_WindowsFocusState.WORLD; + } + else if (s_Override) // Some mod overriding the input + { + s_State = s_OverrideState; + } + else if (s_Count <= 0 || CheckForFocus()) // No windows avaliable + { + s_State = CF_WindowsFocusState.WORLD; + s_PreservedState = s_State; + } + else // Default behaviour + { + s_State = s_PreservedState; + } + + // Update the state change + if (s_State != s_PreviousState) + { + s_PreviousState = s_State; + + OnStateChanged(); + } + + if (window) + { + window.UpdateFocus(s_State == CF_WindowsFocusState.WORLD); + } + + // Delay input state change by 1 frame + if (s_PreviousInputState != s_InputState) + { + s_PreviousInputState = s_InputState; + + OnInputStateChanged(); + } + + bool isMouseDown = (GetMouseState(MouseState.LEFT) & MB_PRESSED_MASK) != 0; + switch (s_InputState) + { + case CF_WindowsInputState.PRESS: + if (!isMouseDown) + s_InputState = CF_WindowsInputState.RELEASE; + break; + case CF_WindowsInputState.RELEASE: + if (isMouseDown) + s_InputState = CF_WindowsInputState.PRESS; + break; + } + + s_Container.SetFlags(WidgetFlags.VEXACTSIZE | WidgetFlags.HEXACTSIZE); + int w, h; + GetScreenSize(w, h); + s_Container.SetSize(w, h); + } + + void OnInputStateChanged() + { + s_InputForcingLossOfFocus = false; + + if (s_InputState == CF_WindowsInputState.PRESS) + { + if (!KeepMouseFocused()) + { + s_InputForcingLossOfFocus = true; + } + } + } + + void OnStateChanged() + { + if (s_State == CF_WindowsFocusState.WINDOW) + { + GetGame().GetInput().ChangeGameFocus(1); + } + else + { + GetGame().GetInput().ChangeGameFocus(-1); + } + + GetGame().GetUIManager().ShowUICursor(!GetGame().GetInput().HasGameFocus()); + } + + bool KeepMouseFocused() + { + if (CheckForFocus()) + return true; + + Widget widget = GetWidgetUnderCursor(); + while (widget != null) + { + if (CheckWidgetForFocus(widget)) + return true; + + widget = widget.GetParent(); + } + + return false; + } + + bool CheckForFocus() + { + if (GetGame().GetUIManager().GetMenu()) + return true; + + if (CF_Popup.IsOpen()) + return true; + + return false; + } + + /* + * @note Function for modders to override + */ + bool CheckWidgetForFocus(Widget widget) + { + if (IsWidgetWindowRoot(widget)) + return true; + + return false; + } +}; diff --git a/JM/CF/Scripts/3_Game/CommunityFramework/WorldData.c b/JM/CF/Scripts/3_Game/CommunityFramework/WorldData.c new file mode 100644 index 00000000..006d20c8 --- /dev/null +++ b/JM/CF/Scripts/3_Game/CommunityFramework/WorldData.c @@ -0,0 +1,10 @@ +modded class WorldData +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/AdvancedCommunication.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/AdvancedCommunication.c index e86ceeef..d3e79d88 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/AdvancedCommunication.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/AdvancedCommunication.c @@ -33,4 +33,12 @@ modded class AdvancedCommunication { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/AnimalBase.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/AnimalBase.c index f8e33cc7..648749f6 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/AnimalBase.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/AnimalBase.c @@ -33,4 +33,12 @@ modded class AnimalBase { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/BuildingBase.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/BuildingBase.c index b71375e5..6f685947 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/BuildingBase.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/BuildingBase.c @@ -33,4 +33,12 @@ modded class BuildingBase { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/CarScript.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/CarScript.c index 22582dbb..f51cd2a9 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/CarScript.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/CarScript.c @@ -33,4 +33,12 @@ modded class CarScript { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/DayZPlayerImplement.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/DayZPlayerImplement.c index 61f86c66..5055ef53 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/DayZPlayerImplement.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/DayZPlayerImplement.c @@ -33,4 +33,12 @@ modded class DayZPlayerImplement { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/HelicopterScript.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/HelicopterScript.c index bc6819f8..d9e1ac45 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/HelicopterScript.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/HelicopterScript.c @@ -33,4 +33,12 @@ modded class HelicopterScript { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/ItemBase.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ItemBase.c index ff3de84d..86a34e12 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/ItemBase.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ItemBase.c @@ -85,4 +85,12 @@ modded class ItemBase { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; \ No newline at end of file diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/ZombieBase.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ZombieBase.c index 5aa034f8..cc14b963 100644 --- a/JM/CF/Scripts/4_World/CommunityFramework/Entities/ZombieBase.c +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ZombieBase.c @@ -33,4 +33,12 @@ modded class ZombieBase { return true; } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Entities/ztest/debug_ui_test.c b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ztest/debug_ui_test.c new file mode 100644 index 00000000..7e7827a2 --- /dev/null +++ b/JM/CF/Scripts/4_World/CommunityFramework/Entities/ztest/debug_ui_test.c @@ -0,0 +1,80 @@ +// This is only temporary testing code. Due to a script compile error the folder name is weird :) + +modded class ZombieBase +{ + void ZombieBase() + { + CF_Debug.Create(this); + } + + void ~ZombieBase() + { + CF_Debug.Destroy(this); + } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + override bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + DayZInfectedInputController dzip = GetInputController(); + + instance.Add("Movement Speed", dzip.GetMovementSpeed()); + instance.Add("Alert Level", dzip.GetAlertLevel()); + instance.Add("Vault", dzip.IsVault()); + instance.Add("Vault Height", dzip.GetVaultHeight()); + instance.Add("Mind State", dzip.GetMindState()); + instance.Add("Target Entity", dzip.GetTargetEntity()); + instance.Add("Look At Enabled", dzip.IsLookAtEnabled()); + instance.Add("Look At DirectionWS", dzip.GetLookAtDirectionWS()); + + return true; + } +}; + +modded class CarScript +{ + void CarScript() + { + CF_Debug.Create(this); + } + + void ~CarScript() + { + CF_Debug.Destroy(this); + } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + override bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + super.CF_OnDebugUpdate(instance, type); + + CarController cc = GetController(); + + instance.Add("Velocity", GetVelocity(this)); + instance.Add("Speedometer", GetSpeedometer()); + instance.Add("Fluid Capacity FUEL", GetFluidCapacity(CarFluid.FUEL)); + instance.Add("Fluid Fraction FUEL", GetFluidFraction(CarFluid.FUEL)); + instance.Add("Fluid Capacity OIL", GetFluidCapacity(CarFluid.OIL)); + instance.Add("Fluid Fraction OIL", GetFluidFraction(CarFluid.OIL)); + instance.Add("Fluid Capacity BRAKE", GetFluidCapacity(CarFluid.BRAKE)); + instance.Add("Fluid Fraction BRAKE", GetFluidFraction(CarFluid.BRAKE)); + instance.Add("Fluid Capacity COOLANT", GetFluidCapacity(CarFluid.COOLANT)); + instance.Add("Fluid Fraction COOLANT", GetFluidFraction(CarFluid.COOLANT)); + instance.Add("Engine On", EngineIsOn()); + instance.Add("Engine RPM", EngineGetRPM()); + instance.Add("Engine RPM Max", EngineGetRPMMax()); + instance.Add("Engine RPM Redline", EngineGetRPMRedline()); + instance.Add("Steering", cc.GetSteering()); + instance.Add("Thrust", cc.GetThrust()); + instance.Add("Thrust Turbo", cc.GetThrustTurbo()); + instance.Add("Thrust Gentle", cc.GetThrustGentle()); + instance.Add("Brake", cc.GetBrake()); + instance.Add("Gear", cc.GetGear()); + instance.Add("Gear Count", GetGearsCount()); + + return true; + } +}; diff --git a/JM/CF/Scripts/4_World/CommunityFramework/Plugins/PluginBase.c b/JM/CF/Scripts/4_World/CommunityFramework/Plugins/PluginBase.c new file mode 100644 index 00000000..17fece4a --- /dev/null +++ b/JM/CF/Scripts/4_World/CommunityFramework/Plugins/PluginBase.c @@ -0,0 +1,10 @@ +modded class PluginBase +{ + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } +}; diff --git a/JM/CF/Scripts/5_Mission/CommunityFramework/GUI/InGameMenu.c b/JM/CF/Scripts/5_Mission/CommunityFramework/GUI/InGameMenu.c new file mode 100644 index 00000000..66bc3f45 --- /dev/null +++ b/JM/CF/Scripts/5_Mission/CommunityFramework/GUI/InGameMenu.c @@ -0,0 +1,54 @@ +modded class InGameMenu +{ + void ~InGameMenu() + { + CF_Debug.CloseManager(); + } + + override Widget Init() + { + super.Init(); + + if (!CF_Debug.IsAllowed()) return layoutRoot; + + Widget wLeft = layoutRoot.FindAnyWidget("dayz_logo"); + Widget wRight = layoutRoot.FindAnyWidget("play_panel_root"); + + float x; + float y; + + float h; + float w; + + wLeft.GetScreenPos(x, y); + wLeft.GetScreenSize(w, h); + + x = x + w; + + wRight.GetScreenPos(w, h); + + w = w - x; + + Widget debugManager = CF_Debug.ShowManager(layoutRoot); + + float d_x; + float d_y; + float d_w; + float d_h; + + debugManager.GetScreenPos(d_x, d_y); + debugManager.GetScreenSize(d_w, d_h); + + int marginX = 0; + int marginY = 0; + + d_y = d_y / d_h; + d_h = d_h / d_h; + marginY = marginY / d_h; + + debugManager.SetPos(x + marginX, d_y + marginY); + debugManager.SetSize(w - (marginX * 2), d_h - (marginY * 2)); + + return layoutRoot; + } +}; \ No newline at end of file diff --git a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionBase.c b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionBase.c index 15cdf0e3..31135abd 100644 --- a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionBase.c +++ b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionBase.c @@ -11,10 +11,25 @@ modded class MissionBase { CreateModuleManager(new JMModuleConstructor()); } + + GetRPCManager().AddRPC("CF", "CF_DebugUIState", this, SingeplayerExecutionType.Client); + } + + void ~MissionBase() + { + CF._MissionCleanup(); } void OnMissionLoaded() { + CF._MissionInit(); + } + + override void OnMissionFinish() + { + super.OnMissionFinish(); + + CF._MissionCleanup(); } void CF_OnUpdate(float timeslice) @@ -32,4 +47,50 @@ modded class MissionBase CF_ModuleGameManager.OnUpdate(this, new CF_EventUpdateArgs(timeslice)); } + + override UIScriptedMenu CreateScriptedMenu(int id) + { + UIScriptedMenu menu = NULL; + + switch (id) + { + case CF_MVVM.MVVM_UI_MENU_ID: + menu = new CF_MVVM_Menu(); + break; + } + + if (menu) + { + menu.SetID(id); + } + else + { + menu = super.CreateScriptedMenu(id); + } + + return menu; + } + + void CF_DebugUIState(CallType type, ParamsReadContext ctx, PlayerIdentity sender, Object target) + { + Param1 data; + if (!ctx.Read(data)) return; + + if (type == CallType.Server) return; + + CF_Debug.SetAllowed(data.param1); + } + + void CF_SendDebugUIState(PlayerIdentity target) + { + GetRPCManager().SendRPC("CF", "CF_DebugUIState", new Param1(CF_Debug.IsAllowed()), true, target); + } + + /** + * @note When overriding and adding to the instance, you must return true. + */ + bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type) + { + return false; + } }; diff --git a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionGameplay.c b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionGameplay.c index 1b7cc6a6..1d07cb78 100644 --- a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionGameplay.c +++ b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionGameplay.c @@ -1,5 +1,13 @@ modded class MissionGameplay { + void MissionGameplay() + { + if (GetGame().IsServer()) + { + CF_Debug.SetAllowed(true); + } + } + override void OnMissionStart() { super.OnMissionStart(); diff --git a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionServer.c b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionServer.c index 3a3102e7..aa234f91 100644 --- a/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionServer.c +++ b/JM/CF/Scripts/5_Mission/CommunityFramework/Mission/MissionServer.c @@ -2,15 +2,43 @@ modded class MissionServer { void MissionServer() { + bool enabled = GetGame().ServerConfigGetInt("cfDebugUI") != 0; + CF_Debug.SetAllowed(enabled); + GetRPCManager().AddRPC( "CF", "RecieveModList", this, SingeplayerExecutionType.Server ); } + void ~MissionServer() + { + CF_Debug.SetAllowed(false); + } + override void OnEvent( EventType eventTypeId, Param params ) { super.OnEvent( eventTypeId, params ); switch( eventTypeId ) { + case ClientPrepareEventTypeID: + ClientPrepareEventParams clientPrepareParams; + Class.CastTo(clientPrepareParams, params); + CF_SendDebugUIState(clientPrepareParams.param1); + break; + case ClientNewEventTypeID: + ClientNewEventParams newParams; + Class.CastTo(newParams, params); + CF_SendDebugUIState(newParams.param1); + break; + case ClientReadyEventTypeID: + ClientReadyEventParams readyParams; + Class.CastTo(readyParams, params); + CF_SendDebugUIState(readyParams.param1); + break; + case ClientReadyEventTypeID: + ClientReconnectEventParams reconnectParams; + Class.CastTo(reconnectParams, params); + CF_SendDebugUIState(reconnectParams.param1); + break; case LogoutCancelEventTypeID: LogoutCancelEventParams logoutCancelParams; diff --git a/JM/CF/Scripts/Data/Inputs.xml b/JM/CF/Scripts/Data/Inputs.xml new file mode 100644 index 00000000..aa9b2f66 --- /dev/null +++ b/JM/CF/Scripts/Data/Inputs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JM/CF/Scripts/config.cpp b/JM/CF/Scripts/config.cpp index 87b707c5..d247fde7 100644 --- a/JM/CF/Scripts/config.cpp +++ b/JM/CF/Scripts/config.cpp @@ -28,6 +28,7 @@ class CfgMods creditsJson = "JM/CF/Scripts/Data/Credits.json"; version = "0.0.0"; versionPath = "JM/CF/scripts/Data/Version.hpp"; + inputs = "JM/CF/Scripts/Data/Inputs.xml"; author = "Jacob_Mango"; authorID = "76561198103677868"; extra = 0; @@ -37,6 +38,19 @@ class CfgMods class defs { + class widgetStyles + { + files[]= + { + }; + }; + class imageSets + { + files[]= + { + "JM/CF/GUI/textures/imageset.imageset" + }; + }; class engineScriptModule { value = ""; diff --git a/JM/CF/Workbench/dayz.gproj b/JM/CF/Workbench/dayz.gproj index c52bc656..0ffb4d86 100644 --- a/JM/CF/Workbench/dayz.gproj +++ b/JM/CF/Workbench/dayz.gproj @@ -26,6 +26,7 @@ GameProjectClass { "gui/imagesets/playstation_buttons.imageset" "gui/imagesets/selection.imageset" "gui/imagesets/console_toolbar.imageset" + "JM/CF/GUI/textures/imageset.imageset" } widgetStyles { "gui/looknfeel/dayzwidgets.styles" diff --git a/docs/Core/CF_KeyState.md b/docs/Core/CF_KeyState.md new file mode 100644 index 00000000..42e213bd --- /dev/null +++ b/docs/Core/CF_KeyState.md @@ -0,0 +1,10 @@ +# CF_KeyState + +enum + +## Values + +- NONE +- UP +- DOWN +- PRESS \ No newline at end of file diff --git a/docs/ExpressionVM/index.md b/docs/ExpressionVM/index.md index e3d437c4..d9a8b6fa 100644 --- a/docs/ExpressionVM/index.md +++ b/docs/ExpressionVM/index.md @@ -51,7 +51,7 @@ class ExpressionFunctionPow : CF_ExpressionFunction CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Pow(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer], param1); } - override string ToStr() + override string GetDebugName() { return CF_NAME; } diff --git a/docs/MVVM/Events.md b/docs/MVVM/Events.md new file mode 100644 index 00000000..090b6657 --- /dev/null +++ b/docs/MVVM/Events.md @@ -0,0 +1,166 @@ +# Events + +## Creating the Event in the Model + +Inside the model class you will want a method that handles the event called from the view. Follow the `Events` table below. + +e.g. Handling a click event would require the function signature: + +```csharp +void OnClick(CF_ModelBase sender, CF_MouseEventArgs args) +``` + +## Adding an Event in Workbench + +On the selected widget, navigate to the properties tab. Ensure that the `scriptclass` property is set to the relevant one for the widget. Read [Creating View](Creating-View.md) for more information. Scroll down to `Script Properties` and assign the model method created earlier to the `Event_X` property. + +## Adding an Event in a Text Editor + +Ensure that the `scriptclass` property is set to the relevant one for the widget. Read [Creating View](Creating-View.md) for more information. + +Within `ScriptParamsClass` assign the model method created earlier to the `Event_X` property. + +``` +ButtonWidgetClass button { + scriptclass "CF_ButtonWidget" + { + ScriptParamsClass { + Event_Click "OnClick" + } + } +} +``` + +## Events +| Name | EventArgs | Notes | +| --------------------- | -------------------------------------------------- | ------------------------------------------------------------ | +| Event_Click | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_ModalResult | [CF_ModalEventArgs](#CF_ModalEventArgs) | | +| Event_DoubleClick | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_Select | [CF_SelectEventArgs](#CF_SelectEventArgs) | | +| Event_ItemSelected | [CF_ItemSelectEventArgs](#CF_ItemSelectEventArgs) | | +| Event_Focus | [CF_PositionEventArgs](#CF_PositionEventArgs) | | +| Event_FocusLost | [CF_PositionEventArgs](#CF_PositionEventArgs) | | +| Event_MouseEnter | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_MouseLeave | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_MouseWheel | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_MouseButtonDown | [CF_MouseEventArgs](#CF_MouseEventArgs) | `Continue` set to `false` prevents `Event_Click` from firing | +| Event_MouseButtonUp | [CF_MouseEventArgs](#CF_MouseEventArgs) | | +| Event_Controller | [CF_ControllerEventArgs](#CF_ControllerEventArgs) | | +| Event_KeyDown | [CF_KeyEventArgs](#CF_KeyEventArgs) | | +| Event_KeyUp | [CF_KeyEventArgs](#CF_KeyEventArgs) | | +| Event_KeyPress | [CF_KeyEventArgs](#CF_KeyEventArgs) | | +| Event_Change | [CF_ChangeEventArgs](#CF_ChangeEventArgs) | | +| Event_Drag | [CF_DragEventArgs](#CF_DragEventArgs) | | +| Event_Dragging | [CF_DragEventArgs](#CF_DragEventArgs) | | +| Event_DraggingOver | [CF_DragEventArgs](#CF_DragEventArgs) | | +| Event_Drop | [CF_DragEventArgs](#CF_DragEventArgs) | | +| Event_DropReceived | [CF_DragEventArgs](#CF_DragEventArgs) | | +| Event_Resize | [CF_ResizeEventArgs](#CF_ResizeEventArgs) | | +| Event_ChildAdd | [CF_ChildEventArgs](#CF_ChildEventArgs) | | +| Event_ChildRemove | [CF_ChildEventArgs](#CF_ChildEventArgs) | | +| Event_Update | [CF_ViewEventArgs](#CF_ViewEventArgs) | | +| Event_Show | [CF_ViewEventArgs](#CF_ViewEventArgs) | | +| Event_Hide | [CF_ViewEventArgs](#CF_ViewEventArgs) | | +| Event_Destroyed | [CF_ViewEventArgs](#CF_ViewEventArgs) | | + +## Event Args + +### CF_ChangeEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| What | string | The name of the variable in the model for what was changed | +| Finished | bool | If the change event is finished | + +### CF_ChildEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Child | Widget | The widget that was changed | +| Remove | bool | True if the change was removal, false if addition | + +### CF_ControllerEventArgs + +Inherits arguments from [CF_ViewEventArgs](#CF_ViewEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Control | int | The controller code | +| Value | int | The value of the controller | + +### CF_DragEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Reciever | Widget | The widget recieving the dragged widget | + +### CF_ItemSelectEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Row | int | The row the selected item is in | +| Column | int | The column the selected item is in | +| OldRow | int | The row the selected item was in | +| OldColumn | int | The column the selected item was in | + +### CF_KeyEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Key | int | The key code | +| State | CF_KeyState | The state of the key code | + +### CF_ModalEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Code | int | The code assigned to the modal | +| Result | int | The result the modal gave | + +### CF_MouseEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Button | int | The mouse button click | +| Enter | int | The widget the mouse left the target for | +| Wheel | int | The amount the mouse wheel moved | +| Type | int | The type of mouse event, 0 for default, 1 for enter and 2 for leave | + +### CF_PositionEventArgs + +Inherits arguments from [CF_ViewEventArgs](#CF_ViewEventArgs) + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| X | int | The screen X position the mouse is at | +| Y | int | The screen Y position the mouse is at | + +### CF_ResizeEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +### CF_SelectEventArgs + +Inherits arguments from [CF_PositionEventArgs](#CF_PositionEventArgs) + +### CF_ViewEventArgs + +| Name | Type | Description | +| ----------------- | ------------- | -------------------------------------------------------------------------- | +| Target | Widget | The target widget the event is firing upon | +| Continue | bool | If the event should continue with default behaviour | diff --git a/docs/MVVM/Model.md b/docs/MVVM/Model.md new file mode 100644 index 00000000..50d91a62 --- /dev/null +++ b/docs/MVVM/Model.md @@ -0,0 +1 @@ +# Model diff --git a/docs/MVVM/Using-Menu.md b/docs/MVVM/Using-Menu.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/MVVM/View.md b/docs/MVVM/View.md new file mode 100644 index 00000000..20dd6e82 --- /dev/null +++ b/docs/MVVM/View.md @@ -0,0 +1,29 @@ +# View + +## Properties + +Properies are linked through script to the name of the variable in the model. [TypeConverters](../TypeConverters/index.md) is used for making the input variable as expected for the property. + +``` +TextWidgetClass { + scriptclass "CF_TextWidget" + { + ScriptParamsClass { + Text "NameOfVariable" + } + } +} +``` + +For all properties, custom TypeConverters can be used. Documentation for creating [TypeConverters](../TypeConverters/index.md). You do not need to register the TypeConverter using attributes. Just place the name of the class at the end of the variable, preceeded by a colon (`:`). This is beneficial for when you want to create a custom typeconverter for a primitive type that does not affect the existing type converters for that primitive type. + +``` +TextWidgetClass { + scriptclass "CF_TextWidget" + { + ScriptParamsClass { + Text "NameOfVariable:NameOfTypeConverterClass" + } + } +} +``` diff --git a/docs/MVVM/index.md b/docs/MVVM/index.md new file mode 100644 index 00000000..368ba403 --- /dev/null +++ b/docs/MVVM/index.md @@ -0,0 +1,9 @@ +# MVVM + +## [Creating Model](Creating-Model.md) + +## [Creating View](Creating-View.md) + +## [Using Menu](Using-Menu.md) + +## [Events](Events.md) \ No newline at end of file diff --git a/docs/Streams/index.md b/docs/Streams/index.md index c48f808a..4922513d 100644 --- a/docs/Streams/index.md +++ b/docs/Streams/index.md @@ -55,7 +55,7 @@ CF_BinaryWriter writer = new CF_BinaryWriter(stream); writer.WriteFloat(5); writer.Close(); -Print(stream.ToStr()); // "40A00000" +Print(stream.GetDebugName()); // "40A00000" ``` ## Serializer diff --git a/docs/Windows/index.md b/docs/Windows/index.md new file mode 100644 index 00000000..e69de29b diff --git a/sources/imageset.tga b/sources/imageset.tga new file mode 100644 index 00000000..4d340cfa Binary files /dev/null and b/sources/imageset.tga differ