Commit 0373514d authored by coppro's avatar coppro

Added primitive update window.

Added diagonal directions (todo: add different text direcitons, primarily for Space)
Cleaned up keyword game file a bit.
parent 8078407e
......@@ -158,5 +158,6 @@ magicseteditor_SOURCES += ./src/util/alignment.cpp
magicseteditor_SOURCES += ./src/util/tagged_string.cpp
magicseteditor_SOURCES += ./src/util/error.cpp
magicseteditor_SOURCES += ./src/util/age.cpp
magicseteditor_SOURCES += ./src/util/spec_sort.cpp
magicseteditor_SOURCES += ./src/main.cpp
magicseteditor_SOURCES += ./src/code_template.cpp
......@@ -14,6 +14,7 @@ menu:
export images: All Card I&mages...
export apprentice: &Apprentice...
export mws: Magic &Workstation...
check updates: Check &Updates...
print preview: Print Pre&view...
print: &Print... Ctrl+P
reload data: Reload Data Ctrl+F5
......@@ -35,7 +36,7 @@ menu:
next card: Select &Next Card PgDn
add card: &Add Card Ctrl++
add cards: Add &Multiple Cards...
remove card: &Remove Select Card Del
remove card: &Delete Selected Card
orientation: &Orientation
rotate 0: &Normal
rotate 270: Rotated 90° &Clockwise
......@@ -105,6 +106,7 @@ help:
export images: Export images for all cards
export apprentice: Export the set so it can be played with in Apprentice
export mws: Export the set so it can be played with in Magic Workstation
check updates: Open the update window to download new packages, such as games, styles, and locales.
print preview: Shows cards as they will be printed
print: Print cards from this set
reload data: Reload all template files (game and style) as well as the set.
......@@ -516,6 +518,12 @@ title:
export cancled: Export Cancled
export html: Export to HTML
save html: Export to HTML
# Package Update Window
package list: Package Updates
package name: Package Name
package status: Current Status
new status: New Status
############################################################## Action (undo/redo) names
action:
......@@ -617,6 +625,11 @@ error:
# Stats panel
dimension not found: There is no statistics dimension '%s'
# Package update window
no packages: Found no package updates.
checking updates: Checking for updates.
############################################################## Types used in scripts / shape names
type:
......@@ -663,6 +676,17 @@ type:
points: points
handle: handle
# Package manager
installed: installed
uninstalled: uninstalled
upgradeable: upgradeable
install: install
uninstall: uninstalled
upgrade: upgrade
do nothing: do nothing
new mse: MSE outdated
############################################################## Magic
game:
......
......@@ -27,7 +27,6 @@ init script:
+ " pattern(/. WUBRG)"
+ " cycle(WUBRG)"
+ ")")
mana_has_guild := sort_rule(order: "</|>") # Is there guild or half mana in the input?
mana_filter := to_upper + mana_sort
# Like mana filter, only also allow tap symbols:
tap_filter := sort_rule(order: "<T>")
......@@ -171,7 +170,7 @@ init script:
sort_index := {
card_color := card.card_color
casting_cost := card.casting_cost
if card.casting_cost_2 != "" and
if card.shape = "split" and
card_color != card.card_color_2 then "H" # multicolor splits
else if chosen(choice: "land", card_color) then (
# land
......@@ -1490,7 +1489,7 @@ keyword:
keyword: Regeneration
match: Regenerate
mode: action
reminder: The next time {if has_pt() then "this creature" else "this"} would be destroyed this turn, it isn't.{if has_pt() then " Instead tap it, remove all damage from it, and remove it from combat." else ""}
reminder: The next time {if has_pt() then "this creature" else "this"} would be destroyed this turn, it isn't.{if has_pt() then " Instead tap it, remove all damage from it, and remove it from combat." else " Instead tap it"}
keyword:
keyword: Bands with other
match: Bands with other <atom-param>name</atom-param>
......@@ -1510,7 +1509,7 @@ keyword:
keyword: Phasing
match: Phasing
mode: old
reminder: At the beginning of your upkeep, put this and any cards and/or counters attached to it in the phased-out zone. If this is already in the phased-out zone, return it and any cards and/or counters attached to it to play. This ability does not cause comes-into-play or leaves-play abilities to trigger.
reminder: At the beginning of your untap step, put this and any cards and/or counters attached to it in the phased-out zone. If this is already in the phased-out zone, return it and any cards and/or counters attached to it to play. This ability does not cause comes-into-play or leaves-play abilities to trigger.
keyword:
keyword: Flanking
match: Flanking
......
......@@ -64,7 +64,7 @@ CardsPanel::CardsPanel(Window* parent, int id)
menuCard->Append(ID_CARD_ADD_MULT, _("card_add_multiple"), _MENU_("add cards"), _HELP_("add cards"));
// NOTE: space after "Del" prevents wx from making del an accellerator
// otherwise we delete a card when delete is pressed inside the editor
menuCard->Append(ID_CARD_REMOVE, _("card_del"), _MENU_("remove card")+_(" "),_HELP_("remove card"));
menuCard->Append(ID_CARD_REMOVE, _("card_del"), _MENU_("remove card"),_HELP_("remove card"));
menuCard->AppendSeparator();
IconMenu* menuRotate = new IconMenu();
menuRotate->Append(ID_CARD_ROTATE_0, _("card_rotate_0"), _MENU_("rotate 0"), _HELP_("rotate 0"), wxITEM_CHECK);
......
......@@ -65,6 +65,7 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
menuExport->Append(ID_FILE_EXPORT_MWS, _("export_mws"), _MENU_("export mws"), _HELP_("export mws"));
menuFile->Append(wxID_ANY, _("export"), _MENU_("export"), _HELP_("export"), wxITEM_NORMAL, menuExport);
menuFile->AppendSeparator();
menuFile->Append(ID_FILE_CHECK_UPDATES, _MENU_("check updates"), _HELP_("check updates"));
// menuFile->Append(ID_FILE_INSPECT, _("Inspect Internal Data..."), _("Shows a the data in the set using a tree structure"));
// menuFile->AppendSeparator();
menuFile->Append(ID_FILE_RELOAD, _MENU_("reload data"), _HELP_("reload data"));
......@@ -466,7 +467,7 @@ void SetWindow::onFileInspect(wxCommandEvent&) {
wnd.show();
}*/
#if defined(__WXMSW__)
#if defined(__WXMSW__)
#include "wx/msw/wrapcctl.h"
#endif
......@@ -527,6 +528,10 @@ void SetWindow::onFileExportMWS(wxCommandEvent&) {
export_mws(this, set);
}
void SetWindow::onFileCheckUpdates(wxCommandEvent&) {
(new UpdateWindow)->Show();
}
void SetWindow::onFilePrint(wxCommandEvent&) {
print_set(this, set);
}
......@@ -677,6 +682,7 @@ BEGIN_EVENT_TABLE(SetWindow, wxFrame)
EVT_MENU (ID_FILE_EXPORT_HTML, SetWindow::onFileExportHTML)
EVT_MENU (ID_FILE_EXPORT_APPR, SetWindow::onFileExportApprentice)
EVT_MENU (ID_FILE_EXPORT_MWS, SetWindow::onFileExportMWS)
EVT_MENU (ID_FILE_CHECK_UPDATES, SetWindow::onFileCheckUpdates)
// EVT_MENU (ID_FILE_INSPECT, SetWindow::onFileInspect)
EVT_MENU (ID_FILE_PRINT, SetWindow::onFilePrint)
EVT_MENU (ID_FILE_PRINT_PREVIEW, SetWindow::onFilePrintPreview)
......
......@@ -114,6 +114,7 @@ class SetWindow : public wxFrame, public SetView {
void onFileExportHTML (wxCommandEvent&);
void onFileExportApprentice(wxCommandEvent&);
void onFileExportMWS (wxCommandEvent&);
void onFileCheckUpdates (wxCommandEvent&);
void onFilePrint (wxCommandEvent&);
void onFilePrintPreview (wxCommandEvent&);
void onFileReload (wxCommandEvent&);
......
......@@ -15,10 +15,13 @@
#include <wx/dialup.h>
#include <wx/url.h>
#include <wx/html/htmlwin.h>
#include <wx/vlbox.h>
DECLARE_POINTER_TYPE(PackageVersionData);
DECLARE_POINTER_TYPE(VersionData);
DECLARE_TYPEOF_COLLECTION(PackageVersionDataP);
// ----------------------------------------------------------------------------- : Update data
/// Information on available packages
......@@ -55,7 +58,7 @@ IMPLEMENT_REFLECTION(PackageVersionData) {
REFLECT(is_installer);
REFLECT(version);
REFLECT(app_version);
REFLECT(depends);
REFLECT_N("depends ons", depends);
}
IMPLEMENT_REFLECTION(VersionData) {
......@@ -67,6 +70,8 @@ IMPLEMENT_REFLECTION(VersionData) {
// The information for the latest version
VersionDataP update_version_data;
// Have we shown the update dialog?
bool shown_dialog = false;
// Is update checking in progress?
volatile bool checking_updates = false;
......@@ -75,6 +80,12 @@ bool update_available() { return update_version_data && update_version_data->ve
// ----------------------------------------------------------------------------- : Update checking
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(UPDATE_CHECK_FINISHED_EVT, -1)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(UPDATE_CHECK_FINISHED_EVT)
// Thread to retrieve update information
// Checks if the current version is the latest version
// If not, displays a message
......@@ -142,14 +153,14 @@ struct HtmlWindowToBrowser : public wxHtmlWindow {
HtmlWindowToBrowser(Window* parent, int id, const wxPoint& pos, const wxSize& size, long flags)
: wxHtmlWindow(parent, id, pos, size, flags)
{}
virtual void OnLinkClicked(const wxHtmlLinkInfo& info) {
wxLaunchDefaultBrowser( info.GetHref() );
}
};
void show_update_dialog(Window* parent) {
if (!update_available()) return; // we already have the latest version
if (!update_available() || shown_dialog) return; // we already have the latest version, or this has already been displayed.
// Show update dialog
wxDialog* dlg = new wxDialog(parent, wxID_ANY, _TITLE_("updates availible"), wxDefaultPosition);
// controls
......@@ -165,5 +176,177 @@ void show_update_dialog(Window* parent) {
dlg->SetSize(400,400);
dlg->Show();
// And never show it again this run
update_version_data = VersionDataP();
shown_dialog = true;
}
// ----------------------------------------------------------------------------- : UpdateWindow
class PackageUpdateList: public wxVListBox {
public:
PackageUpdateList(UpdateWindow * parent)
: wxVListBox (parent, wxID_ANY, wxDefaultPosition, wxSize(480,210), wxNO_BORDER | wxVSCROLL)
, parent(parent)
{
if (!checking_updates && !update_version_data) {
check_updates_now(true);
}
SetItemCount(update_version_data ? update_version_data->packages.size() : 1);
}
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const {
static wxBrush greyBrush(Color(224,224,224));
if (checking_updates) {
String text = _ERROR_("checking updates");
wxSize text_size = dc.GetTextExtent(text);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(greyBrush);
dc.DrawRectangle(rect);
dc.DrawText(text, rect.GetLeft() + (rect.GetWidth() - text_size.GetWidth()) / 2, rect.GetTop() + (rect.GetHeight() - text_size.GetHeight()) / 2);
} else if (!update_version_data || update_version_data->packages.empty()) {
String text = _ERROR_("no packages");
wxSize text_size = dc.GetTextExtent(text);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(greyBrush);
dc.DrawRectangle(rect);
dc.DrawText(text, rect.GetLeft() + (rect.GetWidth() - text_size.GetWidth()) / 2, rect.GetTop() + (rect.GetHeight() - text_size.GetHeight()) / 2);
} else {
static wxBrush darkBrush(Color(192,224,255));
static wxBrush selectBrush(Color(96,96,192));
PackageVersionDataP pack = update_version_data->packages[n];
UpdateWindow::PackageStatus status = parent->package_data[pack].first;
UpdateWindow::PackageAction action = parent->package_data[pack].second;
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(IsSelected(n) ? selectBrush : (n % 2 ? *wxWHITE_BRUSH : darkBrush));
dc.DrawRectangle(rect);
// These two arrays correspond to PackageStatus and PackageAction, respectively
static Color status_colors [] = {
Color(32,160,32)
,Color(32,32,255)
,Color(192,32,32)
};
static Color action_colors [] = {
Color(32,160,32)
,Color(192,32,32)
,Color(192,192,32)
,Color(32,32,255)
,Color(32,32,32)
};
// Ditto here (these are the locale names)
static String status_texts [] = {
_TYPE_("installed")
,_TYPE_("uninstalled")
,_TYPE_("upgradeable")
};
static String action_texts [] = {
_TYPE_("install")
,_TYPE_("uninstall")
,_TYPE_("upgrade")
,_TYPE_("do nothing")
,_TYPE_("new mse")
};
static Color textBack(0,0,0,wxALPHA_TRANSPARENT);
static Color packageFront(64,64,64);
#define SELECT_WHITE(color) (IsSelected(n) ? *wxWHITE : color)
dc.SetTextForeground(SELECT_WHITE(packageFront));
dc.SetTextBackground(textBack);
dc.DrawText(pack->name, rect.GetLeft() + 1, rect.GetTop());
dc.SetTextForeground(SELECT_WHITE(status_colors[status]));
dc.DrawText(status_texts[status], rect.GetLeft() + 240, rect.GetTop());
dc.SetTextForeground(SELECT_WHITE(action_colors[action]));
dc.DrawText(action_texts[action], rect.GetLeft() + 360, rect.GetTop());
#undef SELECT_INVERT
}
}
virtual wxCoord OnMeasureItem(size_t) const {
return (update_version_data && !update_version_data->packages.empty()) ? 15 : 210;
}
void onUpdateCheckingFinished(wxEvent& event) {
SetItemCount(update_version_data ? update_version_data->packages.size() : 1);
}
virtual wxCoord EstimateTotalHeight() const {
return (update_version_data && !update_version_data->packages.empty()) ? 15 * update_version_data->packages.size() : 210;
}
private:
DECLARE_EVENT_TABLE()
UpdateWindow * parent;
};
BEGIN_EVENT_TABLE(PackageUpdateList, wxVListBox)
EVT_CUSTOM(UPDATE_CHECK_FINISHED_EVT, -1, PackageUpdateList::onUpdateCheckingFinished)
END_EVENT_TABLE()
UpdateWindow::UpdateWindow()
: Frame(nullptr, wxID_ANY, _TITLE_("package list"), wxDefaultPosition, wxSize(480,375), wxDEFAULT_DIALOG_STYLE | wxCLIP_CHILDREN)
{
SetIcon(wxIcon());
wxBoxSizer *v = new wxBoxSizer(wxVERTICAL);
package_list = new PackageUpdateList(this);
description_window = new HtmlWindowToBrowser(this, wxID_ANY, wxDefaultPosition, wxSize(480,100), wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER);
wxCommandEvent ev;
SetDefaultPackageStatus(ev);
package_title = new wxStaticText(this, wxID_ANY, _TITLE_("package name"), wxDefaultPosition, wxSize(120,15), wxALIGN_LEFT | wxST_NO_AUTORESIZE);
status_title = new wxStaticText(this, wxID_ANY, _TITLE_("package status"), wxDefaultPosition, wxSize(120,15), wxALIGN_LEFT | wxST_NO_AUTORESIZE);
new_title = new wxStaticText(this, wxID_ANY, _TITLE_("new status"), wxDefaultPosition, wxSize(120,15), wxALIGN_LEFT | wxST_NO_AUTORESIZE);
package_title->Move(1,0);
status_title->Move(240,0);
new_title->Move(360,0);
v->AddSpacer(15);
v->Add(package_list);
v->Add(description_window);
SetSizer(v);
}
void UpdateWindow::SetDefaultPackageStatus(wxCommandEvent&)
{
if (!update_version_data)
return;
FOR_EACH(p, update_version_data->packages) {
PackagedP pack;
try { pack = packages.openAny(p->name); }
catch (Error& e) { } // We couldn't open a package... wonder why?
if (!pack) {
if (p->app_version > file_version)
package_data[p] = PackageData(STATUS_NOT_INSTALLED, ACTION_NEW_MSE);
else
package_data[p] = PackageData(STATUS_NOT_INSTALLED, ACTION_NOTHING);
} else if (pack->version < p->version) {
if (p->app_version > file_version)
package_data[p] = PackageData(STATUS_UPGRADEABLE, ACTION_NEW_MSE);
else
package_data[p] = PackageData(STATUS_UPGRADEABLE, ACTION_UPGRADE);
} else
package_data[p] = PackageData(STATUS_INSTALLED, ACTION_NOTHING);
}
}
BEGIN_EVENT_TABLE(UpdateWindow, Frame)
EVT_COMMAND(-1, UPDATE_CHECK_FINISHED_EVT, UpdateWindow::SetDefaultPackageStatus)
END_EVENT_TABLE()
......@@ -10,6 +10,7 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <wx/html/htmlwin.h>
// ----------------------------------------------------------------------------- : Update checking
......@@ -26,6 +27,42 @@ void check_updates_now(bool async = true);
* Call this function from an onIdle loop */
void show_update_dialog(Window* parent);
class PackageUpdateList;
DECLARE_POINTER_TYPE(PackageVersionData);
/// A window that displays the updates and allows the user to select some.
class UpdateWindow : public Frame {
public:
UpdateWindow();
void DrawTitles(wxPaintEvent&);
enum PackageStatus {
STATUS_INSTALLED,
STATUS_NOT_INSTALLED,
STATUS_UPGRADEABLE
};
enum PackageAction {
ACTION_INSTALL,
ACTION_UNINSTALL,
ACTION_UPGRADE,
ACTION_NOTHING,
ACTION_NEW_MSE
};
typedef pair<PackageStatus, PackageAction> PackageData;
map<PackageVersionDataP, PackageData> package_data;
void SetDefaultPackageStatus(wxCommandEvent&);
private:
DECLARE_EVENT_TABLE();
PackageUpdateList* package_list;
wxHtmlWindow* description_window;
wxStaticText *package_title, *status_title, *new_title;
};
/// Was update data found?
bool update_data_found();
/// Is there an update?
......
......@@ -92,6 +92,10 @@ IMPLEMENT_REFLECTION_ENUM(Direction) {
VALUE_N("bottom to top", BOTTOM_TO_TOP);
VALUE_N("horizontal", LEFT_TO_RIGHT);
VALUE_N("vertical", TOP_TO_BOTTOM);
VALUE_N("top-right to bottom-left", TOP_RIGHT_TO_BOTTOM_LEFT);
VALUE_N("bottom-left to top-right", BOTTOM_LEFT_TO_TOP_RIGHT);
VALUE_N("top-left to bottom-right", TOP_LEFT_TO_BOTTOM_RIGHT);
VALUE_N("bottom-right to top-left", BOTTOM_RIGHT_TO_TOP_LEFT);
}
RealPoint move_in_direction(Direction dir, const RealPoint& point, const RealSize to_move, double spacing) {
......@@ -100,6 +104,10 @@ RealPoint move_in_direction(Direction dir, const RealPoint& point, const RealSiz
case RIGHT_TO_LEFT: return RealPoint(point.x - to_move.width - spacing, point.y);
case TOP_TO_BOTTOM: return RealPoint(point.x, point.y + to_move.height + spacing);
case BOTTOM_TO_TOP: return RealPoint(point.x, point.y - to_move.height - spacing);
case TOP_RIGHT_TO_BOTTOM_LEFT: return RealPoint(point.x - to_move.width - spacing, point.y + to_move.height + spacing);
case BOTTOM_LEFT_TO_TOP_RIGHT: return RealPoint(point.x + to_move.width + spacing, point.y - to_move.height - spacing);
case TOP_LEFT_TO_BOTTOM_RIGHT: return RealPoint(point.x + to_move.width + spacing, point.y + to_move.height + spacing);
case BOTTOM_RIGHT_TO_TOP_LEFT: return RealPoint(point.x - to_move.width - spacing, point.y - to_move.height - spacing);
default: return point; // should not happen
}
}
......@@ -59,6 +59,10 @@ RealPoint align_in_rect(Alignment align, const RealSize& to_align, const RealRec
enum Direction {
LEFT_TO_RIGHT, RIGHT_TO_LEFT,
TOP_TO_BOTTOM, BOTTOM_TO_TOP,
BOTTOM_RIGHT_TO_TOP_LEFT,
TOP_LEFT_TO_BOTTOM_RIGHT,
BOTTOM_LEFT_TO_TOP_RIGHT,
TOP_RIGHT_TO_BOTTOM_LEFT,
HORIZONTAL = LEFT_TO_RIGHT,
VERTICAL = TOP_TO_BOTTOM
};
......
......@@ -41,6 +41,7 @@ enum MenuID {
, ID_FILE_RELOAD = 9
, ID_FILE_RECENT = wxID_FILE1
, ID_FILE_RECENT_MAX = wxID_FILE9
, ID_FILE_CHECK_UPDATES = 10
// Edit menu
, ID_EDIT_UNDO = wxID_UNDO
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment