#pragma once #include "common/FlagsEnum.hpp" #include "common/Singleton.hpp" #include "widgets/splits/SplitContainer.hpp" #include #include #include #include namespace chatterino { class Settings; class Paths; class Window; class ChannelView; class IndirectChannel; class Split; struct SplitDescriptor; class Channel; using ChannelPtr = std::shared_ptr; struct Message; using MessagePtr = std::shared_ptr; class WindowLayout; enum class MessageElementFlag : int64_t; using MessageElementFlags = FlagsEnum; enum class WindowType; enum class SettingsDialogPreference; class FramelessEmbedWindow; class WindowManager final : public Singleton { public: static const QString WINDOW_LAYOUT_FILENAME; WindowManager(); ~WindowManager() override; static void encodeTab(SplitContainer *tab, bool isSelected, QJsonObject &obj); static void encodeChannel(IndirectChannel channel, QJsonObject &obj); static void encodeFilters(Split *split, QJsonArray &arr); static IndirectChannel decodeChannel(const SplitDescriptor &descriptor); void showSettingsDialog( QWidget *parent, SettingsDialogPreference preference = SettingsDialogPreference()); // Show the account selector widget at point void showAccountSelectPopup(QPoint point); // Tell a channel (or all channels if channel is nullptr) to redo their // layout void layoutChannelViews(Channel *channel = nullptr); // Force all channel views to redo their layout // This is called, for example, when the emote scale or timestamp format has // changed void forceLayoutChannelViews(); void repaintVisibleChatWidgets(Channel *channel = nullptr); void repaintGifEmotes(); Window &getMainWindow(); // Returns a pointer to the last selected window. // Edge cases: // - If the application was not focused since the start, this will return a pointer to the main window. // - If the window was closed this points to the main window. // - If the window was unfocused since being selected, this function will still return it. Window *getLastSelectedWindow() const; Window &createWindow(WindowType type, bool show = true, QWidget *parent = nullptr); // Use this method if you want to open a "new" channel in a popup. If you want to popup an // existing Split or SplitContainer, consider using Split::popup() or SplitContainer::popup(). Window &openInPopup(ChannelPtr channel); void select(Split *split); void select(SplitContainer *container); /** * Scrolls to the message in a split that's not * a mentions view and focuses the split. * * @param message Message to scroll to. */ void scrollToMessage(const MessagePtr &message); QPoint emotePopupPos(); void setEmotePopupPos(QPoint pos); void initialize(Settings &settings, Paths &paths) override; void save() override; void closeAll(); int getGeneration() const; void incGeneration(); MessageElementFlags getWordFlags(); void updateWordTypeMask(); // Sends an alert to the main window // It reads the `longAlert` setting to decide whether the alert will expire // or not void sendAlert(); // Queue up a save in the next 10 seconds // If a save was already queued up, we reset the to happen in 10 seconds // again void queueSave(); /// Signals pajlada::Signals::NoArgSignal gifRepaintRequested; // This signal fires whenever views rendering a channel, or all views if the // channel is a nullptr, need to redo their layout pajlada::Signals::Signal layoutRequested; pajlada::Signals::NoArgSignal wordFlagsChanged; pajlada::Signals::Signal selectSplit; pajlada::Signals::Signal selectSplitContainer; pajlada::Signals::Signal scrollToMessageSignal; private: static void encodeNodeRecursively(SplitContainer::Node *node, QJsonObject &obj); // Load window layout from the window-layout.json file WindowLayout loadWindowLayoutFromFile() const; // Apply a window layout for this window manager. void applyWindowLayout(const WindowLayout &layout); // Contains the full path to the window layout file, e.g. /home/pajlada/.local/share/Chatterino/Settings/window-layout.json const QString windowLayoutFilePath; bool initialized_ = false; QPoint emotePopupPos_; std::atomic generation_{0}; std::vector windows_; std::unique_ptr framelessEmbedWindow_; Window *mainWindow_{}; Window *selectedWindow_{}; MessageElementFlags wordFlags_{}; pajlada::SettingListener wordFlagsListener_; QTimer *saveTimer; friend class Window; // this is for selectedWindow_ }; } // namespace chatterino