hrev44227 adds 3 changesets to branch 'master' old head: 75d1324b9160367ffeffb7e228c530dd94bcfc42 new head: 2996f648811ca6080e109ac744709ef294eb1598 ---------------------------------------------------------------------------- bea2387: Made constants static, coding style cleanup. 0ba3686: Added a few convenience methods. 2996f64: Implemented a value hint, changed colors. * When you press on a value, that value will be shown with a highlighted background across the board until another value is set. * Changed the colors to those from the Haiku logo rather than the BeOS logo. This makes it a bit more colorful which one might need to get used to -- comments welcome. [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 194 insertions(+), 92 deletions(-) src/apps/sudoku/SudokuField.cpp | 23 +++++- src/apps/sudoku/SudokuField.h | 3 + src/apps/sudoku/SudokuView.cpp | 142 ++++++++++++++++++++++++++--------- src/apps/sudoku/SudokuView.h | 5 ++ src/kits/interface/Dragger.cpp | 113 ++++++++++++++-------------- ############################################################################ Commit: bea2387b6886201c5eebd41f4a2967e593c2a883 URL: http://cgit.haiku-os.org/haiku/commit/?id=bea2387 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Jun 1 21:29:44 2012 UTC Made constants static, coding style cleanup. ---------------------------------------------------------------------------- diff --git a/src/kits/interface/Dragger.cpp b/src/kits/interface/Dragger.cpp index 9b37ca3..37f92d6 100644 --- a/src/kits/interface/Dragger.cpp +++ b/src/kits/interface/Dragger.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku. + * Copyright 2001-2012, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -8,6 +8,7 @@ * Alexandre Deckner (alex@xxxxxxxxxxxx) */ + //! BDragger represents a replicant "handle". @@ -45,10 +46,10 @@ using BPrivate::gSystemCatalog; #define B_TRANSLATE(str) \ gSystemCatalog.GetString(B_TRANSLATE_MARK(str), "Dragger") -const uint32 kMsgDragStarted = 'Drgs'; -const unsigned char -kHandBitmap[] = { +static const uint32 kMsgDragStarted = 'Drgs'; + +static const unsigned char kHandBitmap[] = { 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 0, 131, 131, 0, 255, 255, 0, 0, 0, 0, 131, 131, 0, 0, @@ -112,8 +113,9 @@ DraggerManager* DraggerManager::sDefaultInstance = NULL; } // unnamed namespace -BDragger::BDragger(BRect bounds, BView *target, uint32 rmask, uint32 flags) - : BView(bounds, "_dragger_", rmask, flags), +BDragger::BDragger(BRect bounds, BView* target, uint32 resizeMask, uint32 flags) + : + BView(bounds, "_dragger_", resizeMask, flags), fTarget(target), fRelation(TARGET_UNKNOWN), fShelf(NULL), @@ -127,8 +129,9 @@ BDragger::BDragger(BRect bounds, BView *target, uint32 rmask, uint32 flags) } -BDragger::BDragger(BMessage *data) - : BView(data), +BDragger::BDragger(BMessage* data) + : + BView(data), fTarget(NULL), fRelation(TARGET_UNKNOWN), fShelf(NULL), @@ -138,16 +141,16 @@ BDragger::BDragger(BMessage *data) fPopUpIsCustom(false), fPopUp(NULL) { - data->FindInt32("_rel", (int32 *)&fRelation); + data->FindInt32("_rel", (int32*)&fRelation); _InitData(); BMessage popupMsg; if (data->FindMessage("_popup", &popupMsg) == B_OK) { - BArchivable *archivable = instantiate_object(&popupMsg); + BArchivable* archivable = instantiate_object(&popupMsg); if (archivable) { - fPopUp = dynamic_cast<BPopUpMenu *>(archivable); + fPopUp = dynamic_cast<BPopUpMenu*>(archivable); fPopUpIsCustom = true; } } @@ -162,7 +165,7 @@ BDragger::~BDragger() BArchivable * -BDragger::Instantiate(BMessage *data) +BDragger::Instantiate(BMessage* data) { if (validate_instantiation(data, "BDragger")) return new BDragger(data); @@ -171,7 +174,7 @@ BDragger::Instantiate(BMessage *data) status_t -BDragger::Archive(BMessage *data, bool deep) const +BDragger::Archive(BMessage* data, bool deep) const { status_t ret = BView::Archive(data, deep); if (ret != B_OK) @@ -179,15 +182,16 @@ BDragger::Archive(BMessage *data, bool deep) const BMessage popupMsg; - if (fPopUp && fPopUpIsCustom) { + if (fPopUp != NULL && fPopUpIsCustom) { bool windowLocked = fPopUp->Window()->Lock(); ret = fPopUp->Archive(&popupMsg, deep); - if (windowLocked) + if (windowLocked) { fPopUp->Window()->Unlock(); // TODO: Investigate, in some (rare) occasions the menu window // has already been unlocked + } if (ret == B_OK) ret = data->AddMessage("_popup", &popupMsg); @@ -229,8 +233,8 @@ BDragger::Draw(BRect update) { BRect bounds(Bounds()); - if (AreDraggersDrawn() && (!fShelf || fShelf->AllowsDragging())) { - if (Parent() && (Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { + if (AreDraggersDrawn() && (fShelf == NULL || fShelf->AllowsDragging())) { + if (Parent() != NULL && (Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { uint32 flags = Parent()->Flags(); Parent()->SetFlags(flags | B_DRAW_ON_CHILDREN); Parent()->Draw(Frame() & ConvertToParent(update)); @@ -248,7 +252,7 @@ BDragger::Draw(BRect update) // TODO: should draw it differently ? } } else if (IsVisibilityChanging()) { - if (Parent()) { + if (Parent() != NULL) { if ((Parent()->Flags() & B_DRAW_ON_CHILDREN) == 0) { uint32 flags = Parent()->Flags(); Parent()->SetFlags(flags | B_DRAW_ON_CHILDREN); @@ -266,13 +270,13 @@ BDragger::Draw(BRect update) void BDragger::MouseDown(BPoint where) { - if (!fTarget || !AreDraggersDrawn()) + if (fTarget == NULL || !AreDraggersDrawn()) return; uint32 buttons; - Window()->CurrentMessage()->FindInt32("buttons", (int32 *)&buttons); + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); - if (fShelf != NULL && (buttons & B_SECONDARY_MOUSE_BUTTON)) + if (fShelf != NULL && (buttons & B_SECONDARY_MOUSE_BUTTON) != 0) _ShowPopUp(fTarget, where); } @@ -285,14 +289,14 @@ BDragger::MouseUp(BPoint point) void -BDragger::MouseMoved(BPoint point, uint32 code, const BMessage *msg) +BDragger::MouseMoved(BPoint point, uint32 code, const BMessage* msg) { BView::MouseMoved(point, code, msg); } void -BDragger::MessageReceived(BMessage *msg) +BDragger::MessageReceived(BMessage* msg) { switch (msg->what) { case B_TRASH_TARGET: @@ -316,7 +320,8 @@ BDragger::MessageReceived(BMessage *msg) Flush(); fTransition = false; } else { - if ((fShelf && (fShelf->AllowsDragging() && AreDraggersDrawn())) + if ((fShelf != NULL && fShelf->AllowsDragging() + && AreDraggersDrawn()) || AreDraggersDrawn()) { Show(); } else @@ -332,25 +337,22 @@ BDragger::MessageReceived(BMessage *msg) fTarget->Archive(&archive); else if (fRelation == TARGET_IS_CHILD) Archive(&archive); - else { - if (fTarget->Archive(&archive)) { - BMessage archivedSelf(B_ARCHIVED_OBJECT); + else if (fTarget->Archive(&archive)) { + BMessage archivedSelf(B_ARCHIVED_OBJECT); - if (Archive(&archivedSelf)) - archive.AddMessage("__widget", &archivedSelf); - } + if (Archive(&archivedSelf)) + archive.AddMessage("__widget", &archivedSelf); } archive.AddInt32("be:actions", B_TRASH_TARGET); BPoint offset; drawing_mode mode; - BBitmap *bitmap = DragBitmap(&offset, &mode); + BBitmap* bitmap = DragBitmap(&offset, &mode); if (bitmap != NULL) DragMessage(&archive, bitmap, mode, offset, this); else { - DragMessage(&archive, - ConvertFromScreen(fTarget->ConvertToScreen(fTarget->Bounds())), - this); + DragMessage(&archive, ConvertFromScreen( + fTarget->ConvertToScreen(fTarget->Bounds())), this); } } break; @@ -543,7 +545,7 @@ BDragger::AllDetached() status_t -BDragger::SetPopUp(BPopUpMenu *menu) +BDragger::SetPopUp(BPopUpMenu* menu) { if (menu != NULL && menu != fPopUp) { delete fPopUp; @@ -555,11 +557,11 @@ BDragger::SetPopUp(BPopUpMenu *menu) } -BPopUpMenu * +BPopUpMenu* BDragger::PopUp() const { if (fPopUp == NULL && fTarget) - const_cast<BDragger *>(this)->_BuildDefaultPopUp(); + const_cast<BDragger*>(this)->_BuildDefaultPopUp(); return fPopUp; } @@ -572,15 +574,15 @@ BDragger::InShelf() const } -BView * +BView* BDragger::Target() const { return fTarget; } -BBitmap * -BDragger::DragBitmap(BPoint *offset, drawing_mode *mode) +BBitmap* +BDragger::DragBitmap(BPoint* offset, drawing_mode* mode) { return NULL; } @@ -598,8 +600,8 @@ void BDragger::_ReservedDragger3() {} void BDragger::_ReservedDragger4() {} -BDragger & -BDragger::operator=(const BDragger &) +BDragger& +BDragger::operator=(const BDragger&) { return *this; } @@ -663,7 +665,7 @@ BDragger::_RemoveFromList() status_t BDragger::_DetermineRelationship() { - if (fTarget) { + if (fTarget != NULL) { if (fTarget == Parent()) fRelation = TARGET_IS_PARENT; else if (fTarget == ChildAt(0)) @@ -680,11 +682,12 @@ BDragger::_DetermineRelationship() } if (fRelation == TARGET_IS_PARENT) { - BRect bounds (Frame()); - BRect parentBounds (Parent()->Bounds()); - if (!parentBounds.Contains(bounds)) + BRect bounds(Frame()); + BRect parentBounds(Parent()->Bounds()); + if (!parentBounds.Contains(bounds)) { MoveTo(parentBounds.right - bounds.Width(), parentBounds.bottom - bounds.Height()); + } } return B_OK; @@ -692,14 +695,14 @@ BDragger::_DetermineRelationship() status_t -BDragger::_SetViewToDrag(BView *target) +BDragger::_SetViewToDrag(BView* target) { if (target->Window() != Window()) return B_ERROR; fTarget = target; - if (Window()) + if (Window() != NULL) _DetermineRelationship(); return B_OK; @@ -707,7 +710,7 @@ BDragger::_SetViewToDrag(BView *target) void -BDragger::_SetShelf(BShelf *shelf) +BDragger::_SetShelf(BShelf* shelf) { fShelf = shelf; } @@ -731,13 +734,13 @@ BDragger::_BuildDefaultPopUp() fPopUp = new BPopUpMenu("Shelf", false, false, B_ITEMS_IN_COLUMN); // About - BMessage *msg = new BMessage(B_ABOUT_REQUESTED); + BMessage* msg = new BMessage(B_ABOUT_REQUESTED); - const char *name = fTarget->Name(); - if (name) + const char* name = fTarget->Name(); + if (name != NULL) msg->AddString("target", name); - BString about(B_TRANSLATE("About %app"B_UTF8_ELLIPSIS)); + BString about(B_TRANSLATE("About %app" B_UTF8_ELLIPSIS)); about.ReplaceFirst("%app", name); fPopUp->AddItem(new BMenuItem(about.String(), msg)); @@ -748,11 +751,11 @@ BDragger::_BuildDefaultPopUp() void -BDragger::_ShowPopUp(BView *target, BPoint where) +BDragger::_ShowPopUp(BView* target, BPoint where) { BPoint point = ConvertToScreen(where); - if (!fPopUp && fTarget) + if (fPopUp == NULL && fTarget != NULL) _BuildDefaultPopUp(); fPopUp->SetTargetForItems(fTarget); ############################################################################ Commit: 0ba36860ad2973704cf0e53e5a37f944882261de URL: http://cgit.haiku-os.org/haiku/commit/?id=0ba3686 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Tue Jun 5 22:34:51 2012 UTC Added a few convenience methods. ---------------------------------------------------------------------------- diff --git a/src/apps/sudoku/SudokuField.cpp b/src/apps/sudoku/SudokuField.cpp index a139d47..f1ff6bc 100644 --- a/src/apps/sudoku/SudokuField.cpp +++ b/src/apps/sudoku/SudokuField.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2007-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -280,6 +280,13 @@ SudokuField::HintMaskAt(uint32 x, uint32 y) const } +bool +SudokuField::HasHint(uint32 x, uint32 y, uint32 value) const +{ + return (_FieldAt(x, y).hint_mask & (1UL << (value - 1))) != 0; +} + + void SudokuField::SetValidMaskAt(uint32 x, uint32 y, uint32 validMask) { @@ -294,6 +301,13 @@ SudokuField::ValidMaskAt(uint32 x, uint32 y) const } +bool +SudokuField::IsValid(uint32 x, uint32 y, uint32 value) const +{ + return (_FieldAt(x, y).valid_mask & (1UL << (value - 1))) != 0; +} + + void SudokuField::SetFlagsAt(uint32 x, uint32 y, uint32 flags) { @@ -308,6 +322,13 @@ SudokuField::FlagsAt(uint32 x, uint32 y) const } +bool +SudokuField::IsInitialValue(uint32 x, uint32 y) const +{ + return (_FieldAt(x, y).flags & kInitialValue) != 0; +} + + void SudokuField::SetValueAt(uint32 x, uint32 y, uint32 value, bool setSolved) { diff --git a/src/apps/sudoku/SudokuField.h b/src/apps/sudoku/SudokuField.h index 2b0bbf6f..ace2647 100644 --- a/src/apps/sudoku/SudokuField.h +++ b/src/apps/sudoku/SudokuField.h @@ -41,13 +41,16 @@ public: void SetHintMaskAt(uint32 x, uint32 y, uint32 hintMask); uint32 HintMaskAt(uint32 x, uint32 y) const; + bool HasHint(uint32 x, uint32 y, uint32 value) const; void SetValidMaskAt(uint32 x, uint32 y, uint32 validMask); uint32 ValidMaskAt(uint32 x, uint32 y) const; + bool IsValid(uint32 x, uint32 y, uint32 value) const; void SetFlagsAt(uint32 x, uint32 y, uint32 flags); uint32 FlagsAt(uint32 x, uint32 y) const; + bool IsInitialValue(uint32 x, uint32 y) const; void SetValueAt(uint32 x, uint32 y, uint32 value, bool setSolved = false); ############################################################################ Revision: hrev44227 Commit: 2996f648811ca6080e109ac744709ef294eb1598 URL: http://cgit.haiku-os.org/haiku/commit/?id=2996f64 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Tue Jun 5 22:35:51 2012 UTC Implemented a value hint, changed colors. * When you press on a value, that value will be shown with a highlighted background across the board until another value is set. * Changed the colors to those from the Haiku logo rather than the BeOS logo. This makes it a bit more colorful which one might need to get used to -- comments welcome. ---------------------------------------------------------------------------- diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index 6533162..849c5e5 100644 --- a/src/apps/sudoku/SudokuView.cpp +++ b/src/apps/sudoku/SudokuView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2007-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -28,9 +28,17 @@ #include <String.h> -const uint32 kMsgCheckSolved = 'chks'; +static const uint32 kMsgCheckSolved = 'chks'; -const uint32 kStrongLineSize = 2; +static const uint32 kStrongLineSize = 2; + +static const rgb_color kBackgroundColor = {255, 255, 240}; +static const rgb_color kHintColor = {255, 115, 0}; +static const rgb_color kValueColor = {0, 91, 162}; +static const rgb_color kValueCompletedColor = {55, 140, 35}; +static const rgb_color kInvalidValueColor = {200, 0, 0}; +static const rgb_color kValueHintBackgroundColor = {255, 215, 127}; +static const rgb_color kHintValueHintBackgroundColor = {255, 235, 185}; extern const char* kSignature; @@ -103,6 +111,7 @@ SudokuView::InitObject(const BMessage* archive) { fField = NULL; fShowHintX = ~0UL; + fValueHintValue = ~0UL; fLastHintValue = ~0UL; fLastField = ~0UL; fKeyboardX = 0; @@ -131,9 +140,8 @@ SudokuView::InitObject(const BMessage* archive) SetViewColor(B_TRANSPARENT_COLOR); // to avoid flickering - rgb_color color = { 255, 255, 240 }; - fBackgroundColor = color; - SetLowColor(color); + fBackgroundColor = kBackgroundColor; + SetLowColor(fBackgroundColor); FrameResized(0, 0); } @@ -212,6 +220,7 @@ SudokuView::SetTo(entry_ref& ref) _PushUndo(); status = fField->SetTo(_BaseCharacter(), buffer); + fValueHintValue = ~0UL; Invalidate(); fclose(file); return status; @@ -234,6 +243,7 @@ SudokuView::SetTo(const char* data) _PushUndo(); status = fField->SetTo(_BaseCharacter(), buffer); + fValueHintValue = ~0UL; Invalidate(); return status; } @@ -250,6 +260,7 @@ SudokuView::SetTo(SudokuField* field) fField = field; fBlockSize = fField->BlockSize(); + fValueHintValue = ~0UL; FrameResized(0, 0); Invalidate(); return B_OK; @@ -377,7 +388,7 @@ SudokuView::SaveTo(BDataIO& stream, uint32 exportAs) text << "<td width=\"" << divider << "\" "; text << "class=\"sudoku sudoku_empty " << style; text << "\">\n "; - } else if (fField->FlagsAt(x, y) & kInitialValue) { + } else if (fField->IsInitialValue(x, y)) { text << "<td width=\"" << divider << "\" "; text << "class=\"sudoku sudoku_initial " << style << "\">\n"; @@ -543,7 +554,7 @@ SudokuView::ClearChanged() for (uint32 y = 0; y < fField->Size(); y++) { for (uint32 x = 0; x < fField->Size(); x++) { - if ((fField->FlagsAt(x, y) & kInitialValue) == 0) + if (!fField->IsInitialValue(x, y)) fField->SetValueAt(x, y, 0); } } @@ -612,8 +623,9 @@ SudokuView::FrameResized(float /*width*/, float /*height*/) // font for numbers uint32 size = fField->Size(); - fWidth = (Bounds().Width() - kStrongLineSize * (fBlockSize - 1)) / size; - fHeight = (Bounds().Height() - kStrongLineSize * (fBlockSize - 1)) / size; + fWidth = (Bounds().Width() + 2 - kStrongLineSize * (fBlockSize - 1)) / size; + fHeight = (Bounds().Height() + 2 - kStrongLineSize * (fBlockSize - 1)) + / size; _FitFont(fFieldFont, fWidth - 2, fHeight - 2); font_height fontHeight; @@ -641,8 +653,8 @@ SudokuView::FrameResized(float /*width*/, float /*height*/) BPoint SudokuView::_LeftTop(uint32 x, uint32 y) { - return BPoint(x * fWidth + x / fBlockSize * kStrongLineSize + 1, - y * fHeight + y / fBlockSize * kStrongLineSize + 1); + return BPoint(x * fWidth - 1 + x / fBlockSize * kStrongLineSize + 1, + y * fHeight - 1 + y / fBlockSize * kStrongLineSize + 1); } @@ -679,6 +691,22 @@ SudokuView::_InvalidateField(uint32 x, uint32 y) void +SudokuView::_InvalidateValue(uint32 value, bool invalidateHint, + uint32 fieldX, uint32 fieldY) +{ + for (uint32 y = 0; y < fField->Size(); y++) { + for (uint32 x = 0; x < fField->Size(); x++) { + if (fField->ValueAt(x, y) == value || (x == fieldX && y == fieldY)) + Invalidate(_Frame(x, y)); + else if (invalidateHint && fField->ValueAt(x, y) == 0 + && fField->HasHint(x, y, value)) + Invalidate(_Frame(x, y)); + } + } +} + + +void SudokuView::_InvalidateKeyboardFocus(uint32 x, uint32 y) { BRect frame = _Frame(x, y); @@ -724,6 +752,22 @@ SudokuView::_GetFieldFor(BPoint where, uint32& x, uint32& y) void +SudokuView::_SetValueHintValue(uint32 value) +{ + if (value == fValueHintValue) + return; + + if (fValueHintValue != ~0UL) + _InvalidateValue(fValueHintValue, true); + + fValueHintValue = value; + + if (fValueHintValue != ~0UL) + _InvalidateValue(fValueHintValue, true); +} + + +void SudokuView::_RemoveHint() { if (fShowHintX == ~0UL) @@ -801,6 +845,15 @@ SudokuView::MouseDown(BPoint where) Looper()->CurrentMessage()->FindInt32("clicks", &clicks); } + if (buttons == B_PRIMARY_MOUSE_BUTTON && clicks == 1) { + uint32 value = fField->ValueAt(x, y); + if (value != 0) { + // Toggle value hint + _SetValueHintValue(fValueHintValue == value ? ~0UL : value); + return; + } + } + uint32 hintX, hintY; if (!_GetHintFieldFor(where, x, y, hintX, hintY)) return; @@ -813,9 +866,10 @@ SudokuView::MouseDown(BPoint where) || (buttons & (B_SECONDARY_MOUSE_BUTTON | B_TERTIARY_MOUSE_BUTTON)) != 0) { // double click or other buttons set a value - if ((fField->FlagsAt(x, y) & kInitialValue) == 0) { + if (!fField->IsInitialValue(x, y)) { bool wasCompleted; if (fField->ValueAt(x, y) > 0) { + // Remove value value = fField->ValueAt(x, y) - 1; wasCompleted = fField->IsValueCompleted(value + 1); @@ -823,6 +877,7 @@ SudokuView::MouseDown(BPoint where) fShowHintX = x; fShowHintY = y; } else { + // Set value wasCompleted = fField->IsValueCompleted(value + 1); fField->SetValueAt(x, y, value + 1); @@ -834,8 +889,11 @@ SudokuView::MouseDown(BPoint where) fLastField = field; } + if (value + 1 != fValueHintValue) + _SetValueHintValue(~0UL); + if (wasCompleted != fField->IsValueCompleted(value + 1)) - Invalidate(); + _InvalidateValue(value + 1, false, x, y); else _InvalidateField(x, y); } @@ -852,7 +910,12 @@ SudokuView::MouseDown(BPoint where) hintMask &= ~valueMask; fField->SetHintMaskAt(x, y, hintMask); - _InvalidateHintField(x, y, hintX, hintY); + + if (value + 1 != fValueHintValue) { + _SetValueHintValue(~0UL); + _InvalidateHintField(x, y, hintX, hintY); + } else + _InvalidateField(x, y); fLastHintValue = value; fLastField = field; @@ -879,8 +942,9 @@ SudokuView::MouseMoved(BPoint where, uint32 transit, fKeyboardX = x; fKeyboardY = y; } + if (!isField - || (fField->FlagsAt(x, y) & kInitialValue) != 0 + || fField->IsInitialValue(x, y) || (!fShowCursor && fField->ValueAt(x, y) != 0)) { _RemoveHint(); return; @@ -919,7 +983,7 @@ void SudokuView::_InsertKey(char rawKey, int32 modifiers) { if (!fEditable || !_ValidCharacter(rawKey) - || (fField->FlagsAt(fKeyboardX, fKeyboardY) & kInitialValue) != 0) + || fField->IsInitialValue(fKeyboardX, fKeyboardY)) return; uint32 value = rawKey - _BaseCharacter(); @@ -1144,9 +1208,12 @@ SudokuView::_DrawHints(uint32 x, uint32 y) for (uint32 j = 0; j < fBlockSize; j++) { for (uint32 i = 0; i < fBlockSize; i++) { uint32 value = j * fBlockSize + i; - if (hintMask & (1UL << value)) - SetHighColor(200, 0, 0); - else { + if (hintMask & (1UL << value)) { +// if (value + 1 == fValueHintValue) +// SetHighColor(kValueHintBackgroundColor); +// else + SetHighColor(kHintColor); + }else { if (!showAll) continue; @@ -1170,18 +1237,14 @@ SudokuView::_DrawHints(uint32 x, uint32 y) void SudokuView::Draw(BRect /*updateRect*/) { - // draw one pixel border otherwise not covered - // by lines and fields - SetLowColor(fBackgroundColor); - StrokeRect(Bounds(), B_SOLID_LOW); - // draw lines uint32 size = fField->Size(); + SetLowColor(fBackgroundColor); SetHighColor(0, 0, 0); - float width = fWidth; + float width = fWidth - 1; for (uint32 x = 1; x < size; x++) { if (x % fBlockSize == 0) { FillRect(BRect(width, 0, width + kStrongLineSize, @@ -1193,7 +1256,7 @@ SudokuView::Draw(BRect /*updateRect*/) width += fWidth; } - float height = fHeight; + float height = fHeight - 1; for (uint32 y = 1; y < size; y++) { if (y % fBlockSize == 0) { FillRect(BRect(0, height, Bounds().Width(), @@ -1209,39 +1272,46 @@ SudokuView::Draw(BRect /*updateRect*/) for (uint32 y = 0; y < size; y++) { for (uint32 x = 0; x < size; x++) { + uint32 value = fField->ValueAt(x, y); + + rgb_color backgroundColor = fBackgroundColor; + if (value == fValueHintValue) + backgroundColor = kValueHintBackgroundColor; + else if (value == 0 && fField->HasHint(x, y, fValueHintValue)) + backgroundColor = kHintValueHintBackgroundColor; + if (((fShowCursor && x == fShowHintX && y == fShowHintY) || (fShowKeyboardFocus && x == fKeyboardX && y == fKeyboardY)) - && (fField->FlagsAt(x, y) & kInitialValue) == 0) { + && !fField->IsInitialValue(x, y)) { // TODO: make color more intense - SetLowColor(tint_color(fBackgroundColor, B_DARKEN_2_TINT)); + SetLowColor(tint_color(backgroundColor, B_DARKEN_2_TINT)); FillRect(_Frame(x, y), B_SOLID_LOW); } else { - SetLowColor(fBackgroundColor); + SetLowColor(backgroundColor); FillRect(_Frame(x, y), B_SOLID_LOW); } if (fShowKeyboardFocus && x == fKeyboardX && y == fKeyboardY) _DrawKeyboardFocus(); - uint32 value = fField->ValueAt(x, y); if (value == 0) { _DrawHints(x, y); continue; } SetFont(&fFieldFont); - if ((fField->FlagsAt(x, y) & kInitialValue) != 0) + if (fField->IsInitialValue(x, y)) SetHighColor(0, 0, 0); else { if ((fHintFlags & kMarkInvalid) == 0 - || fField->ValidMaskAt(x, y) & (1UL << (value - 1))) { + || fField->IsValid(x, y, value)) { if (fField->IsValueCompleted(value)) - SetHighColor(60, 60, 150); + SetHighColor(kValueCompletedColor); else - SetHighColor(0, 0, 220); + SetHighColor(kValueColor); } else - SetHighColor(200, 0, 0); + SetHighColor(kInvalidValueColor); } char text[2]; diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 70b67c7..59532fb 100644 --- a/src/apps/sudoku/SudokuView.h +++ b/src/apps/sudoku/SudokuView.h @@ -94,8 +94,12 @@ private: void _InvalidateHintField(uint32 x, uint32 y, uint32 hintX, uint32 hintY); void _InvalidateField(uint32 x, uint32 y); + void _InvalidateValue(uint32 value, + bool invalidateHint = false, + uint32 x = ~0UL, uint32 y = ~0UL); void _InvalidateKeyboardFocus(uint32 x, uint32 y); void _InsertKey(char rawKey, int32 modifiers); + void _SetValueHintValue(uint32 value); void _RemoveHint(); bool _GetHintFieldFor(BPoint where, uint32 x, uint32 y, uint32& hintX, uint32& hintY); @@ -127,6 +131,7 @@ private: uint32 fShowHintY; uint32 fLastHintValue; bool fLastHintValueSet; + uint32 fValueHintValue; uint32 fLastField; uint32 fKeyboardX; uint32 fKeyboardY;