contextmenu.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. //--------------------------------------------------------------------------
  2. class ContextMenu extends ScriptedWidgetEventHandler
  3. {
  4. protected static ref ContextMenu m_ContextMenuInstance;
  5. Widget m_context_menu_root_widget;
  6. private Widget m_context_menu_panel_widget;
  7. private ref array<ref CallQueueContext> m_commands;
  8. private int m_max_item_width;
  9. private int m_count;
  10. private bool m_builtIn = false;
  11. const int ITEMS_COUNT = 27;
  12. //--------------------------------------------------------------------------
  13. void ContextMenu()
  14. {
  15. m_commands = new array<ref CallQueueContext>;
  16. m_count = 0;
  17. }
  18. //--------------------------------------------------------------------------
  19. void ~ContextMenu()
  20. {
  21. Clear();
  22. delete m_context_menu_root_widget;
  23. }
  24. //--------------------------------------------------------------------------
  25. void Init(Widget layoutRoot, bool builtIn = false)
  26. {
  27. m_builtIn = builtIn;
  28. if (!m_context_menu_root_widget)
  29. {
  30. m_context_menu_root_widget = GetGame().GetWorkspace().CreateWidgets("gui/layouts/day_z_inventory_context_menu.layout", layoutRoot);
  31. m_context_menu_panel_widget = m_context_menu_root_widget.FindAnyWidget("PanelWidget");
  32. m_context_menu_root_widget.Show(false);
  33. m_context_menu_root_widget.SetHandler(this);
  34. }
  35. }
  36. //--------------------------------------------------------------------------
  37. void Show(int x, int y)
  38. {
  39. if ( m_count == 0) return;
  40. int screen_w, screen_h;
  41. float w, h;
  42. float sx, sy;
  43. int offset_x;// = -20;
  44. int offset_y;// = -10;
  45. GetScreenSize(screen_w, screen_h);
  46. // align buttons
  47. float button_height_percent = 0.02; // button height is 4% of screen height
  48. float button_height = screen_h * button_height_percent;
  49. for ( int i = 0; i < m_count; i++)
  50. {
  51. ButtonWidget menu_button = ButtonWidget.Cast( m_context_menu_root_widget.FindAnyWidget( String( "Button" + (i+1).ToString() ) ) );
  52. if (menu_button)
  53. {
  54. menu_button.SetSize(0.90, button_height);
  55. menu_button.Show(true);
  56. }
  57. }
  58. AutoHeightSpacer spacer;
  59. m_context_menu_panel_widget.GetScript(spacer);
  60. if ( spacer )
  61. {
  62. spacer.Update();
  63. }
  64. m_context_menu_root_widget.GetSize(w, h);
  65. m_context_menu_panel_widget.GetSize(sx, sy);
  66. m_context_menu_root_widget.SetSize(w, sy);
  67. // set position
  68. m_context_menu_root_widget.GetScreenSize(w,h);
  69. screen_w -= 10;
  70. screen_h -= 10;
  71. int right_edge = x + w - offset_x;
  72. if (right_edge > screen_w)
  73. {
  74. x = screen_w - w - offset_x;
  75. }
  76. else
  77. {
  78. x = x + offset_x;
  79. }
  80. int bottom_edge = y + h - offset_y;
  81. if (bottom_edge > screen_h)
  82. {
  83. y = y - h - offset_y;
  84. }
  85. else
  86. {
  87. y = y + offset_y;
  88. }
  89. m_context_menu_root_widget.SetPos(x, y);
  90. m_context_menu_root_widget.Show(true);
  91. }
  92. //--------------------------------------------------------------------------
  93. void SetSize(float x, float y)
  94. {
  95. m_context_menu_root_widget.SetSize(x, y);
  96. }
  97. //--------------------------------------------------------------------------
  98. void ShowBackdrop(bool show)
  99. {
  100. if (show == true)
  101. {
  102. m_context_menu_root_widget.FindAnyWidget("BackdropImageWidget").Show(true);
  103. }
  104. else
  105. {
  106. m_context_menu_root_widget.FindAnyWidget("BackdropImageWidget").Show(false);
  107. }
  108. }
  109. //--------------------------------------------------------------------------
  110. void Hide()
  111. {
  112. m_context_menu_root_widget.Show(false);
  113. Clear();
  114. }
  115. //--------------------------------------------------------------------------
  116. bool IsVisible()
  117. {
  118. return m_context_menu_root_widget.IsVisible();
  119. }
  120. //--------------------------------------------------------------------------
  121. override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
  122. {
  123. super.OnMouseLeave(w, enterW, x, y);
  124. if ( !m_builtIn && enterW && m_context_menu_panel_widget && enterW != m_context_menu_panel_widget && enterW.GetParent() != m_context_menu_panel_widget )
  125. {
  126. Hide();
  127. return true;
  128. }
  129. return false;
  130. }
  131. //--------------------------------------------------------------------------
  132. override bool OnMouseButtonDown(Widget w, int x, int y, int button)
  133. {
  134. super.OnMouseButtonDown(w, x, y, button);
  135. if (button == MouseState.LEFT && w.GetUserID() > -1 && w.GetUserID() < m_commands.Count())
  136. {
  137. CallQueueContext ctx = m_commands.Get(w.GetUserID());
  138. int actionId = Param3<EntityAI, int, int>.Cast(ctx.m_params).param2;
  139. if (actionId == EActions.DELETE)
  140. Hide();
  141. UIScriptedMenu menu = GetGame().GetUIManager().GetMenu();
  142. if (menu)
  143. GetGame().GetCallQueue(CALL_CATEGORY_GUI).Call(menu.Refresh);
  144. ctx.Call();
  145. return true;
  146. }
  147. return false;
  148. }
  149. //--------------------------------------------------------------------------
  150. void Add(string label, Class obj, string fn_name, Param params)
  151. {
  152. AddEx(label, FadeColors.LIGHT_GREY, obj, fn_name, params);
  153. }
  154. void AddEx(string label, int labelColor, Class obj, string funcName, Param params)
  155. {
  156. int count = Count();
  157. ButtonWidget menuButton = ButtonWidget.Cast(m_context_menu_root_widget.FindAnyWidget(string.Format("Button%1", count + 1)));
  158. if (menuButton)
  159. {
  160. label.ToUpper();
  161. menuButton.SetText(label);
  162. menuButton.SetTextColor(labelColor);
  163. menuButton.Show(true);
  164. if (funcName == "")
  165. {
  166. menuButton.SetFlags(menuButton.GetFlags() | WidgetFlags.IGNOREPOINTER);
  167. }
  168. else
  169. {
  170. menuButton.ClearFlags(WidgetFlags.IGNOREPOINTER);
  171. }
  172. int itemWidth = label.Length();
  173. if (m_max_item_width < itemWidth)
  174. m_max_item_width = itemWidth;
  175. }
  176. m_count++;
  177. m_commands.Insert(new CallQueueContext(obj, funcName, params));
  178. }
  179. //--------------------------------------------------------------------------
  180. void Remove(int index)
  181. {
  182. if (index < m_commands.Count())
  183. {
  184. m_commands.RemoveOrdered(index);
  185. ButtonWidget menu_button = ButtonWidget.Cast( m_context_menu_root_widget.FindAnyWidget( String( "Button" + ( index + 1 ).ToString() ) ) );
  186. menu_button.Show( false );
  187. menu_button.SetText( "" );
  188. m_count--;
  189. }
  190. }
  191. //--------------------------------------------------------------------------
  192. int Count()
  193. {
  194. return m_commands.Count();
  195. }
  196. //--------------------------------------------------------------------------
  197. void Clear()
  198. {
  199. int i;
  200. m_commands.Clear();
  201. if (!m_context_menu_panel_widget)
  202. return;
  203. Widget child = m_context_menu_panel_widget.GetChildren();
  204. while(child)
  205. {
  206. ButtonWidget button = ButtonWidget.Cast(child);
  207. if(button)
  208. {
  209. button.Show(false);
  210. }
  211. child = child.GetSibling();
  212. }
  213. m_count = 0;
  214. m_max_item_width = 0;
  215. }
  216. void BuildContextMenu(notnull EntityAI entity, notnull Widget rootWidget, Class target)
  217. {
  218. Clear();
  219. TSelectableActionInfoArrayEx customActions = new TSelectableActionInfoArrayEx();
  220. entity.GetDebugActions(customActions);
  221. int actionsCount = customActions.Count();
  222. for (int i = 0; i < customActions.Count(); i++)
  223. {
  224. TSelectableActionInfoWithColor actionInfo = TSelectableActionInfoWithColor.Cast(customActions.Get(i));
  225. if (actionInfo)
  226. {
  227. int actionId = actionInfo.param2;
  228. int textColor = actionInfo.param4;
  229. string actionText = actionInfo.param3;
  230. if (actionId == EActions.SEPARATOR)
  231. AddEx(actionText, textColor, null, "", null);
  232. else
  233. AddEx(actionText, textColor, target, "OnSelectAction", new Param3<EntityAI, int, int>(entity, actionId, textColor));
  234. }
  235. }
  236. }
  237. //--------------------------------------------------------------------------
  238. static void DisplayContextMenu(int x, int y, notnull EntityAI entity, notnull Widget rootWidget, Class target)
  239. {
  240. m_ContextMenuInstance = new ContextMenu();
  241. if (m_ContextMenuInstance)
  242. {
  243. m_ContextMenuInstance.Init(rootWidget);
  244. m_ContextMenuInstance.BuildContextMenu(entity, rootWidget, target);
  245. m_ContextMenuInstance.SetSize(1,1);
  246. m_ContextMenuInstance.Show(x, y);
  247. }
  248. }
  249. };