Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENHANCEMENT] xtd.forms - message_notifier #180

Open
1 task
gammasoft71 opened this issue May 17, 2022 · 3 comments
Open
1 task

[ENHANCEMENT] xtd.forms - message_notifier #180

gammasoft71 opened this issue May 17, 2022 · 3 comments
Assignees
Labels
enhancement New feature or request In progress
Milestone

Comments

@gammasoft71
Copy link
Owner

xtd.forms - xtd::forms::message_notifier

Library

xtd.forms

Enhancement

xtd::forms::message_notifier

Description

message_notifier is a small, nonblocking notification pop-up. A message_notifier is shown to users with readable message content at the bottom or top of the screen or at a specific target and disappears automatically after a few seconds (time-out). The control has various built-in options for customizing visual elements, durations, and dismissing toasts.

  • xtd::forms::message_notifier component

First draft

Unfortunately, the different OS don't manage the notifications in the same way.
So, we should have as for the dialog box xtd::forms::about_dialog manage the two styles of dialog:

  • xtd::forms::dialog_style::standard (notification managed by xtd)
  • xtd::forms::dialog_style::system (notification system).

Notification system :

Use wxNotificationMessage whenever possible. But typically, on macOS it doesn't work (Maybe for a user right ?).
And if the wxWidgets component doesn't match maybe call the native version for each OS (as I did for xtd::forms::message_box which was not implemented correctly in macOS and Windows).

Standard notification :

Implement our own xtd::forms::form (no border, no title and no controls). Add an image, a message and the possibility of 1, 2 or more buttons.
Add an xtd::forms::timer for automatic closing.

Common

  • Add asynchronous button events (like xtd::forms::show_sheet) which allows to know which button has been clicked.
  • Add a close event.
  • add properties for the message_notifier

API

Globally the API will be close to xtd::forms::message_dialog and xtd::forms::message_box with the possibility to have custom buttons and a timer to close the notification automatically.

@gammasoft71 gammasoft71 added the enhancement New feature or request label May 17, 2022
@gammasoft71 gammasoft71 added this to the 0.2.0 milestone May 17, 2022
@gammasoft71 gammasoft71 self-assigned this May 17, 2022
@gammasoft71 gammasoft71 moved this from Todo to In Progress in xtd - kanban board May 18, 2022
@baderouaich
Copy link
Collaborator

baderouaich commented May 20, 2022

It may be a good approach to be able to use xtd::forms::message_notifier like this (as initial mock-up):

message_notifier mn;
mn.title("TITLE");
mn.message("MESSAGE"):
mn.notifier_style(message_notifier_style::information | warning | error); // if an icon is set, the system icon style will be overwritten with the icon.
mn.icon(xtd::drawing::icon::empty); // if icon is empty, system icon style (message_notifier_style) will be displayed instead.
mn.button_action("Ok", []() {
    xtd::diagnostics::debug::write_line("Action: Ok");
 });
mn.button_action("Cancel", []() {
    xtd::diagnostics::debug::write_line("Action: Cancel");
 });
 // .. as many button actions as we like ..
mn.click += [] {
    xtd::diagnostics::debug::write_line("Event: message notifier clicked");
};
mn.notifier_closed += [] {
    xtd::diagnostics::debug::write_line("Event: message notifier closed");
};
mn.timeout(10 * 1000); // timeout in milliseconds
mn.show();

@gammasoft71
Copy link
Owner Author

gammasoft71 commented May 20, 2022

For the events, I prefer to have only a close event and to be able to get the result of the notifier a bit like for the message_dialog.
This allows to keep the same consistency in the whole framework. If someone knows the message_dialog, he automatically knows the message_notifier and vice versa ;-).

I really see the message_notifier class as the message_dialog class. With a timeout that can be activated or not to close automatically the notification.
And just the possibility to change the text of the buttons (I would also like to add this possibility to message_dialog ;-)).

Look at the following example of the message_dialog in asynchronous.

Implementation sheet...

namespace xtd {
  enum class notifier_result {
    ok,
    cancel,
    yes,
    no,
    //...
  };
  
  class notifier_closed_event_args : public xtd::event_Args {
  public:
    //...
  
    xtd::forms::notifier_result notifier_reult() const;
  
  //...
  };

  class message_notifier : public xtd::forms::componant {
  public:
    /// ...
    
    /// Properties
    
    bool close_timeout_enabled() const;
    message_notifier& close_timeout_enabled(bool value);
    
    std::chrono::milliseconds close_timeout_interval() const;
    message_notifier& close_timeout_interval(std::chrono::milliseconds value);
    message_notifier& close_timeout_interval_milliseconds(int32_t value);
    
    const xtd::string& button_ok_text() const;
    message_notifier& button_ok_text(const xtd::string& value);
    message_notifier& button_ok_text(std::nullptr_t); // Reset to default value
    
    xtd::forms::notifier_result notifier_result() const;
    
    /// ...

    xtd::forms::message_notifier_buttons buttons() const;
    message_notifier& buttons(xtd::forms::message_notifier_buttons value);
    
    const xtd::drawing::image& icon() const;
    message_notifier& icon(xtd::forms::message_notifier_icon value);
    message_notifier& icon(const xtd::drawing::image&);
    message_notifier& icon(const xtd::drawing::icon&);
    
    /// Events
    event<message_notifier, xtd::forms::notifier_closed_event_handler> notifier_closed;
    
  protected:
    virtual void on_notifier_closed(const xtd::forms::notifier_closed_event_args& e);

    // ...     
  };
}

Example of message_notifier usage :

message_notifier notfier;
notifier.title("Title");
notifier.message("message...");
notifier.notifier_icon();
notifier.icon(message_notifier_icon::question); // or: notifier.icon(xtd::drawing::image("my_icon"));
notifier.buttons(message_notifier::buttons::ok_cancel);
notifier.cancel_button_text("Dismiss");
notifier.notifier_closed += [&](const notifier_closed_event_args& e) {
  if (e.notifier_result() == notifier_result::ok) // or: if (notifier.notifier_result() == notifier_result::ok)
   //...
};
notifier.show();

Repository owner moved this from In Progress to Done in xtd - kanban board May 20, 2022
@gammasoft71 gammasoft71 reopened this May 20, 2022
Repository owner moved this from Done to In Progress in xtd - kanban board May 20, 2022
@gammasoft71
Copy link
Owner Author

After some thought and research, the following code shows the new implementation proposal:

namespace xtd {
  namespace forms {
    class notifier_button : public xtd::forms::component {
      public:
        notifier_button() = default;
        notifier_button(const xtd::ustring& text);
        
        const xtd::ustring& text() const noexcept;
        notifier_button& text(const xtd::ustring& value);
    };
    
    using notifier_button_ref = std::reference_wrapper<notifier_button>;

    class notifier_button_click_event_args : public xtd::event_args {
    public:
      //...
    
      xtd::forms::notifier_button button() const;
    
    //...
    };
  
    class notifier_closed_event_args : public xtd::event_args {
    public:
      //...
    
      std::optional<xtd::forms::notifier_button> button() const;
      bool close_on_timeout() const noexcept;
      bool close_on_click_message() const noexcept;
    
      //...
    };

    class message_notifier : public xtd::forms::componant {
    public:
      /// ...

      /// @name Alias
      
      using notifier_button_collection = xtd::forms::layout::arranged_element_collection<notifier_button_ref>;
      
      /// Properties
      
      const notifier_button_collection& buttons() const noexcept;
      notifier_button_collection& buttons();

      
      bool close_timeout_enabled() const noexcept;
      message_notifier& close_timeout_enabled(bool value);
      
      std::chrono::milliseconds close_timeout_interval() const noexcept;
      message_notifier& close_timeout_interval(std::chrono::milliseconds value);
      message_notifier& close_timeout_interval_milliseconds(int32_t value);
      
      std::optional<xtd::forms::notifier_button> notifier_button_clicked() const;
      
      /// ...
  
      const xtd::drawing::image& icon() const;
      message_notifier& icon(const xtd::drawing::image&);
      message_notifier& icon(const xtd::drawing::icon&);
      
      /// Events
      
      event<message_notifier, xtd::forms::notifier_button_click_event_handler> button_click;
      event<message_notifier, xtd::forms::notifier_closed_event_handler> notifier_closed;
      
    protected:
      virtual void on_button_click(const xtd::forms::message_notifier_button_click_event_args& e);
      virtual void on_notifier_closed(const xtd::forms::notifier_closed_event_args& e);

      // ...     
    };
  }
}

And usage :

#include <xtd/xtd>

using namespace xtd;
using namespace std::literals;
using namespace xtd::forms;

namespace examples {
  class form1 : public form {
  public:
    form1() {
      text("Message notifier example");
      
      button1.parent(*this);
      button1.location({10, 10});
      button1.text("Notify");
      button1.click += [&] {
        message_notifier1.show();
      };
      
      message_notifier1.buttons().push_back_range({start_message_notifier_button, cancel_message_notifier_button});
      message_notifier1.close_timeout_enabled(true);
      message_notifier1.close_timeout_interval(2s);
      message_notifier1.icon(xtd::drawing::system_icons::question());
      message_notifier1.message("Start the auto backup now");
      message_notifier1.notifier_style(notifier_style::standard);
      message_notifier1.title("Backup");
      message_notifier.button_click += {*this, &form1::on_message_notifier_button_click};
    }
    
  private:
    void on_message_notifier_button_click(object& sender, const on_message_notifier_button_click_event_args& e) {
      if (e.button() == start_message_notifier_button)
        diagnostics::debug::write_line("Start backup");
      else
        diagnostics::debug::write_line("Cancel backup");
    }

    button button1;
    message_notifier_button start_message_notifier_button {"&Start"};
    message_notifier_button cancel_message_notifier_button {"&Cancel"};
    message_notifier message_notifier1;
  };
}

int main() {
  application::run(examples::form1());
}

@baderouaich baderouaich changed the title [ENHANCEMENT] xtd.forms - xtd::forms::message_notifier [ENHANCEMENT] xtd.forms - message_notifier Nov 24, 2022
@gammasoft71 gammasoft71 removed this from the 0.2.0 milestone Mar 28, 2023
@gammasoft71 gammasoft71 added this to the 0.3.0 milestone Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request In progress
Projects
Status: In Progress
Development

No branches or pull requests

2 participants