Commit 04d257c1 authored by Loic Guegan's avatar Loic Guegan
Browse files

Improve GUI

parent 7554a929
Pipeline #215227722 failed with stage
in 7 minutes and 25 seconds
......@@ -8,7 +8,8 @@ if(APPLE)
message(STATUS "Using C++11 for OSX")
set(CMAKE_CXX_STANDARD 11) # On OSX c++14 generate warning (since we have -Werror ...)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra") # Be hard-liner
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra") # Be hard-liner
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") # Be hard-liner
########## DEPENDENCIES ##########
# Find boost
......@@ -36,7 +37,6 @@ link_directories(${wxWidgets_LIBRARIES_DIRS})
set(SRC ${CMAKE_SOURCE_DIR}/src)
# Model Module
file(GLOB_RECURSE CMD ${SRC}/command/*.cpp)
file(GLOB_RECURSE CNF ${SRC}/config/*.cpp)
file(GLOB_RECURSE ENGINE ${SRC}/engine/*.cpp)
file(GLOB_RECURSE MODEL ${SRC}/model/*.cpp)
file(GLOB_RECURSE UTILS ${SRC}/utils/*.cpp)
......
#include "Configurable.hpp"
namespace ochess {
void Configurable::ConfSet(string key, string value) {
Settings.put(key, value);
}
string Configurable::ConfGet(string key) {
return (Settings.get<string>(key));
}
vector<string> Configurable::ConfList() {
vector<string> keys;
for (auto pair : Settings) {
keys.push_back(pair.first);
}
return (keys);
}
}
#ifndef CONFIG_CONFIGURABLE_HPP_
#define CONFIG_CONFIGURABLE_HPP_
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <vector>
using namespace boost::property_tree;
using namespace std;
namespace ochess {
// To use friend declaration
class ConfigManager;
/**
* @class Configurable
* @brief You should inherit from this class to be able to register to the \a ConfigManager.
*
* Public member function are usually used by the ConfigManager and the protected member
* by the child class.
*
*/
class Configurable {
/// Allow the ConfigManager to have control
friend ConfigManager;
/// @brief Contains the current module settings
ptree Settings;
/// @brief Contains the actual module name who request for being Configurable
string Name;
protected:
/**
* @brief Be careful to use a @b UNIQUE module name
* @param moduleName
*/
Configurable(string moduleName) :
Name(moduleName) {
}
/**
* @brief Assign a setting value to a key
* @param key Key of the setting
* @param value Value of the setting
*/
void ConfSet(string key, string value);
/**
* @brief Retrieve a settings value
* @param key
* @return The value associated to the @a key
*/
string ConfGet(string key);
/**
* @brief List all the available settings
* @return List of all the available @a keys
*/
vector<string> ConfList();
public:
/**
* Should be implemented by the child class when configuration is available via @ref ConfGet
* (usually called after the configuration file is loaded by the @ref ConfigManager)
*/
virtual void Configure() {
}
};
}
#endif
......@@ -9,9 +9,8 @@ EVT_KEY_DOWN(BoardPanel::HandleKey)
END_EVENT_TABLE()
BoardPanel::BoardPanel(wxFrame *parent) :
wxPanel(parent), Configurable("BoardView") {
wxPanel(parent) {
UA = std::make_shared<UserActions>();
CNF.AddModule(this);
UA->IsDraggingPiece = false;
UA->DraggingPieceSquare = boost::none;
UA->IsDrawingArrow = false;
......
......@@ -10,7 +10,6 @@
#include <boost/format.hpp>
#include <sstream>
#include <boost/thread/mutex.hpp>
#include "config/Configurable.hpp"
#include "ochess.hpp"
using namespace ochess::model;
......@@ -26,7 +25,7 @@ typedef struct UserActions {
bool WasDragging;
} UserActions;
class BoardPanel: public wxPanel, public Configurable {
class BoardPanel: public wxPanel {
private:
BoardController C;
std::shared_ptr<UserActions> UA;
......@@ -42,7 +41,6 @@ public:
void HandleKey(wxKeyEvent &event);
void SetPiecesSkin(std::string path);
void SetBoardSkin(std::string path);
void Configure() override {};
DECLARE_EVENT_TABLE()
};
......
......@@ -3,83 +3,73 @@
namespace ochess {
namespace gui {
enum {
ID_Hello = 1
};
wxBEGIN_EVENT_TABLE(MainFrame, wxFrame) EVT_MENU(ID_Hello, MainFrame::OnHello)
EVT_MENU(wxID_EXIT, MainFrame::OnExit)
EVT_MENU(wxID_ABOUT, MainFrame::OnAbout)
EVT_MENU_RANGE(200, 299, MainFrame::ChangePieces)
EVT_MENU_RANGE(300, 399, MainFrame::ChangeSquares)
wxEND_EVENT_TABLE()
wxMenu* MainFrame::getPiecesMenu() {
wxMenu *themes = new wxMenu;
short id = 200;
for (auto &theme : CNF.ListPiecesThemes()) {
themes->Append(id, theme, "");
id++;
}
return themes;
}
wxMenu* MainFrame::getSquaresMenu() {
wxMenu *themes = new wxMenu;
short id = 300;
for (auto &theme : CNF.ListBoardThemes()) {
themes->Append(id, theme, "");
id++;
}
return themes;
MainFrame::MainFrame(const wxString &title, const wxPoint &pos,
const wxSize &size) :
wxFrame(NULL, wxID_ANY, title, pos, size) {
// File menu
wxMenu *menuFile = new wxMenu;
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
this->Bind(wxEVT_COMMAND_MENU_SELECTED,&MainFrame::MenuEventHandler,this,wxID_EXIT);
// Edit Menu
wxMenu *menuEdit = new wxMenu;
menuEdit->AppendSeparator();
menuEdit->Append(WIN_SETTINGS, "Settings", "Configure OChess", false);
this->Bind(wxEVT_COMMAND_MENU_SELECTED,&MainFrame::MenuEventHandler,this,WIN_SETTINGS);
// Help Menu
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
this->Bind(wxEVT_COMMAND_MENU_SELECTED,&MainFrame::MenuEventHandler,this,wxID_ABOUT);
// Setup the menu bar
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "File");
menuBar->Append(menuEdit, "Edition");
menuBar->Append(menuHelp, "Help");
SetMenuBar(menuBar);
// Create required windows
Create(WIN_SETTINGS);
// Setup status bar
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
// Various setup
this->Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this);
}
void MainFrame::Create(WIN name) {
switch (name) {
case BOARD: {
case WIN_BOARD: {
BoardView *b = new BoardView((wxFrame*) this);
Windows[name]=b;
break;
}
case ENGINE:
case WIN_ENGINE:
{
EngineView *e = new EngineView();
Windows[name]=e;
break;
}
case WIN_SETTINGS:{
Settings *bs=new Settings(this);
Windows[name]=bs;
break;
}
}
}
wxWindow* MainFrame::operator[](WIN name){
if(Windows.find(name)==Windows.end())
Create(name);
return(Windows[name]);
}
MainFrame::MainFrame(const wxString &title, const wxPoint &pos,
const wxSize &size) :
wxFrame(NULL, wxID_ANY, title, pos, size) {
wxMenu *menuFile = new wxMenu;
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
"Help string shown in status bar for this menu item");
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
menuBar->Append(menuHelp, "&Help");
menuBar->Append(getPiecesMenu(), "Pieces");
Create(BOARD);
wxWindow* w=(*this)[ENGINE];
EngineView* v=(EngineView*)w;
menuBar->Append(v->GetMenu(), "Engines");
this->Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this);
menuBar->Append(getSquaresMenu(), "Board");
SetMenuBar(menuBar);
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
}
void MainFrame::OnClose(wxCloseEvent &event) {
event.Skip();
......@@ -87,6 +77,26 @@ void MainFrame::OnClose(wxCloseEvent &event) {
pair.second->Destroy();
}
wxMenu* MainFrame::getPiecesMenu() {
wxMenu *themes = new wxMenu;
short id = 200;
for (auto &theme : CNF.ListPiecesThemes()) {
themes->Append(id, theme, "");
id++;
}
return themes;
}
wxMenu* MainFrame::getSquaresMenu() {
wxMenu *themes = new wxMenu;
short id = 300;
for (auto &theme : CNF.ListBoardThemes()) {
themes->Append(id, theme, "");
id++;
}
return themes;
}
void MainFrame::ChangeSquares(wxCommandEvent &event) {
wxMenu *menu = getSquaresMenu();
wxMenuItem *item = menu->FindItem(event.GetId());
......@@ -102,21 +112,21 @@ void MainFrame::ChangePieces(wxCommandEvent &event) {
//p->BP->SetPiecesSkin(item->GetItemLabel().ToStdString());
}
void MainFrame::OnExit(wxCommandEvent &event) {
(void) event;
Close(true);
void MainFrame::MenuEventHandler(wxCommandEvent &event){
switch(event.GetId()){
case wxID_EXIT:
Close(true);
break;
case wxID_ABOUT:
wxMessageBox("This is a wxWidgets' Hello world sample", "About Hello World",
wxOK | wxICON_INFORMATION);
break;
case WIN_SETTINGS:
Create(WIN_SETTINGS);
break;
}
}
void MainFrame::OnAbout(wxCommandEvent &event) {
(void) event;
wxMessageBox("This is a wxWidgets' Hello world sample", "About Hello World",
wxOK | wxICON_INFORMATION);
}
void MainFrame::OnHello(wxCommandEvent &event) {
(void) event;
wxLogMessage
("Hello world from wxWidgets!");
}
} // namespace gui
} // namespace ochess
......
......@@ -6,18 +6,24 @@
#include <wx/wx.h>
#endif
#include "gui/board/BoardView.hpp"
#include "gui/engine/EngineView.hpp"
#include "ochess.hpp"
#include <unordered_map>
// ----- Other frames -----
#include "gui/board/BoardView.hpp"
#include "gui/engine/EngineView.hpp"
#include "settings/Settings.hpp"
#define GET_VIEW(mainFrame, entry, viewType) ((viewType*)(*((MainFrame*)(mainFrame)))[(entry)])
namespace ochess {
namespace gui {
/**
* @brief Used to select a particular window
*/
typedef enum WIN {
BOARD,ENGINE
WIN_BOARD,WIN_ENGINE,WIN_SETTINGS
} WIN;
......@@ -40,13 +46,12 @@ public:
wxWindow* operator[](WIN name);
private:
/**
* Main window components
* All the windows that should be accessible from the entire application should
* be in the map.
*/
unordered_map<WIN,wxWindow*> Windows;
void OnHello(wxCommandEvent &event);
void OnExit(wxCommandEvent &event);
void OnAbout(wxCommandEvent &event);
void MenuEventHandler(wxCommandEvent &event);
void ChangePieces(wxCommandEvent &event);
void ChangeSquares(wxCommandEvent &event);
wxMenu* getPiecesMenu();
......@@ -54,7 +59,6 @@ private:
void OnClose(wxCloseEvent &event);
void Create(WIN name);
wxDECLARE_EVENT_TABLE();
};
} // namespace gui
......
/*
* BoardSettings.cpp
*
* Created on: 12 nov. 2020
* Author: loic
*/
#include "BoardSettings.hpp"
namespace ochess {
namespace gui {
BoardSettings::BoardSettings(wxWindow *parent):wxPanel(parent,wxID_ANY,wxDefaultPosition) {
new wxButton(this,wxID_ANY,"BoardSettings");
}
} /* namespace gui */
} /* namespace ochess */
/*
* BoardSettings.hpp
*
* Created on: 12 nov. 2020
* Author: loic
*/
#pragma once
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
namespace ochess {
namespace gui {
class BoardSettings: public wxPanel {
public:
BoardSettings(wxWindow* parent);
};
} /* namespace gui */
} /* namespace ochess */
/*
* MenuTree.cpp
*
* Created on: 11 nov. 2020
* Author: loic
*/
#include "MenuTree.hpp"
namespace ochess {
namespace gui {
} /* namespace gui */
} /* namespace ochess */
/*
* MenuTree.hpp
*
* Created on: 11 nov. 2020
* Author: loic
*/
#ifndef SRC_GUI_MAINFRAME_SETTINGS_MENUTREE_HPP_
#define SRC_GUI_MAINFRAME_SETTINGS_MENUTREE_HPP_
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/dataview.h>
#include <vector>
#include <algorithm>
using namespace std;
namespace ochess {
namespace gui {
class MenuTree : public wxDataViewCtrl{
public:
MenuTree(wxWindow *parent,wxSize size):wxDataViewCtrl(parent, wxID_ANY,wxDefaultPosition,size){
this->AppendTextColumn("Menu",0,wxDATAVIEW_CELL_INERT,200);
}
};
class MenuTreeNode{
public:
MenuTreeNode(string title):Title(title),Parent(nullptr),Id(-1){
}
string Title;
MenuTreeNode* Parent;
vector<MenuTreeNode*> Children;
int Id;
};
class MenuTreeModel: public wxDataViewModel {
vector<MenuTreeNode*> Entries;
public:
MenuTreeModel() {
}
MenuTreeNode* CreateEntry(string title,int id){
MenuTreeNode* entry=new MenuTreeNode(title);
entry->Id=id;
this->Entries.push_back(entry);
ItemAdded(wxDataViewItem(0), wxDataViewItem((void*)entry));
return entry;
}
void CreateSubEntry(MenuTreeNode* entry, string title,int id){
MenuTreeNode* subEntry=new MenuTreeNode(title);
subEntry->Id=id;
entry->Children.push_back(subEntry);
subEntry->Parent=entry;
ItemAdded(wxDataViewItem((void*)entry), wxDataViewItem((void*)subEntry));
}
vector<wxDataViewItem> GetItems(){
vector<wxDataViewItem> items;
for(auto entry:Entries){
items.push_back(wxDataViewItem((void*)entry));
}
return(items);
}
// ----- Override
virtual bool IsContainer(const wxDataViewItem &item) const wxOVERRIDE {
MenuTreeNode* entry=(MenuTreeNode*)item.GetID();
if(!entry)
return(false);
return (entry->Children.size()!=0);
}
virtual void GetValue(wxVariant &variant, const wxDataViewItem &item,
unsigned int col) const wxOVERRIDE {
MenuTreeNode* entry=(MenuTreeNode*)item.GetID();
variant=entry->Title;
}
virtual bool SetValue(const wxVariant &variant, const wxDataViewItem &item,
unsigned int col) wxOVERRIDE {
return true;
}
virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const
wxOVERRIDE {
return (true);
}
virtual wxDataViewItem GetParent(const wxDataViewItem &item) const
wxOVERRIDE {
if(!item.IsOk())
return(wxDataViewItem(0));
MenuTreeNode* entry=(MenuTreeNode*)item.GetID();
// If it is an entry
if(entry->Parent==nullptr)
return(wxDataViewItem(0));
return(wxDataViewItem((void*)entry->Parent));
}
virtual unsigned int GetChildren(const wxDataViewItem &parent,
wxDataViewItemArray &array) const wxOVERRIDE {
MenuTreeNode* entry=(MenuTreeNode*)parent.GetID();
if(!entry){
for(MenuTreeNode *entry:Entries){
array.push_back(wxDataViewItem((void*)entry));
}
return(Entries.size());
}
if(entry->Children.size()>0){
for(auto child:entry->Children)
array.push_back(wxDataViewItem((void*)child));
return(entry->Children.size());
}
return (0);
}
virtual wxString GetColumnType(unsigned int col) const wxOVERRIDE {
return "string";
}
virtual unsigned int GetColumnCount() const wxOVERRIDE
{
return 1;
}
};
} /* namespace gui */
} /* namespace ochess */
#endif /* SRC_GUI_MAINFRAME_SETTINGS_MENUTREE_HPP_ */