1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef CONTEXT_MENU_HXX
19#define CONTEXT_MENU_HXX
20
21#include "bspf.hxx"
22#include "Command.hxx"
23#include "Dialog.hxx"
24#include "Variant.hxx"
25
26/**
27 * Popup context menu which, when clicked, "pop up" a list of items and
28 * lets the user pick on of them.
29 *
30 * Implementation wise, when the user selects an item, then the given 'cmd'
31 * is broadcast, with data being equal to the tag value of the selected entry.
32 *
33 * There are also several utility methods (named as sendSelectionXXX) that
34 * allow to cycle through the current items without actually opening the dialog.
35 */
36class ContextMenu : public Dialog, public CommandSender
37{
38 public:
39 enum {
40 kItemSelectedCmd = 'CMsl'
41 };
42
43 public:
44 ContextMenu(GuiObject* boss, const GUI::Font& font,
45 const VariantList& items, int cmd = 0, int width = 0);
46 virtual ~ContextMenu() = default;
47
48 /** Add the given items to the widget. */
49 void addItems(const VariantList& items);
50
51 /** Show context menu onscreen at the specified coordinates */
52 void show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int item = -1);
53
54 /** Select the first entry matching the given tag. */
55 void setSelected(const Variant& tag, const Variant& defaultTag);
56
57 /** Select the entry at the given index. */
58 void setSelectedIndex(int idx);
59
60 /** Select the highest/last entry in the internal list. */
61 void setSelectedMax();
62
63 /** Clear selection (reset to default). */
64 void clearSelection();
65
66 /** Accessor methods for the currently selected item. */
67 int getSelected() const;
68 const string& getSelectedName() const;
69 const Variant& getSelectedTag() const;
70
71 /** This dialog uses its own positioning, so we override Dialog::center() */
72 void center() override;
73
74 /** The following methods are used when we want to select *and*
75 send a command for the new selection. They are only to be used
76 when the dialog *isn't* open, and are basically a shortcut so
77 that a PopUpWidget has some basic functionality without forcing
78 to open its associated ContextMenu. */
79 bool sendSelectionUp();
80 bool sendSelectionDown();
81 bool sendSelectionFirst();
82 bool sendSelectionLast();
83
84 private:
85 void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
86 void handleMouseMoved(int x, int y) override;
87 bool handleMouseClicks(int x, int y, MouseButton b) override;
88 void handleMouseWheel(int x, int y, int direction) override;
89 void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
90 void handleJoyDown(int stick, int button, bool longPress) override;
91 void handleJoyAxis(int stick, JoyAxis axis, JoyDir adir, int button) override;
92 bool handleJoyHat(int stick, int hat, JoyHatDir vahdirlue, int button) override;
93 void handleEvent(Event::Type e);
94
95 void drawDialog() override;
96
97 void recalc(const Common::Rect& image);
98
99 int findItem(int x, int y) const;
100 void drawCurrentSelection(int item);
101
102 void moveUp();
103 void moveDown();
104 void movePgUp();
105 void movePgDown();
106 void moveToFirst();
107 void moveToLast();
108 void moveToSelected();
109 void scrollUp(int distance = 1);
110 void scrollDown(int distance = 1);
111 void sendSelection();
112
113 private:
114 VariantList _entries;
115
116 int _rowHeight;
117 int _firstEntry, _numEntries;
118 int _selectedOffset, _selectedItem;
119 bool _showScroll;
120 bool _isScrolling;
121 ColorId _scrollUpColor, _scrollDnColor;
122
123 int _cmd;
124
125 uInt32 _xorig, _yorig;
126 uInt32 _maxWidth;
127
128 private:
129 // Following constructors and assignment operators not supported
130 ContextMenu() = delete;
131 ContextMenu(const ContextMenu&) = delete;
132 ContextMenu(ContextMenu&&) = delete;
133 ContextMenu& operator=(const ContextMenu&) = delete;
134 ContextMenu& operator=(ContextMenu&&) = delete;
135};
136
137#endif
138