Extended ResourceEdit.

Signed-off-by: Matt Madia <[email protected]>
This commit is contained in:
Tri-Edge AI
2013-02-27 22:09:21 -05:00
committed by Matt Madia
parent 49126a0e9b
commit dc4fe6be00
33 changed files with 2121 additions and 232 deletions
+16 -5
View File
@@ -25,13 +25,24 @@
#define MSG_CLEAR 'm015'
#define MSG_SELECTALL 'm016'
#define MSG_ADD 'm020'
#define MSG_REMOVE 'm021'
#define MSG_MOVEUP 'm022'
#define MSG_MOVEDOWN 'm023'
#define MSG_ADDAPPRES 'm020'
#define MSG_SETTINGS 'm021'
#define MSG_SELECTION 'm030'
#define MSG_ADD 'm030'
#define MSG_REMOVE 'm031'
#define MSG_MOVEUP 'm032'
#define MSG_MOVEDOWN 'm033'
#define MSG_SELECTION 'm040'
#define MSG_INVOCATION 'm041'
#define MSG_ACCEPT 'm050'
#define MSG_CANCEL 'm051'
#define MSG_IGNORE 'm052'
#define MSG_SETTINGS_APPLY 'm022'
#define MSG_SETTINGS_REVERT 'm023'
#define MSG_SETTINGS_CLOSED 'm024'
// TODO: Remove prior to release.
#define DEBUG 1
+17 -71
View File
@@ -9,84 +9,22 @@
#include <ByteOrder.h>
BString
toStringBOOL(const void* data)
int32
ResourceType::FindIndex(type_code code)
{
if (*(bool*)data)
return "✔ true";
else
return "✖ false";
}
for (int32 i = 0; kDefaultTypes[i].type != NULL; i++)
if (StringToCode(kDefaultTypes[i].code) == code)
return i;
BString
toStringBYTE(const void* data)
{
return (BString() << *(int8*)data);
}
BString
toStringSHRT(const void* data)
{
return (BString() << *(int16*)data);
}
BString
toStringLONG(const void* data)
{
return (BString() << *(int32*)data);
}
BString
toStringLLNG(const void* data)
{
return (BString() << *(int64*)data);
}
BString
toStringUBYT(const void* data)
{
return (BString() << *(uint8*)data);
}
BString
toStringUSHT(const void* data)
{
return (BString() << *(uint16*)data);
}
BString
toStringULNG(const void* data)
{
return (BString() << *(uint32*)data);
}
BString
toStringULLG(const void* data)
{
return (BString() << *(uint64*)data);
}
BString
toStringRAWT(const void* data)
{
return "[Raw Data]";
return -1;
}
int32
FindTypeCodeIndex(type_code code)
ResourceType::FindIndex(const char* type)
{
for (int32 i = 0; kDefaultTypes[i].type != NULL; i++)
if (kDefaultTypes[i].typeCode == code)
if (strcmp(kDefaultTypes[i].type, type) == 0)
return i;
return -1;
@@ -94,8 +32,16 @@ FindTypeCodeIndex(type_code code)
void
TypeCodeToString(type_code code, char* str)
ResourceType::CodeToString(type_code code, char* str)
{
*(type_code*)str = B_HOST_TO_BENDIAN_INT32(code);
str[4] = '\0';
}
type_code
ResourceType::StringToCode(const char* code)
{
// TODO: Code may be in other formats, too! Ex.: 0x4C4F4E47
return B_BENDIAN_TO_HOST_INT32(*(int32*)code);
}
+41 -38
View File
@@ -6,61 +6,64 @@
#define DEFAULT_TYPES_H
#include "AppFlagsEdit.h"
#include "BooleanEdit.h"
#include "EditView.h"
#include "NormalEdit.h"
#include "ResourceRow.h"
#include <String.h>
struct ResourceDataType {
const char* type;
type_code typeCode;
uint32 size;
BString (*toString)(const void*);
struct ResourceType {
const char* type;
const char* code;
const char* data;
uint32 size;
EditView* edit;
static int32 FindIndex(const char* type);
static int32 FindIndex(type_code code);
static void CodeToString(type_code code, char* str);
static type_code StringToCode(const char* code);
};
// TODO: Rework design of this. This one sucks.
BString toStringBOOL(const void* data);
BString toStringBYTE(const void* data);
BString toStringSHRT(const void* data);
BString toStringLONG(const void* data);
BString toStringLLNG(const void* data);
BString toStringUBYT(const void* data);
BString toStringUSHT(const void* data);
BString toStringULNG(const void* data);
BString toStringULLG(const void* data);
BString toStringRAWT(const void* data);
#define LINE "", "", "", ~0, NULL
#define END NULL, NULL, NULL, 0, NULL
char * const kDefaultData[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
#define LINE "", 0, ~0
#define END NULL, 0, 0
const ResourceDataType kDefaultTypes[] = {
{ "bool", 'BOOL', 1, toStringBOOL },
const ResourceType kDefaultTypes[] = {
{ "app_signature", "", "application/MyApp", 18, new NormalEdit() },
{ "app_name_catalog_entry", "", "MyApp:System name:MyApp", 24, new NormalEdit() },
//{ "app_flags", "", "None", 4, NULL },
{ LINE },
{ "int8", 'BYTE', 1, toStringBYTE },
{ "int16", 'SHRT', 2, toStringSHRT },
{ "int32", 'LONG', 4, toStringLONG },
{ "int64", 'LLNG', 8, toStringLLNG },
{ "bool", "BOOL", "false", 1, new BooleanEdit() },
{ LINE },
{ "uint8", 'UBYT', 1, toStringUBYT },
{ "uint16", 'USHT', 2, toStringUSHT },
{ "uint32", 'ULNG', 4, toStringULNG },
{ "uint64", 'ULLG', 8, toStringULLG },
{ "int8", "BYTE", "0", 1, new NormalEdit() },
{ "int16", "SHRT", "0", 2, new NormalEdit() },
{ "int32", "LONG", "0", 4, new NormalEdit() },
{ "int64", "LLNG", "0", 8, new NormalEdit() },
{ LINE },
{ "raw", 'RAWT', 0, toStringRAWT },
{ "uint8", "UBYT", "0", 1, new NormalEdit() },
{ "uint16", "USHT", "0", 2, new NormalEdit() },
{ "uint32", "ULNG", "0", 4, new NormalEdit() },
{ "uint64", "ULLG", "0", 8, new NormalEdit() },
{ LINE },
{ "string", "CSTR", "\"\"", 0, NULL },
{ "raw", "RAWT", "", 0, NULL },
{ LINE },
{ "array", "", "", 0, NULL },
{ "message", "", "", 0, NULL },
{ "import", "", "", 0, NULL },
{ END }
};
const int32 kDefaultTypeSelected = 4;
const int32 kDefaultTypeSelected = 8;
// int32
#undef LINE
#undef END
int32 FindTypeCodeIndex(type_code code);
void TypeCodeToString(type_code code, char* str);
#endif
+163
View File
@@ -0,0 +1,163 @@
/*
* Copyright 2012-2013 Tri-Edge AI <[email protected]>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "EditWindow.h"
#include "Constants.h"
#include "DefaultTypes.h"
#include "EditView.h"
#include "ResourceRow.h"
#include <Box.h>
#include <Button.h>
#include <GroupLayoutBuilder.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <StringView.h>
#include <TextControl.h>
#include <View.h>
EditWindow::EditWindow(BRect frame, ResourceRow* row)
:
BWindow(frame, "Edit Resource",
B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 0)
{
int32 ix = ResourceType::FindIndex(row->ResourceType());
fRow = row;
fView = new BView(Bounds(), "fView", B_FOLLOW_ALL, 0);
fView->SetLayout(new BGroupLayout(B_VERTICAL));
fIDText = new BTextControl(BRect(0, 0, 0, 0),
"fIDText", "ID:", row->ResourceStringID(), NULL);
fIDText->SetDivider(50);
fNameText = new BTextControl(BRect(0, 0, 0, 0),
"fNameText", "Name:", row->ResourceName(), NULL);
fNameText->SetDivider(50);
fTypePopUp = new BPopUpMenu("(Type)");
// TODO: (Not so) evil redundancy.
for (int32 i = 0; kDefaultTypes[i].type != NULL; i++) {
if (kDefaultTypes[i].size == ~(uint32)0)
fTypePopUp->AddSeparatorItem();
else
fTypePopUp->AddItem(new BMenuItem(kDefaultTypes[i].type,
new BMessage(MSG_SELECTION)));
}
// ---
fTypePopUp->ItemAt(ix)->SetMarked(true);
fTypeMenu = new BMenuField(BRect(0, 0, 0, 0),
"fTypeMenu", "Type:", fTypePopUp);
fTypeMenu->SetDivider(50);
fCodeText = new BTextControl(BRect(0, 0, 0, 0),
"fCodeText", "Code:", row->ResourceStringCode(), NULL);
fCodeText->SetDivider(50);
fEditViewBox = new BBox(BRect(0, 0, 0, 0), "fEditViewBox");
fEditViewBox->SetLayout(new BGroupLayout(B_VERTICAL));
fEditView = kDefaultTypes[ix].edit;
fEditView->AttachTo(fEditViewBox);
fEditView->Edit(fRow);
fErrorString = new BStringView(BRect(0, 0, 0, 0),
"fErrorString", "");
fErrorString->SetHighColor(ui_color(B_FAILURE_COLOR));
fCancelButton = new BButton(BRect(0, 0, 0, 0),
"fCancelButton", "Cancel", new BMessage(MSG_CANCEL));
fOKButton = new BButton(BRect(0, 0, 0, 0),
"fOKButton", "OK", new BMessage(MSG_ACCEPT));
fView->AddChild(BGroupLayoutBuilder(B_VERTICAL, 8)
.Add(fIDText)
.Add(fNameText)
.Add(fTypeMenu)
.Add(fCodeText)
.Add(fEditViewBox)
.Add(fErrorString)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 8)
.AddGlue()
.Add(fCancelButton)
.Add(fOKButton)
.SetInsets(8, 8, 8, 8)
)
.SetInsets(8, 8, 8, 8)
);
AddChild(fView);
ResizeTo(250, 350);
Show();
}
EditWindow::~EditWindow()
{
fEditView->RemoveSelf();
}
void
EditWindow::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case MSG_SELECTION:
{
int32 ix = fTypePopUp->FindMarkedIndex();
fCodeText->SetText(kDefaultTypes[ix].code);
fEditView->RemoveSelf();
fEditView = kDefaultTypes[ix].edit;
fEditView->AttachTo(fEditViewBox);
fEditView->Edit(fRow);
break;
}
case MSG_CANCEL:
PostMessage(B_QUIT_REQUESTED);
break;
case MSG_ACCEPT:
{
if (_Validate()) {
int32 ix = fTypePopUp->FindMarkedIndex();
fRow->SetResourceStringID(fIDText->Text());
fRow->SetResourceName(fNameText->Text());
fRow->SetResourceType(kDefaultTypes[ix].type);
fRow->SetResourceStringCode(fCodeText->Text());
fRow->SetResourceSize(kDefaultTypes[ix].size);
fEditView->Commit();
PostMessage(B_QUIT_REQUESTED);
}
break;
}
}
}
bool
EditWindow::_Validate()
{
// TODO: Implement validation of entered data.
fErrorString->SetText("");
return true;
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright 2012-2013 Tri-Edge AI <[email protected]>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef EDIT_WINDOW_H
#define EDIT_WINDOW_H
#include <Window.h>
class EditView;
class ResourceRow;
class BBox;
class BButton;
class BMenuField;
class BPopUpMenu;
class BStringView;
class BTextControl;
class EditWindow : public BWindow {
public:
EditWindow(BRect frame, ResourceRow* row);
~EditWindow();
void MessageReceived(BMessage* msg);
private:
ResourceRow* fRow;
BView* fView;
BTextControl* fIDText;
BTextControl* fNameText;
BPopUpMenu* fTypePopUp;
BMenuField* fTypeMenu;
BTextControl* fCodeText;
EditView* fEditView;
BBox* fEditViewBox;
BStringView* fErrorString;
BButton* fCancelButton;
BButton* fOKButton;
bool _Validate();
};
#endif
+33 -2
View File
@@ -2,14 +2,46 @@ SubDir HAIKU_TOP src apps resourceedit ;
UsePrivateHeaders interface shared ;
local sourceDirs =
edits
interface
settings
support
;
local sourceDir ;
for sourceDir in $(sourceDirs) {
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps resourceedit $(sourceDir) ] ;
}
Application ResourceEdit
:
DefaultTypes.cpp
# edits
AppFlagsEdit.cpp
BooleanEdit.cpp
EditView.cpp
NormalEdit.cpp
# interface
ImageButton.cpp
# settings
GenericSettingsView.cpp
# support
UndoContext.cpp
# .
DefaultTypes.cpp
EditWindow.cpp
MainWindow.cpp
ResourceEdit.cpp
ResourceListView.cpp
ResourceRow.cpp
SettingsFile.cpp
SettingsWindow.cpp
main.cpp
:
be
@@ -17,7 +49,6 @@ Application ResourceEdit
translation
libcolumnlistview.a
$(TARGET_LIBSTDC++)
:
ResourceEdit.rdef
;
File diff suppressed because it is too large Load Diff
+106 -5
View File
@@ -6,12 +6,17 @@
#define MAIN_WINDOW_H
#include "UndoContext.h"
#include <Window.h>
class ImageButton;
class ResourceListView;
class ResourceRow;
class SettingsFile;
class BColumnListView;
class BBox;
class BEntry;
class BFilePanel;
class BMenu;
@@ -20,20 +25,30 @@ class BMenuField;
class BMenuItem;
class BMessage;
class BPopUpMenu;
class BStringView;
class BTextControl;
class MainWindow : public BWindow {
public:
MainWindow(BRect frame, BEntry* entry);
MainWindow(BRect frame, BEntry* entry, SettingsFile* settings);
~MainWindow();
bool QuitRequested();
void MouseDown(BPoint point);
void MessageReceived(BMessage* msg);
void SelectionChanged();
void AdaptSettings();
private:
BEntry* fAssocEntry;
SettingsFile* fSettings;
BFilePanel* fSavePanel;
bool fUnsavedChanges;
UndoContext* fUndoContext;
BMenuBar* fMenuBar;
@@ -56,6 +71,10 @@ private:
BMenuItem* fClearItem;
BMenuItem* fSelectAllItem;
BMenu* fToolsMenu;
BMenuItem* fAddAppResourcesItem;
BMenuItem* fSettingsItem;
BMenu* fHelpMenu;
BTextControl* fResourceIDText;
@@ -68,9 +87,9 @@ private:
ImageButton* fMoveUpButton;
ImageButton* fMoveDownButton;
BColumnListView* fResourceList;
BFilePanel* fSavePanel;
ResourceListView* fResourceList;
BBox* fStatsBox;
BStringView* fStatsString;
void _SetTitleFromEntry();
void _SaveAs();
@@ -79,6 +98,88 @@ private:
int32 _NextResourceID();
void _RefreshStats();
void _RefreshUndoRedo();
void _Do(UndoContext::Action* action);
class AddAction : public UndoContext::Action {
public:
AddAction(const BString& label,
ResourceListView* list, BList* rows);
~AddAction();
void Do();
void Undo();
private:
ResourceListView* fList;
BList* fRows;
bool fAdded;
};
class RemoveAction : public UndoContext::Action {
public:
RemoveAction(const BString& label,
ResourceListView* list, BList* rows);
~RemoveAction();
void Do();
void Undo();
private:
ResourceListView* fList;
BList* fRows;
bool fRemoved;
};
class EditAction : public UndoContext::Action {
public:
EditAction(const BString& label,
ResourceListView* list,
ResourceRow* rowold, ResourceRow* rownew);
~EditAction();
void Do();
void Undo();
private:
ResourceListView* fList;
ResourceRow* fRowOld;
ResourceRow* fRowNew;
};
class MoveUpAction : public UndoContext::Action {
public:
MoveUpAction(const BString& label,
ResourceListView* list, BList* rows);
~MoveUpAction();
void Do();
void Undo();
private:
ResourceListView* fList;
BList* fRows;
};
class MoveDownAction : public UndoContext::Action {
public:
MoveDownAction(const BString& label,
ResourceListView* list, BList* rows);
~MoveDownAction();
void Do();
void Undo();
private:
ResourceListView* fList;
BList* fRows;
};
};
+34 -3
View File
@@ -9,6 +9,8 @@
#include "AboutWindow.h"
#include "Constants.h"
#include "MainWindow.h"
#include "SettingsFile.h"
#include "SettingsWindow.h"
#include <Entry.h>
#include <FilePanel.h>
@@ -23,6 +25,11 @@ ResourceEdit::ResourceEdit()
fOpenPanel = new BFilePanel(B_OPEN_PANEL, &be_app_messenger, NULL, 0, true,
new BMessage(MSG_OPEN_DONE));
fSettings = new SettingsFile("resourceedit_settings");
fSettings->Load();
fSettingsWindow = NULL;
}
@@ -68,11 +75,35 @@ ResourceEdit::MessageReceived(BMessage* msg)
}
case MSG_SAVEALL:
{
for (int32 i = 0; i < fWindowList.CountItems(); i++)
((MainWindow*)fWindowList.ItemAt(i))->PostMessage(MSG_SAVE);
for (int32 i = 0; i < fWindowList.CountItems(); i++) {
MainWindow* window = ((MainWindow*)fWindowList.ItemAt(i));
window->PostMessage(MSG_SAVE);
}
break;
}
case MSG_SETTINGS:
{
if (fSettingsWindow != NULL)
fSettingsWindow->Activate();
else
fSettingsWindow = new SettingsWindow(fSettings);
break;
}
case MSG_SETTINGS_APPLY:
{
for (int32 i = 0; i < fWindowList.CountItems(); i++) {
MainWindow* window = ((MainWindow*)fWindowList.ItemAt(i));
window->PostMessage(MSG_SETTINGS_APPLY);
}
break;
}
case MSG_SETTINGS_CLOSED:
fSettingsWindow = NULL;
break;
default:
BApplication::MessageReceived(msg);
}
@@ -98,7 +129,7 @@ ResourceEdit::ReadyToRun()
void
ResourceEdit::_CreateWindow(BEntry* assocEntry)
{
MainWindow* window = new MainWindow(_Cascade(), assocEntry);
MainWindow* window = new MainWindow(_Cascade(), assocEntry, fSettings);
fWindowList.AddItem(window);
+5
View File
@@ -10,6 +10,8 @@
class MainWindow;
class SettingsFile;
class SettingsWindow;
class BEntry;
class BFilePanel;
@@ -30,6 +32,9 @@ private:
BFilePanel* fOpenPanel;
SettingsFile* fSettings;
SettingsWindow* fSettingsWindow;
void ArgvReceived(int32 argc, char* argv[]);
void ReadyToRun();
+1 -1
View File
@@ -16,7 +16,7 @@ resource app_version {
resource app_flags B_SINGLE_LAUNCH;
resource(1, "BEOS:FILE_TYPES") message {
resource file_types message {
"types" = "text/x-vnd.Be.ResourceDef"
};
+10 -2
View File
@@ -19,7 +19,7 @@ ResourceListView::ResourceListView(BRect rect, const char* name,
BColumnListView(rect, name, resizingMode, drawFlags, border,
showHorizontalScrollbar)
{
//SetMouseTrackingEnabled(true);
}
@@ -29,11 +29,19 @@ ResourceListView::~ResourceListView()
}
void
ResourceListView::MouseDown(BPoint point)
{
PRINT(("MouseDown()"));
}
void
ResourceListView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_SIMPLE_DATA: {
case B_SIMPLE_DATA:
{
entry_ref ref;
int32 n = 0;
+1
View File
@@ -16,6 +16,7 @@ public:
bool showHorizontalScrollbar = true);
~ResourceListView();
void MouseDown(BPoint point);
void MessageReceived(BMessage* msg);
private:
+45 -33
View File
@@ -9,14 +9,17 @@
#include <ColumnListView.h>
#include <ColumnTypes.h>
#include <stdlib.h>
ResourceRow::ResourceRow()
:
BRow()
{
fRawData = NULL;
Parent = NULL;
ActionIndex = -1;
SetField(new BIntegerField(0), 0);
SetField(new BStringField(""), 0);
SetField(new BStringField(""), 1);
SetField(new BStringField(""), 2);
SetField(new BStringField(""), 3);
@@ -34,7 +37,14 @@ ResourceRow::~ResourceRow()
void
ResourceRow::SetResourceID(int32 id)
{
((BIntegerField*)GetField(0))->SetValue(id);
((BStringField*)GetField(0))->SetString((BString() << id).String());
}
void
ResourceRow::SetResourceStringID(const char* id)
{
((BStringField*)GetField(0))->SetString(id);
}
@@ -53,14 +63,22 @@ ResourceRow::SetResourceType(const char* type)
void
ResourceRow::SetResourceTypeCode(type_code code)
ResourceRow::SetResourceCode(type_code code)
{
fTypeCode = code;
TypeCodeToString(code, fTypeString);
fCode = code;
ResourceType::CodeToString(code, fTypeString);
((BStringField*)GetField(3))->SetString(fTypeString);
}
void
ResourceRow::SetResourceStringCode(const char* code)
{
fCode = ResourceType::StringToCode(code);
((BStringField*)GetField(3))->SetString(code);
}
void
ResourceRow::SetResourceData(const char* data)
{
@@ -68,23 +86,6 @@ ResourceRow::SetResourceData(const char* data)
}
void
ResourceRow::SetResourceRawData(const void* data)
{
if (data == NULL)
data = kDefaultData;
fRawData = data;
int32 ix = FindTypeCodeIndex(ResourceTypeCode());
if (ix == -1)
SetResourceData("[Unknown Data]");
else
SetResourceData(kDefaultTypes[ix].toString(fRawData));
}
void
ResourceRow::SetResourceSize(off_t size)
{
@@ -95,7 +96,18 @@ ResourceRow::SetResourceSize(off_t size)
int32
ResourceRow::ResourceID()
{
return ((BIntegerField*)GetField(0))->Value();
const char* strID = ResourceStringID();
// TODO: Check whether is numeric and resolve if not.
return atoi(strID);
}
const char*
ResourceRow::ResourceStringID()
{
return ((BStringField*)GetField(0))->String();
}
@@ -114,9 +126,16 @@ ResourceRow::ResourceType()
type_code
ResourceRow::ResourceTypeCode()
ResourceRow::ResourceCode()
{
return fTypeCode;
return fCode;
}
const char*
ResourceRow::ResourceStringCode()
{
return ((BStringField*)GetField(3))->String();
}
@@ -127,13 +146,6 @@ ResourceRow::ResourceData()
}
const void*
ResourceRow::ResourceRawData()
{
return fRawData;
}
off_t
ResourceRow::ResourceSize()
{
+9 -6
View File
@@ -17,24 +17,27 @@ public:
~ResourceRow();
void SetResourceID(int32 id);
void SetResourceStringID(const char* id);
void SetResourceName(const char* name);
void SetResourceType(const char* type);
void SetResourceTypeCode(type_code code);
void SetResourceCode(type_code code);
void SetResourceStringCode(const char* code);
void SetResourceData(const char* data);
void SetResourceRawData(const void*);
void SetResourceSize(off_t size);
int32 ResourceID();
const char* ResourceStringID();
const char* ResourceName();
const char* ResourceType();
type_code ResourceTypeCode();
type_code ResourceCode();
const char* ResourceStringCode();
const char* ResourceData();
const void* ResourceRawData();
off_t ResourceSize();
ResourceRow* Parent;
int32 ActionIndex;
private:
const void* fRawData;
type_code fTypeCode;
type_code fCode;
char fTypeString[8];
};
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "SettingsFile.h"
SettingsFile::SettingsFile(const char* name)
{
find_directory(B_USER_SETTINGS_DIRECTORY, &fPath);
fPath.Append(name, true);
}
SettingsFile::~SettingsFile()
{
}
void
SettingsFile::Defaults()
{
UndoLimit = 100;
}
void
SettingsFile::Load()
{
fFile = new BFile(fPath.Path(), B_READ_ONLY);
if (fFile->InitCheck() == B_OK) {
fFile->Read(&UndoLimit, sizeof(UndoLimit));
// TODO: Add more settings here (2/3).
} else
Defaults();
delete fFile;
}
void
SettingsFile::Save()
{
fFile = new BFile(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE);
if (fFile->InitCheck() == B_OK) {
fFile->Write(&UndoLimit, sizeof(UndoLimit));
// TODO: Add more settings here (3/3).
}
delete fFile;
}
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef SETTINGS_FILE_H
#define SETTINGS_FILE_H
#include <File.h>
#include <FindDirectory.h>
#include <Path.h>
class SettingsFile
{
public:
int32 UndoLimit;
// TODO: Add more settings here (1/3).
SettingsFile(const char* name);
~SettingsFile();
void Defaults();
void Load();
void Save();
private:
BPath fPath;
BFile* fFile;
};
#endif
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "SettingsWindow.h"
#include "Constants.h"
#include "GenericSettingsView.h"
#include "SettingsFile.h"
#include <Application.h>
#include <Button.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <ListView.h>
#include <ScrollView.h>
#include <View.h>
SettingsWindow::SettingsWindow(SettingsFile* settings)
:
BWindow(BRect(200, 150, 600, 450), "Settings", B_TITLED_WINDOW, B_NOT_RESIZABLE)
{
fSettings = settings;
BRect bounds = Bounds();
fBackView = new BView(bounds, "fBackView", B_FOLLOW_ALL, 0);
fBackView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fListView = new BListView(BRect(8, 8, 100 + 8, bounds.bottom - 8),
"fListView", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL);
// TODO: Implement selecting different categories of settings.
// fListView->SetSelectionMessage(new BMessage(...));
fListView->AddItem(new BStringItem("Generic"));
fListView->Select(0);
fScrollView = new BScrollView("fScrollView", fListView, B_FOLLOW_TOP_BOTTOM,
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
fGenericSettingsView = new GenericSettingsView(
BRect(132, 8, bounds.right - 8, bounds.bottom - 8 - 40),
"fGenericSettingsView", fSettings);
// TODO: Add more settings views (2/4).
fRevertButton = new BButton(BRect(bounds.right - 152, bounds.bottom - 32,
bounds.right - 88, bounds.bottom - 8),
"fRevertButton", "Revert",
new BMessage(MSG_SETTINGS_REVERT));
fApplyButton = new BButton(BRect(bounds.right - 72, bounds.bottom - 32,
bounds.right - 8, bounds.bottom - 8), "fApplyButton", "Apply",
new BMessage(MSG_SETTINGS_APPLY));
AdaptSettings();
fBackView->AddChild(fScrollView);
fBackView->AddChild(fGenericSettingsView);
fBackView->AddChild(fRevertButton);
fBackView->AddChild(fApplyButton);
AddChild(fBackView);
Show();
}
SettingsWindow::~SettingsWindow()
{
}
bool
SettingsWindow::QuitRequested()
{
be_app->PostMessage(MSG_SETTINGS_CLOSED);
return true;
}
void
SettingsWindow::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case MSG_SETTINGS_APPLY:
{
ApplySettings();
fSettings->Save();
be_app->PostMessage(MSG_SETTINGS_APPLY);
break;
}
case MSG_SETTINGS_REVERT:
{
AdaptSettings();
fSettings->Save();
be_app->PostMessage(MSG_SETTINGS_APPLY);
break;
}
default:
BWindow::MessageReceived(msg);
}
}
void
SettingsWindow::ApplySettings()
{
fGenericSettingsView->ApplySettings();
// TODO: Add more settings views (3/4).
}
void
SettingsWindow::AdaptSettings()
{
fGenericSettingsView->AdaptSettings();
// TODO: Add more settings views (4/4).
}
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef SETTINGS_WINDOW_H
#define SETTINGS_WINDOW_H
#include <Window.h>
class GenericSettingsView;
class SettingsFile;
class BButton;
class BListView;
class BScrollView;
class BView;
class SettingsWindow : public BWindow {
public:
SettingsWindow(SettingsFile* settings);
~SettingsWindow();
bool QuitRequested();
void MessageReceived(BMessage* msg);
void ApplySettings();
void AdaptSettings();
private:
SettingsFile* fSettings;
BView* fBackView;
BListView* fListView;
BScrollView* fScrollView;
GenericSettingsView* fGenericSettingsView;
// TODO: Add more settings (1/4).
BButton* fRevertButton;
BButton* fApplyButton;
};
#endif
@@ -0,0 +1,4 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
@@ -0,0 +1,4 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
@@ -0,0 +1,71 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "NormalEdit.h"
#include "ResourceRow.h"
#include <CheckBox.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
BooleanEdit::BooleanEdit()
:
EditView("BooleanEdit")
{
}
BooleanEdit::~BooleanEdit()
{
}
void
BooleanEdit::AttachTo(BView* view)
{
EditView::AttachTo(view);
SetLayout(new BGroupLayout(B_VERTICAL));
fValueCheck = new BCheckBox(BRect(0, 0, 0, 0), "fValueText",
"", NULL);
AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(fValueCheck)
.AddGlue()
);
view->AddChild(this);
}
void
BooleanEdit::Edit(ResourceRow* row)
{
EditView::Edit(row);
BString data = fRow->ResourceData();
if (data == "" || data == "0" || data == "false")
fValueCheck->SetValue(B_CONTROL_OFF);
else
fValueCheck->SetValue(B_CONTROL_ON);
}
void
BooleanEdit::Commit()
{
EditView::Commit();
if (fValueCheck->Value() == B_CONTROL_ON)
fRow->SetResourceData("true");
else
fRow->SetResourceData("false");
}
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef BOOLEAN_EDIT_H
#define BOOLEAN_EDIT_H
#include "EditView.h"
class BCheckBox;
class BooleanEdit : public EditView {
public:
BooleanEdit();
~BooleanEdit();
void AttachTo(BView* view);
void Edit(ResourceRow* row);
void Commit();
private:
BCheckBox* fValueCheck;
};
#endif
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "EditView.h"
EditView::EditView(const char* name)
:
BView(BRect(0, 0, 0, 0), name, 0, 0)
{
// Implemented by subclasses.
}
EditView::~EditView()
{
// Implemented by subclasses.
}
void
EditView::AttachTo(BView* view)
{
while (true) {
BView* child = ChildAt(0);
if (child == NULL)
break;
child->RemoveSelf();
}
// Implemented by subclasses.
}
void
EditView::Edit(ResourceRow* row)
{
fRow = row;
// Implemented by subclasses.
}
void
EditView::Commit()
{
// Implemented by subclasses.
}
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef EDIT_VIEW_H
#define EDIT_VIEW_H
#include <View.h>
class ResourceRow;
class EditView : public BView {
public:
EditView(const char* name);
virtual ~EditView();
virtual void AttachTo(BView* view);
virtual void Edit(ResourceRow* row);
virtual void Commit();
protected:
ResourceRow* fRow;
};
#endif
@@ -0,0 +1,64 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "NormalEdit.h"
#include "ResourceRow.h"
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <TextControl.h>
NormalEdit::NormalEdit()
:
EditView("NormalEdit")
{
}
NormalEdit::~NormalEdit()
{
}
void
NormalEdit::AttachTo(BView* view)
{
EditView::AttachTo(view);
SetLayout(new BGroupLayout(B_VERTICAL));
fValueText = new BTextControl(BRect(0, 0, 0, 0), "fValueText",
"Value:", "", NULL);
fValueText->SetDivider(50);
AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(fValueText)
.AddGlue()
);
view->AddChild(this);
}
void
NormalEdit::Edit(ResourceRow* row)
{
EditView::Edit(row);
fValueText->SetText(fRow->ResourceData());
}
void
NormalEdit::Commit()
{
EditView::Commit();
fRow->SetResourceData(fValueText->Text());
}
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef NORMAL_EDIT_H
#define NORMAL_EDIT_H
#include "EditView.h"
class BTextControl;
// TODO: Templatize this class and rename to NumericEdit.
//template<typename $type>
class NormalEdit : public EditView {
public:
NormalEdit();
~NormalEdit();
void AttachTo(BView* view);
void Edit(ResourceRow* row);
void Commit();
private:
BTextControl* fValueText;
};
#endif
@@ -0,0 +1,60 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "GenericSettingsView.h"
#include "SettingsFile.h"
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <String.h>
#include <TextControl.h>
#include <stdlib.h>
GenericSettingsView::GenericSettingsView(BRect frame, const char* name,
SettingsFile* settings, uint32 resizingMode, uint32 flags)
:
BView(frame, name, resizingMode, flags)
{
fSettings = settings;
SetLayout(new BGroupLayout(B_VERTICAL));
fUndoLimitText = new BTextControl(BRect(0, 0, 0, 0), "fUndoLimitText",
"Undo Limit:", NULL, NULL);
fUndoLimitText->SetDivider(100);
// TODO: Add more controls for generic settings (2/4).
AddChild(BGroupLayoutBuilder(B_VERTICAL, 8)
.Add(fUndoLimitText)
.AddGlue()
);
}
GenericSettingsView::~GenericSettingsView()
{
}
void
GenericSettingsView::ApplySettings()
{
fSettings->UndoLimit = atoi(fUndoLimitText->Text());
// TODO: Add more controls for generic settings (3/4).
}
void
GenericSettingsView::AdaptSettings()
{
fUndoLimitText->SetText(BString() << fSettings->UndoLimit);
// TODO: Add more controls for generic settings (4/4).
}
@@ -0,0 +1,37 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef GENERIC_SETTINGS_VIEW_H
#define GENERIC_SETTINGS_VIEW_H
#include <View.h>
class SettingsFile;
class BTextControl;
class GenericSettingsView : public BView {
public:
GenericSettingsView(BRect frame, const char* name,
SettingsFile* settings,
uint32 resizingMode = B_FOLLOW_ALL,
uint32 flags = 0);
~GenericSettingsView();
void ApplySettings();
void AdaptSettings();
private:
SettingsFile* fSettings;
BTextControl* fUndoLimitText;
// TODO: Add more controls for generic settings (1/4).
};
#endif
@@ -0,0 +1,175 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "UndoContext.h"
#include "Constants.h"
#include <List.h>
#include <String.h>
UndoContext::Action::Action(const BString& label)
{
fLabel = label;
}
UndoContext::Action::~Action()
{
}
void
UndoContext::Action::Do()
{
}
void
UndoContext::Action::Undo()
{
}
void
UndoContext::Action::SetLabel(const BString& label)
{
fLabel = label;
}
BString
UndoContext::Action::Label() const
{
return fLabel;
}
UndoContext::UndoContext()
{
fAt = 0;
fLimit = 3;
fHistory = new BList();
}
UndoContext::~UndoContext()
{
for (int32 i = 0; i < fHistory->CountItems(); i++)
delete (Action*)fHistory->ItemAt(i);
delete fHistory;
}
void
UndoContext::SetLimit(int32 limit)
{
int32 delta = fLimit - limit;
if (limit > 1)
fLimit = limit;
else
limit = 1;
if (delta > 0) {
for (int32 i = 0; i < delta; i++)
delete (Action*)fHistory->ItemAt(i);
fHistory->RemoveItems(0, delta);
if (fAt > fLimit)
fAt = fLimit;
}
}
int32
UndoContext::Limit() const
{
return fLimit;
}
void
UndoContext::Do(UndoContext::Action* action)
{
int32 count = fHistory->CountItems();
if (fAt >= fLimit)
delete (Action*)fHistory->RemoveItem((int32)0);
else {
for (int32 i = fAt; i < count; i++)
delete (Action*)fHistory->ItemAt(i);
fHistory->RemoveItems(fAt, count - fAt);
fAt++;
}
fHistory->AddItem(action);
action->Do();
}
void
UndoContext::Undo()
{
if (!CanUndo())
return;
fAt--;
((Action*)fHistory->ItemAt(fAt))->Undo();
}
void
UndoContext::Redo()
{
if (!CanRedo())
return;
((Action*)fHistory->ItemAt(fAt))->Do();
fAt++;
}
bool
UndoContext::CanUndo() const
{
return fAt > 0;
}
bool
UndoContext::CanRedo() const
{
return fAt < fHistory->CountItems();
}
BString
UndoContext::UndoLabel() const
{
if (CanUndo())
return ((Action*)fHistory->ItemAt(fAt - 1))->Label();
else
return "";
}
BString
UndoContext::RedoLabel() const
{
if (CanRedo())
return ((Action*)fHistory->ItemAt(fAt))->Label();
else
return "";
}
@@ -0,0 +1,55 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef UNDO_CONTEXT_H
#define UNDO_CONTEXT_H
#include <List.h>
#include <String.h>
class UndoContext {
public:
class Action {
public:
Action(const BString& label);
virtual ~Action();
virtual void Do();
virtual void Undo();
void SetLabel(const BString& label);
BString Label() const;
private:
BString fLabel;
};
UndoContext();
~UndoContext();
void SetLimit(int32 limit);
int32 Limit() const;
void Do(Action* action);
void Undo();
void Redo();
bool CanUndo() const;
bool CanRedo() const;
BString UndoLabel() const;
BString RedoLabel() const;
private:
int32 fAt;
int32 fLimit;
BList* fHistory;
};
#endif