Author: stippi Date: Wed Mar 3 11:08:50 2010 New Revision: 278 URL: http://mmlr.dyndns.org/changeset/278 Log: Moved some utility stuff into new subfolder "support". Some of these needs to be removed too, once WebPositive is moved into Haiku. SettingsMessage comes straight from MediaPlayer. Should be moved into src/kits/shared eventually. Added: webkit/trunk/WebKit/haiku/WebPositive/support/ webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.cpp - copied unchanged from r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.cpp webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.h - copied unchanged from r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.h webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.cpp - copied unchanged from r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.cpp webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.h - copied unchanged from r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.h webkit/trunk/WebKit/haiku/WebPositive/support/IconUtils.h - copied unchanged from r252, webkit/trunk/WebKit/haiku/WebPositive/IconUtils.h webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.cpp webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.h Deleted: webkit/trunk/WebKit/haiku/WebPositive/DateTime.cpp webkit/trunk/WebKit/haiku/WebPositive/DateTime.h webkit/trunk/WebKit/haiku/WebPositive/IconButton.cpp webkit/trunk/WebKit/haiku/WebPositive/IconButton.h webkit/trunk/WebKit/haiku/WebPositive/IconUtils.h Modified: webkit/trunk/WebKit/Jamfile Modified: webkit/trunk/WebKit/Jamfile ============================================================================== --- webkit/trunk/WebKit/Jamfile Wed Mar 3 10:57:46 2010 (r277) +++ webkit/trunk/WebKit/Jamfile Wed Mar 3 11:08:50 2010 (r278) @@ -114,18 +114,21 @@ #----------------------------------------------------------------------------- SEARCH_SOURCE += [ FDirName $(TOP) WebKit haiku WebPositive ] ; SEARCH_SOURCE += [ FDirName $(TOP) WebKit haiku WebPositive autocompletion ] ; +SEARCH_SOURCE += [ FDirName $(TOP) WebKit haiku WebPositive support ] ; Application WebPositive : # autocompletion AutoCompleter.cpp AutoCompleterDefaultImpl.cpp TextControlCompleter.cpp + # support + DateTime.cpp + IconButton.cpp + SettingsMessage.cpp # WebPositive AuthenticationPanel.cpp BrowsingHistory.cpp - DateTime.cpp DownloadWindow.cpp - IconButton.cpp BrowserApp.cpp BrowserWindow.cpp SettingsWindow.cpp Copied: webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.cpp (from r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.cpp) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.cpp Wed Mar 3 11:08:50 2010 (r278, copy of r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.cpp) @@ -0,0 +1,1367 @@ +/* + * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Julun <host.haiku@xxxxxx> + * Stephan Aßmus <superstippi@xxxxxx> + */ + +#include "DateTime.h" + + +#include <time.h> +#include <sys/time.h> + +#include <Message.h> + + +namespace BPrivate { + + +const int32 kSecondsPerMinute = 60; + +const int32 kHoursPerDay = 24; +const int32 kMinutesPerDay = 1440; +const int32 kSecondsPerDay = 86400; +const int32 kMillisecondsPerDay = 86400000; + +const bigtime_t kMicrosecondsPerSecond = 1000000LL; +const bigtime_t kMicrosecondsPerMinute = 60000000LL; +const bigtime_t kMicrosecondsPerHour = 3600000000LL; +const bigtime_t kMicrosecondsPerDay = 86400000000LL; + + +/*! + Constructs a new BTime object. Asked for its time representation, it will + return 0 for Hour(), Minute(), Second() etc. This can represent midnight, + but be aware IsValid() will return false. +*/ +BTime::BTime() + : fMicroseconds(-1) +{ +} + + +/*! + Constructs a BTime object with \c hour \c minute, \c second, \c microsecond. + + \c hour must be between 0 and 23, \c minute and \c second must be between + 0 and 59 and \c microsecond should be in the range of 0 and 999999. If the + specified time is invalid, the time is not set and IsValid() returns false. +*/ +BTime::BTime(int32 hour, int32 minute, int32 second, int32 microsecond) + : fMicroseconds(-1) +{ + _SetTime(hour, minute, second, microsecond); +} + + +/*! + Constructs a new BTime object from the provided BMessage archive. +*/ +BTime::BTime(const BMessage* archive) + : fMicroseconds(-1) +{ + if (archive == NULL) + return; + archive->FindInt64("mircoseconds", &fMicroseconds); +} + + +/*! + Empty destructor. +*/ +BTime::~BTime() +{ +} + + +/*! + Archives the BTime object into the provided BMessage object. + @returns \c B_OK if all went well. + \c B_BAD_VALUE, if the message is \c NULL. + \c other error codes, depending on failure to append + fields to the message. +*/ +status_t +BTime::Archive(BMessage* into) const +{ + if (into == NULL) + return B_BAD_VALUE; + return into->AddInt64("mircoseconds", fMicroseconds); +} + + +/*! + Returns true if the time is valid, otherwise false. A valid time can be + BTime(23, 59, 59, 999999) while BTime(24, 00, 01) would be invalid. +*/ +bool +BTime::IsValid() const +{ + return fMicroseconds > -1 && fMicroseconds < kMicrosecondsPerDay; +} + + +/*! + This is an overloaded member function, provided for convenience. +*/ +bool +BTime::IsValid(const BTime& time) const +{ + return time.fMicroseconds > -1 && time.fMicroseconds < kMicrosecondsPerDay; +} + + +/*! + This is an overloaded member function, provided for convenience. +*/ +bool +BTime::IsValid(int32 hour, int32 minute, int32 second, int32 microsecond) const +{ + return BTime(hour, minute, second, microsecond).IsValid(); +} + + +/*! + Returns the current time as reported by the system depending on the given + time_type \c type. +*/ +BTime +BTime::CurrentTime(time_type type) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + // gettimeofday failed? + time(&tv.tv_sec); + } + + struct tm result; + struct tm* timeinfo; + if (type == B_GMT_TIME) + timeinfo = gmtime_r(&tv.tv_sec, &result); + else + timeinfo = localtime_r(&tv.tv_sec, &result); + + int32 sec = timeinfo->tm_sec; + return BTime(timeinfo->tm_hour, timeinfo->tm_min, (sec > 59) ? 59 : sec, + tv.tv_usec); +} + + +/*! + Returns a copy of the current BTime object. +*/ +BTime +BTime::Time() const +{ + return *this; +} + + +/*! + This is an overloaded member function, provided for convenience. Set the + current BTime object to the passed BTime \c time object. +*/ +bool +BTime::SetTime(const BTime& time) +{ + fMicroseconds = time.fMicroseconds; + return IsValid(); +} + + +/*! + Set the time to \c hour \c minute, \c second and \c microsecond. + + \c hour must be between 0 and 23, \c minute and \c second must be between + 0 and 59 and \c microsecond should be in the range of 0 and 999999. Returns + true if the time is valid; otherwise false. If the specified time is + invalid, the time is not set and the function returns false. +*/ +bool +BTime::SetTime(int32 hour, int32 minute, int32 second, int32 microsecond) +{ + return _SetTime(hour, minute, second, microsecond); +} + + + +/*! + Adds \c hours to the current time. If the passed value is negativ it will + become earlier. Note: The time will wrap if it passes midnight. +*/ +void +BTime::AddHours(int32 hours) +{ + _AddMicroseconds(bigtime_t(hours % kHoursPerDay) * kMicrosecondsPerHour); +} + + +/*! + Adds \c minutes to the current time. If the passed value is negativ it will + become earlier. Note: The time will wrap if it passes midnight. +*/ +void +BTime::AddMinutes(int32 minutes) +{ + _AddMicroseconds(bigtime_t(minutes % kMinutesPerDay) * + kMicrosecondsPerMinute); +} + + +/*! + Adds \c seconds to the current time. If the passed value is negativ it will + become earlier. Note: The time will wrap if it passes midnight. +*/ +void +BTime::AddSeconds(int32 seconds) +{ + _AddMicroseconds(bigtime_t(seconds % kSecondsPerDay) * + kMicrosecondsPerSecond); +} + + +/*! + Adds \c milliseconds to the current time. If the passed value is negativ it + will become earlier. Note: The time will wrap if it passes midnight. +*/ +void +BTime::AddMilliseconds(int32 milliseconds) +{ + _AddMicroseconds(bigtime_t(milliseconds % kMillisecondsPerDay) * 1000); +} + + +/*! + Adds \c microseconds to the current time. If the passed value is negativ it + will become earlier. Note: The time will wrap if it passes midnight. +*/ +void +BTime::AddMicroseconds(int32 microseconds) +{ + _AddMicroseconds(microseconds); +} + + +/*! + Returns the hour fragment of the time. +*/ +int32 +BTime::Hour() const +{ + return int32(_Microseconds() / kMicrosecondsPerHour); +} + + +/*! + Returns the minute fragment of the time. +*/ +int32 +BTime::Minute() const +{ + return int32(((_Microseconds() % kMicrosecondsPerHour)) / kMicrosecondsPerMinute); +} + + +/*! + Returns the second fragment of the time. +*/ +int32 +BTime::Second() const +{ + return int32(_Microseconds() / kMicrosecondsPerSecond) % kSecondsPerMinute; +} + + +/*! + Returns the millisecond fragment of the time. +*/ +int32 +BTime::Millisecond() const +{ + + return Microsecond() / 1000; +} + + +/*! + Returns the microsecond fragment of the time. +*/ +int32 +BTime::Microsecond() const +{ + return int32(_Microseconds() % 1000000); +} + + +bigtime_t +BTime::_Microseconds() const +{ + return fMicroseconds == -1 ? 0 : fMicroseconds; +} + + +/*! + Returns the difference between this time and the given BTime \c time based + on the passed diff_type \c type. If \c time is earlier the return value will + be negativ. + + The return value then can be hours, minutes, seconds, milliseconds or + microseconds while its range will always be between -86400000000 and + 86400000000 depending on diff_type \c type. +*/ +bigtime_t +BTime::Difference(const BTime& time, diff_type type) const +{ + bigtime_t diff = time._Microseconds() - _Microseconds(); + switch (type) { + case B_HOURS_DIFF: { + diff /= kMicrosecondsPerHour; + } break; + case B_MINUTES_DIFF: { + diff /= kMicrosecondsPerMinute; + } break; + case B_SECONDS_DIFF: { + diff /= kMicrosecondsPerSecond; + } break; + case B_MILLISECONDS_DIFF: { + diff /= 1000; + } break; + case B_MICROSECONDS_DIFF: + default: break; + } + return diff; +} + + +/*! + Returns true if this time is different from \c time, otherwise false. +*/ +bool +BTime::operator!=(const BTime& time) const +{ + return fMicroseconds != time.fMicroseconds; +} + + +/*! + Returns true if this time is equal to \c time, otherwise false. +*/ +bool +BTime::operator==(const BTime& time) const +{ + return fMicroseconds == time.fMicroseconds; +} + + +/*! + Returns true if this time is earlier than \c time, otherwise false. +*/ +bool +BTime::operator<(const BTime& time) const +{ + return fMicroseconds < time.fMicroseconds; +} + + +/*! + Returns true if this time is earlier than or equal to \c time, otherwise false. +*/ +bool +BTime::operator<=(const BTime& time) const +{ + return fMicroseconds <= time.fMicroseconds; +} + + +/*! + Returns true if this time is later than \c time, otherwise false. +*/ +bool +BTime::operator>(const BTime& time) const +{ + return fMicroseconds > time.fMicroseconds; +} + + +/*! + Returns true if this time is later than or equal to \c time, otherwise false. +*/ +bool +BTime::operator>=(const BTime& time) const +{ + return fMicroseconds >= time.fMicroseconds; +} + + +void +BTime::_AddMicroseconds(bigtime_t microseconds) +{ + bigtime_t count = 0; + if (microseconds < 0) { + count = ((kMicrosecondsPerDay - microseconds) / kMicrosecondsPerDay) * + kMicrosecondsPerDay; + } + fMicroseconds = (_Microseconds() + microseconds + count) % kMicrosecondsPerDay; +} + + +bool +BTime::_SetTime(bigtime_t hour, bigtime_t minute, bigtime_t second, + bigtime_t microsecond) +{ + fMicroseconds = hour * kMicrosecondsPerHour + + minute * kMicrosecondsPerMinute + + second * kMicrosecondsPerSecond + + microsecond; + + bool isValid = IsValid(); + if (!isValid) + fMicroseconds = -1; + + return isValid; +} + + +// #pragma mark - BDate + + +/*! + Constructs a new BDate object. IsValid() will return false. +*/ +BDate::BDate() + : fDay(-1), + fYear(0), + fMonth(-1) +{ +} + + +/*! + Constructs a BDate object with \c year \c month and \c day. + + Please note that a date before 1.1.4713 BC, a date with year 0 and a date + between 4.10.1582 and 15.10.1582 are considered invalid. If the specified + date is invalid, the date is not set and IsValid() returns false. Also note + that every passed year will be interpreted as is. + +*/ +BDate::BDate(int32 year, int32 month, int32 day) +{ + _SetDate(year, month, day); +} + + +/*! + Constructs a new BDate object from the provided archive. +*/ +BDate::BDate(const BMessage* archive) + : fDay(-1), + fYear(0), + fMonth(-1) +{ + if (archive == NULL) + return; + archive->FindInt32("day", &fDay); + archive->FindInt32("year", &fYear); + archive->FindInt32("month", &fMonth); +} + + +/*! + Empty destructor. +*/ +BDate::~BDate() +{ +} + + +/*! + Archives the BDate object into the provided BMessage object. + @returns \c B_OK if all went well. + \c B_BAD_VALUE, if the message is \c NULL. + \c other error codes, depending on failure to append + fields to the message. +*/ +status_t +BDate::Archive(BMessage* into) const +{ + if (into == NULL) + return B_BAD_VALUE; + status_t ret = into->AddInt32("day", fDay); + if (ret == B_OK) + ret = into->AddInt32("year", fYear); + if (ret == B_OK) + ret = into->AddInt32("month", fMonth); + return ret; +} + + +/*! + Returns true if the date is valid, otherwise false. + + Please note that a date before 1.1.4713 BC, a date with year 0 and a date + between 4.10.1582 and 15.10.1582 are considered invalid. +*/ +bool +BDate::IsValid() const +{ + return IsValid(fYear, fMonth, fDay); +} + + +/*! + This is an overloaded member function, provided for convenience. +*/ +bool +BDate::IsValid(const BDate& date) const +{ + return IsValid(date.fYear, date.fMonth, date.fDay); +} + + +/*! + This is an overloaded member function, provided for convenience. +*/ +bool +BDate::IsValid(int32 year, int32 month, int32 day) const +{ + // no year 0 in Julian and nothing before 1.1.4713 BC + if (year == 0 || year < -4713) + return false; + + if (month < 1 || month > 12) + return false; + + if (day < 1 || day > _DaysInMonth(year, month)) + return false; + + // 'missing' days between switch julian - gregorian + if (year == 1582 && month == 10 && day > 4 && day < 15) + return false; + + return true; +} + + +/*! + Returns the current date as reported by the system depending on the given + time_type \c type. +*/ +BDate +BDate::CurrentDate(time_type type) +{ + time_t timer; + struct tm result; + struct tm* timeinfo; + + time(&timer); + + if (type == B_GMT_TIME) + timeinfo = gmtime_r(&timer, &result); + else + timeinfo = localtime_r(&timer, &result); + + return BDate(timeinfo->tm_year + 1900, timeinfo->tm_mon +1, timeinfo->tm_mday); +} + + +/*! + Returns a copy of the current BTime object. +*/ +BDate +BDate::Date() const +{ + return *this; +} + + +/*! + This is an overloaded member function, provided for convenience. +*/ +bool +BDate::SetDate(const BDate& date) +{ + return _SetDate(date.fYear, date.fMonth, date.fDay); +} + + +/*! + Set the date to \c year \c month and \c day. + + Returns true if the date is valid; otherwise false. If the specified date is + invalid, the date is not set and the function returns false. +*/ +bool +BDate::SetDate(int32 year, int32 month, int32 day) +{ + return _SetDate(year, month, day); +} + + +/*! + This function sets the given \c year, \c month and \c day to the + representative values of this date. The pointers can be NULL. If the date is + invalid, the values will be set to -1 for \c month and \c day, the \c year + will be set to 0. +*/ +void +BDate::GetDate(int32* year, int32* month, int32* day) +{ + if (year) + *year = fYear; + + if (month) + *month = fMonth; + + if (day) + *day = fDay; +} + + +/*! + Adds \c days to the current date. If the passed value is negativ it will + become earlier. If the current date is invalid, the \c days are not added. +*/ +void +BDate::AddDays(int32 days) +{ + if (IsValid()) + *this = JulianDayToDate(DateToJulianDay() + days); +} + + +/*! + Adds \c years to the current date. If the passed value is negativ it will + become earlier. If the current date is invalid, the \c years are not added. + The day/ month combination will be adjusted if it does not exist in the + resulting year, so this function will then return the latest valid date. +*/ +void +BDate::AddYears(int32 years) +{ + if (IsValid()) { + const int32 tmp = fYear; + fYear += years; + + if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) + fYear += (years > 0) ? +1 : -1; + + fDay = min_c(fDay, _DaysInMonth(fYear, fMonth)); + } +} + + +/*! + Adds \c months to the current date. If the passed value is negativ it will + become earlier. If the current date is invalid, the \c months are not added. + The day/ month combination will be adjusted if it does not exist in the + resulting year, so this function will then return the latest valid date. +*/ +void +BDate::AddMonths(int32 months) +{ + if (IsValid()) { + const int32 tmp = fYear; + fYear += months / 12; + fMonth += months % 12; + + if (fMonth > 12) { + fYear++; + fMonth -= 12; + } else if (fMonth < 1) { + fYear--; + fMonth += 12; + } + + if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) + fYear += (months > 0) ? +1 : -1; + + // 'missing' days between switch julian - gregorian + if (fYear == 1582 && fMonth == 10 && fDay > 4 && fDay < 15) + fDay = (months > 0) ? 15 : 4; + + fDay = min_c(fDay, DaysInMonth()); + } +} + + +/*! + Returns the day fragment of the date. The return value will be in the range + of 1 to 31, in case the date is invalid it will be -1. +*/ +int32 +BDate::Day() const +{ + return fDay; +} + + +/*! + Returns the year fragment of the date. If the date is invalid, the function + returns 0. +*/ +int32 +BDate::Year() const +{ + return fYear; +} + + +/*! + Returns the month fragment of the date. The return value will be in the + range of 1 to 12, in case the date is invalid it will be -1. +*/ +int32 +BDate::Month() const +{ + return fMonth; +} + + +/*! + Returns the difference in days between this date and the given BDate \c date. + If \c date is earlier the return value will be negativ. If the calculation + is done with an invalid date, the result is undefined. +*/ +int32 +BDate::Difference(const BDate& date) const +{ + return date.DateToJulianDay() - DateToJulianDay(); +} + + +/*! + Returns the week number of the date, if the date is invalid it will return + B_ERROR. Please note that this function does only work within the Gregorian + calendar, thus a date before 15.10.1582 will return B_ERROR. +*/ +int32 +BDate::WeekNumber() const +{ + /* + This algorithm is taken from: + Frequently Asked Questions about Calendars + Version 2.8 Claus Tøndering 15 December 2005 + + Note: it will work only within the Gregorian Calendar + */ + + if (!IsValid() || fYear < 1582 + || (fYear == 1582 && fMonth < 10) + || (fYear == 1582 && fMonth == 10 && fDay < 15)) + return int32(B_ERROR); + + int32 a; + int32 b; + int32 s; + int32 e; + int32 f; + + if (fMonth > 0 && fMonth < 3) { + a = fYear - 1; + b = (a / 4) - (a / 100) + (a / 400); + int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); + s = b - c; + e = 0; + f = fDay - 1 + 31 * (fMonth - 1); + } else if (fMonth >= 3 && fMonth <= 12) { + a = fYear; + b = (a / 4) - (a / 100) + (a / 400); + int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); + s = b - c; + e = s + 1; + f = fDay + ((153 * (fMonth - 3) + 2) / 5) + 58 + s; + } else + return int32(B_ERROR); + + int32 g = (a + b) % 7; + int32 d = (f + g - e) % 7; + int32 n = f + 3 - d; + + int32 weekNumber; + if (n < 0) + weekNumber = 53 - (g -s) / 5; + else if (n > 364 + s) + weekNumber = 1; + else + weekNumber = n / 7 + 1; + + return weekNumber; +} + + +/*! + Returns the day of the week in the range of 1 to 7, while 1 stands for + monday. If the date is invalid, the function will return B_ERROR. +*/ +int32 +BDate::DayOfWeek() const +{ + // http://en.wikipedia.org/wiki/Julian_day#Calculation + return IsValid() ? (DateToJulianDay() % 7) + 1 : int32(B_ERROR); +} + + +/*! + Returns the day of the year in the range of 1 to 365 (366 in leap years). If + the date is invalid, the function will return B_ERROR. +*/ +int32 +BDate::DayOfYear() const +{ + if (!IsValid()) + return int32(B_ERROR); + + return DateToJulianDay() - _DateToJulianDay(fYear, 1, 1) + 1; +} + + +/*! + Returns true if the passed \c year is a leap year, otherwise false. If the + \c year passed is before 4713 BC, the result is undefined. +*/ +bool +BDate::IsLeapYear(int32 year) const +{ + if (year < 1582) { + if (year < 0) + year++; + return (year % 4) == 0; + } + return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0); +} + + +/*! + Returns the number of days in the year of the current date. If the date is + valid it will return 365 or 366, otherwise B_ERROR; +*/ +int32 +BDate::DaysInYear() const +{ + if (!IsValid()) + return int32(B_ERROR); + + return IsLeapYear(fYear) ? 366 : 365; +} + + +/*! + Returns the number of days in the month of the current date. If the date is + valid it will return 28 up to 31, otherwise B_ERROR; +*/ +int32 +BDate::DaysInMonth() const +{ + if (!IsValid()) + return int32(B_ERROR); + + return _DaysInMonth(fYear, fMonth); +} + + +/*! + Returns the short day name in case of an valid day, otherwise an empty + string. The passed \c day must be in the range of 1 to 7 while 1 stands for + monday. +*/ +BString +BDate::ShortDayName(int32 day) const +{ + if (day < 1 || day > 7) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_wday = day == 7 ? 0 : day; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%a", &tm_struct); + + return BString(buffer); +} + + +/*! + Returns the short month name in case of an valid month, otherwise an empty + string. The passed \c month must be in the range of 1 to 12. +*/ +BString +BDate::ShortMonthName(int32 month) const +{ + if (month < 1 || month > 12) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_mon = month - 1; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%b", &tm_struct); + + return BString(buffer); +} + + +/*! + Returns the long day name in case of an valid day, otherwise an empty + string. The passed \c day must be in the range of 1 to 7 while 1 stands for + monday. +*/ +BString +BDate::LongDayName(int32 day) const +{ + if (day < 1 || day > 7) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_wday = day == 7 ? 0 : day; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%A", &tm_struct); + + return BString(buffer); +} + + +/*! + Returns the long month name in case of an valid month, otherwise an empty + string. The passed \c month must be in the range of 1 to 12. +*/ +BString +BDate::LongMonthName(int32 month) const +{ + if (month < 1 || month > 12) + return BString(); + + tm tm_struct; + memset(&tm_struct, 0, sizeof(tm)); + tm_struct.tm_mon = month - 1; + + char buffer[256]; + strftime(buffer, sizeof(buffer), "%B", &tm_struct); + + return BString(buffer); +} + + +/*! + Converts the date to Julian day. If your date is invalid, the function will + return B_ERROR. +*/ +int32 +BDate::DateToJulianDay() const +{ + return _DateToJulianDay(fYear, fMonth, fDay); +} + + +/* + Converts the passed \c julianDay to an BDate. If the \c julianDay is negativ, + the function will return an invalid date. Because of the switch from Julian + calendar to Gregorian calendar the 4.10.1582 is followed by the 15.10.1582. +*/ +BDate +BDate::JulianDayToDate(int32 julianDay) +{ + BDate date; + const int32 kGregorianCalendarStart = 2299161; + if (julianDay >= kGregorianCalendarStart) { + // http://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number + int32 j = julianDay + 32044; + int32 dg = j % 146097; + int32 c = (dg / 36524 + 1) * 3 / 4; + int32 dc = dg - c * 36524; + int32 db = dc % 1461; + int32 a = (db / 365 + 1) * 3 / 4; + int32 da = db - a * 365; + int32 m = (da * 5 + 308) / 153 - 2; + date.fYear = ((j / 146097) * 400 + c * 100 + (dc / 1461) * 4 + a) - 4800 + + (m + 2) / 12; + date.fMonth = (m + 2) % 12 + 1; + date.fDay = int32((da - (m + 4) * 153 / 5 + 122) + 1.5); + } else if (julianDay >= 0) { + // http://en.wikipedia.org/wiki/Julian_day#Calculation + julianDay += 32082; + int32 d = (4 * julianDay + 3) / 1461; + int32 e = julianDay - (1461 * d) / 4; + int32 m = ((5 * e) + 2) / 153; + date.fDay = e - (153 * m + 2) / 5 + 1; + date.fMonth = m + 3 - 12 * (m / 10); + int32 year = d - 4800 + (m / 10); + if (year <= 0) + year--; + date.fYear = year; + } + return date; +} + + +/*! + Returns true if this date is different from \c date, otherwise false. +*/ +bool +BDate::operator!=(const BDate& date) const +{ + return DateToJulianDay() != date.DateToJulianDay(); +} + + +/*! + Returns true if this date is equal to \c date, otherwise false. +*/ +bool +BDate::operator==(const BDate& date) const +{ + return DateToJulianDay() == date.DateToJulianDay(); +} + + +/*! + Returns true if this date is earlier than \c date, otherwise false. +*/ +bool +BDate::operator<(const BDate& date) const +{ + return DateToJulianDay() < date.DateToJulianDay(); +} + + +/*! + Returns true if this date is earlier than or equal to \c date, otherwise false. +*/ +bool +BDate::operator<=(const BDate& date) const +{ + return DateToJulianDay() <= date.DateToJulianDay(); +} + + +/*! + Returns true if this date is later than \c date, otherwise false. +*/ +bool +BDate::operator>(const BDate& date) const +{ + return DateToJulianDay() > date.DateToJulianDay(); +} + + +/*! + Returns true if this date is later than or equal to \c date, otherwise false. +*/ +bool +BDate::operator>=(const BDate& date) const +{ + return DateToJulianDay() >= date.DateToJulianDay(); +} + + +bool +BDate::_SetDate(int32 year, int32 month, int32 day) +{ + fDay = -1; + fYear = 0; + fMonth = -1; + + bool valid = IsValid(year, month, day); + if (valid) { + fDay = day; + fYear = year; + fMonth = month; + } + + return valid; +} + + +int32 +BDate::_DaysInMonth(int32 year, int32 month) const +{ + if (month == 2 && IsLeapYear(year)) + return 29; + + const int32 daysInMonth[12] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + return daysInMonth[month -1]; +} + + +int32 +BDate::_DateToJulianDay(int32 _year, int32 month, int32 day) const +{ + if (IsValid(_year, month, day)) { + int32 year = _year; + if (year < 0) year++; + + int32 a = (14 - month) / 12; + int32 y = year + 4800 - a; + int32 m = month + (12 * a) - 3; + + // http://en.wikipedia.org/wiki/Julian_day#Calculation + if (year > 1582 + || (year == 1582 && month > 10) + || (year == 1582 && month == 10 && day >= 15)) { + return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - + (y / 100) + (y / 400) - 32045; + } else if (year < 1582 + || (year == 1582 && month < 10) + || (year == 1582 && month == 10 && day <= 4)) { + return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - 32083; + } + } + + // http://en.wikipedia.org/wiki/Gregorian_calendar: + // The last day of the Julian calendar was Thursday October 4, 1582 + // and this was followed by the first day of the Gregorian calendar, + // Friday October 15, 1582 (the cycle of weekdays was not affected). + return int32(B_ERROR); +} + + +// #pragma mark - BDateTime + + +/*! + Constructs a new BDateTime object. IsValid() will return false. +*/ +BDateTime::BDateTime() + : fDate(), + fTime() +{ +} + + +/*! + Constructs a BDateTime object with \c date and \c time. The return value + of IsValid() depends on the validity of the passed objects. +*/ +BDateTime::BDateTime(const BDate& date, const BTime& time) + : fDate(date), + fTime(time) +{ +} + + +/*! + Constructs a new BDateTime object. IsValid() will return false. +*/ +BDateTime::BDateTime(const BMessage* archive) + : fDate(archive), + fTime(archive) +{ +} + + +/*! + Empty destructor. +*/ +BDateTime::~BDateTime() +{ +} + + +/*! + Archives the BDateTime object into the provided BMessage object. + @returns \c B_OK if all went well. + \c B_BAD_VALUE, if the message is \c NULL. + \c other error codes, depending on failure to append + fields to the message. +*/ +status_t +BDateTime::Archive(BMessage* into) const +{ + status_t ret = fDate.Archive(into); + if (ret == B_OK) + ret = fTime.Archive(into); + return ret; +} + + +/*! + Returns true if the date time is valid, otherwise false. +*/ +bool +BDateTime::IsValid() const +{ + return fDate.IsValid() && fTime.IsValid(); +} + + +/*! + Returns the current date and time as reported by the system depending on the + given time_type \c type. +*/ +BDateTime +BDateTime::CurrentDateTime(time_type type) +{ + return BDateTime(BDate::CurrentDate(type), BTime::CurrentTime(type)); +} + + +/*! + Sets the current date and time of this object to \c date and \c time. +*/ +void +BDateTime::SetDateTime(const BDate& date, const BTime& time) +{ + fDate = date; + fTime = time; +} + + +/*! + Returns the current date of this object. +*/ +BDate +BDateTime::Date() const +{ + return fDate; +} + + +/*! + Set the current date of this object to \c date. +*/ +void +BDateTime::SetDate(const BDate& date) +{ + fDate = date; +} + + +/*! + Returns the current time of this object. +*/ +BTime +BDateTime::Time() const +{ + return fTime; +} + + +/*! + Sets the current time of this object to \c time. +*/ +void +BDateTime::SetTime(const BTime& time) +{ + fTime = time; +} + + +/*! + Returns the current date and time converted to seconds since + 1.1.1970 - 00:00:00. If the current date is before 1.1.1970 the function + returns -1; +*/ +int32 +BDateTime::Time_t() const +{ + BDate date(1970, 1, 1); + if (date.Difference(fDate) < 0) + return -1; + + tm tm_struct; + + tm_struct.tm_hour = fTime.Hour(); + tm_struct.tm_min = fTime.Minute(); + tm_struct.tm_sec = fTime.Second(); + + tm_struct.tm_year = fDate.Year() - 1900; + tm_struct.tm_mon = fDate.Month() - 1; + tm_struct.tm_mday = fDate.Day(); + + // set less 0 as we wan't use it + tm_struct.tm_isdst = -1; + + // return secs_since_jan1_1970 or -1 on error + return int32(mktime(&tm_struct)); +} + + +/*! + Sets the current date and time converted from seconds since + 1.1.1970 - 00:00:00. +*/ +void +BDateTime::SetTime_t(uint32 seconds) +{ + BTime time; + time.AddSeconds(seconds % kSecondsPerDay); + fTime.SetTime(time); + + BDate date(1970, 1, 1); + date.AddDays(seconds / kSecondsPerDay); + fDate.SetDate(date); +} + + +/*! + Returns true if this datetime is different from \c dateTime, otherwise false. +*/ +bool +BDateTime::operator!=(const BDateTime& dateTime) const +{ + return fTime != dateTime.fTime && fDate != dateTime.fDate; +} + + +/*! + Returns true if this datetime is equal to \c dateTime, otherwise false. +*/ +bool +BDateTime::operator==(const BDateTime& dateTime) const +{ + return fTime == dateTime.fTime && fDate == dateTime.fDate; +} + + +/*! + Returns true if this datetime is earlier than \c dateTime, otherwise false. +*/ +bool +BDateTime::operator<(const BDateTime& dateTime) const +{ + return fTime < dateTime.fTime && fDate < dateTime.fDate; +} + + +/*! + Returns true if this datetime is earlier than or equal to \c dateTime, + otherwise false. +*/ +bool +BDateTime::operator<=(const BDateTime& dateTime) const +{ + return fTime <= dateTime.fTime && fDate <= dateTime.fDate; +} + + +/*! + Returns true if this datetime is later than \c dateTime, otherwise false. +*/ +bool +BDateTime::operator>(const BDateTime& dateTime) const +{ + return fTime > dateTime.fTime && fDate > dateTime.fDate; +} + + +/*! + Returns true if this datetime is later than or equal to \c dateTime, + otherwise false. +*/ +bool +BDateTime::operator>=(const BDateTime& dateTime) const +{ + return fTime >= dateTime.fTime && fDate >= dateTime.fDate; +} + + +} //namespace BPrivate Copied: webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.h (from r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/DateTime.h Wed Mar 3 11:08:50 2010 (r278, copy of r252, webkit/trunk/WebKit/haiku/WebPositive/DateTime.h) @@ -0,0 +1,215 @@ +/* + * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _DATE_TIME_H_ +#define _DATE_TIME_H_ + + +#include <String.h> + + +class BMessage; + + +namespace BPrivate { + + +enum time_type { + B_GMT_TIME, + B_LOCAL_TIME +}; + + +enum diff_type { + B_HOURS_DIFF, + B_MINUTES_DIFF, + B_SECONDS_DIFF, + B_MILLISECONDS_DIFF, + B_MICROSECONDS_DIFF +}; + + +class BTime { +public: + BTime(); + BTime(int32 hour, int32 minute, int32 second, + int32 microsecond = 0); + BTime(const BMessage* archive); + ~BTime(); + + status_t Archive(BMessage* into) const; + + bool IsValid() const; + bool IsValid(const BTime& time) const; + bool IsValid(int32 hour, int32 minute, int32 second, + int32 microsecond = 0) const; + + static BTime CurrentTime(time_type type); + + BTime Time() const; + bool SetTime(const BTime& time); + bool SetTime(int32 hour, int32 minute, int32 second, + int32 microsecond = 0); + + void AddHours(int32 hours); + void AddMinutes(int32 minutes); + void AddSeconds(int32 seconds); + void AddMilliseconds(int32 milliseconds); + void AddMicroseconds(int32 microseconds); + + int32 Hour() const; + int32 Minute() const; + int32 Second() const; + int32 Millisecond() const; + int32 Microsecond() const; + bigtime_t Difference(const BTime& time, + diff_type type) const; + + bool operator!=(const BTime& time) const; + bool operator==(const BTime& time) const; + + bool operator<(const BTime& time) const; + bool operator<=(const BTime& time) const; + + bool operator>(const BTime& time) const; + bool operator>=(const BTime& time) const; + +private: + bigtime_t _Microseconds() const; + void _AddMicroseconds(bigtime_t microseconds); + bool _SetTime(bigtime_t hour, bigtime_t minute, + bigtime_t second, bigtime_t microsecond); + +private: + bigtime_t fMicroseconds; +}; + + +class BDate { +public: + BDate(); + BDate(int32 year, int32 month, int32 day); + BDate(const BMessage* archive); + ~BDate(); + + status_t Archive(BMessage* into) const; + + bool IsValid() const; + bool IsValid(const BDate& date) const; + bool IsValid(int32 year, int32 month, + int32 day) const; + + static BDate CurrentDate(time_type type); + + BDate Date() const; + bool SetDate(const BDate& date); + + bool SetDate(int32 year, int32 month, int32 day); + void GetDate(int32* year, int32* month, int32* day); + + void AddDays(int32 days); + void AddYears(int32 years); + void AddMonths(int32 months); + + int32 Day() const; + int32 Year() const; + int32 Month() const; + int32 Difference(const BDate& date) const; + + int32 DayOfWeek() const; + int32 DayOfYear() const; + + int32 WeekNumber() const; + bool IsLeapYear(int32 year) const; + + int32 DaysInYear() const; + int32 DaysInMonth() const; + + BString ShortDayName(int32 day) const; + BString ShortMonthName(int32 month) const; + + BString LongDayName(int32 day) const; + BString LongMonthName(int32 month) const; + + int32 DateToJulianDay() const; + static BDate JulianDayToDate(int32 julianDay); + + bool operator!=(const BDate& date) const; + bool operator==(const BDate& date) const; + + bool operator<(const BDate& date) const; + bool operator<=(const BDate& date) const; + + bool operator>(const BDate& date) const; + bool operator>=(const BDate& date) const; + +private: + int32 _DaysInMonth(int32 year, int32 month) const; + bool _SetDate(int32 year, int32 month, int32 day); + int32 _DateToJulianDay(int32 year, int32 month, + int32 day) const; + +private: + int32 fDay; + int32 fYear; + int32 fMonth; +}; + + +class BDateTime { +public: + BDateTime(); + BDateTime(const BDate &date, const BTime &time); + BDateTime(const BMessage* archive); + ~BDateTime(); + + status_t Archive(BMessage* into) const; + + bool IsValid() const; + + static BDateTime CurrentDateTime(time_type type); + void SetDateTime(const BDate &date, const BTime &time); + + BDate Date() const; + void SetDate(const BDate &date); + + BTime Time() const; + void SetTime(const BTime &time); + + int32 Time_t() const; + void SetTime_t(uint32 seconds); + + bool operator!=(const BDateTime& dateTime) const; + bool operator==(const BDateTime& dateTime) const; + + bool operator<(const BDateTime& dateTime) const; + bool operator<=(const BDateTime& dateTime) const; + + bool operator>(const BDateTime& dateTime) const; + bool operator>=(const BDateTime& dateTime) const; + +private: + BDate fDate; + BTime fTime; +}; + + +} // namespace BPrivate + + +using BPrivate::time_type; +using BPrivate::B_GMT_TIME; +using BPrivate::B_LOCAL_TIME; +using BPrivate::diff_type; +using BPrivate::B_HOURS_DIFF; +using BPrivate::B_MINUTES_DIFF; +using BPrivate::B_SECONDS_DIFF; +using BPrivate::B_MILLISECONDS_DIFF; +using BPrivate::B_MICROSECONDS_DIFF; +using BPrivate::BTime; +using BPrivate::BDate; +using BPrivate::BDateTime; + + +#endif // _DATE_TIME_H_ Copied: webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.cpp (from r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.cpp) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.cpp Wed Mar 3 11:08:50 2010 (r278, copy of r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.cpp) @@ -0,0 +1,929 @@ +/* + * Copyright 2006-2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus <superstippi@xxxxxx> + */ + +// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic +// it should be placed into a common folder for generic useful stuff + +#include "IconButton.h" + +#include <new> +#include <stdio.h> + +#include <Application.h> +#include <Bitmap.h> +#include <Control.h> +#include <ControlLook.h> +#include <Entry.h> +#include <Looper.h> +#include <Message.h> +#include <Mime.h> +#include <Path.h> +#include <Region.h> +#include <Resources.h> +#include <Roster.h> +#include <TranslationUtils.h> +#include <Window.h> +#include "IconUtils.h" + +using std::nothrow; + +// constructor +IconButton::IconButton(const char* name, uint32 id, const char* label, + BMessage* message, BHandler* target) + : BView(name, B_WILL_DRAW), + BInvoker(message, target), + fButtonState(STATE_ENABLED), + fID(id), + fNormalBitmap(NULL), + fDisabledBitmap(NULL), + fClickedBitmap(NULL), + fDisabledClickedBitmap(NULL), + fLabel(label), + fTargetCache(target) +{ + SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + SetViewColor(B_TRANSPARENT_32_BIT); +} + +// destructor +IconButton::~IconButton() +{ + _DeleteBitmaps(); +} + +// MessageReceived +void +IconButton::MessageReceived(BMessage* message) +{ + switch (message->what) { + default: + BView::MessageReceived(message); + break; + } +} + +// AttachedToWindow +void +IconButton::AttachedToWindow() +{ + rgb_color background = B_TRANSPARENT_COLOR; + if (BView* parent = Parent()) { + background = parent->ViewColor(); + if (background == B_TRANSPARENT_COLOR) + background = parent->LowColor(); + } + if (background == B_TRANSPARENT_COLOR) + background = ui_color(B_PANEL_BACKGROUND_COLOR); + SetLowColor(background); + + SetTarget(fTargetCache); + if (!Target()) + SetTarget(Window()); +} + +// Draw +void +IconButton::Draw(BRect area) +{ + rgb_color background = LowColor(); + + BRect r(Bounds()); + + if (be_control_look != NULL) { + uint32 flags = 0; + BBitmap* bitmap = fNormalBitmap; + if (!IsEnabled()) { + flags |= BControlLook::B_DISABLED; + bitmap = fDisabledBitmap; + } + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + flags |= BControlLook::B_ACTIVATED; + + if (DrawBorder()) { + be_control_look->DrawButtonFrame(this, r, area, background, + background, flags); + be_control_look->DrawButtonBackground(this, r, area, background, + flags); + } else { + SetHighColor(background); + FillRect(r); + } + + if (bitmap && bitmap->IsValid()) { + float x = r.left + floorf((r.Width() + - bitmap->Bounds().Width()) / 2.0 + 0.5); + float y = r.top + floorf((r.Height() + - bitmap->Bounds().Height()) / 2.0 + 0.5); + BPoint point(x, y); + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + point += BPoint(1.0, 1.0); + if (bitmap->ColorSpace() == B_RGBA32 + || bitmap->ColorSpace() == B_RGBA32_BIG) { + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + } + DrawBitmap(bitmap, point); + } + return; + } + + rgb_color lightShadow, shadow, darkShadow, light; + BBitmap* bitmap = fNormalBitmap; + // adjust colors and bitmap according to flags + if (IsEnabled()) { + lightShadow = tint_color(background, B_DARKEN_1_TINT); + shadow = tint_color(background, B_DARKEN_2_TINT); + darkShadow = tint_color(background, B_DARKEN_4_TINT); + light = tint_color(background, B_LIGHTEN_MAX_TINT); + SetHighColor(0, 0, 0, 255); + } else { + lightShadow = tint_color(background, 1.11); + shadow = tint_color(background, B_DARKEN_1_TINT); + darkShadow = tint_color(background, B_DARKEN_2_TINT); + light = tint_color(background, B_LIGHTEN_2_TINT); + bitmap = fDisabledBitmap; + SetHighColor(tint_color(background, B_DISABLED_LABEL_TINT)); + } + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) { + if (IsEnabled()) { +// background = tint_color(background, B_DARKEN_2_TINT); +// background = tint_color(background, B_LIGHTEN_1_TINT); + background = tint_color(background, B_DARKEN_1_TINT); + bitmap = fClickedBitmap; + } else { +// background = tint_color(background, B_DARKEN_1_TINT); +// background = tint_color(background, (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0); + background = tint_color(background, (B_NO_TINT + B_DARKEN_1_TINT) / 2.0); + bitmap = fDisabledClickedBitmap; + } + // background + SetLowColor(background); + r.InsetBy(2.0, 2.0); + StrokeLine(r.LeftBottom(), r.LeftTop(), B_SOLID_LOW); + StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_LOW); + r.InsetBy(-2.0, -2.0); + } + // draw frame only if tracking + if (DrawBorder()) { + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + DrawPressedBorder(r, background, shadow, darkShadow, lightShadow, light); + else + DrawNormalBorder(r, background, shadow, darkShadow, lightShadow, light); + r.InsetBy(2.0, 2.0); + } else + _DrawFrame(r, background, background, background, background); + float width = Bounds().Width(); + float height = Bounds().Height(); + // bitmap + BRegion originalClippingRegion; + if (bitmap && bitmap->IsValid()) { + float x = floorf((width - bitmap->Bounds().Width()) / 2.0 + 0.5); + float y = floorf((height - bitmap->Bounds().Height()) / 2.0 + 0.5); + BPoint point(x, y); + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + point += BPoint(1.0, 1.0); + if (bitmap->ColorSpace() == B_RGBA32 || bitmap->ColorSpace() == B_RGBA32_BIG) { + FillRect(r, B_SOLID_LOW); + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + } + DrawBitmap(bitmap, point); + // constrain clipping region + BRegion region= originalClippingRegion; + GetClippingRegion(®ion); + region.Exclude(bitmap->Bounds().OffsetByCopy(point)); + ConstrainClippingRegion(®ion); + } + // background + SetDrawingMode(B_OP_COPY); + FillRect(r, B_SOLID_LOW); + ConstrainClippingRegion(NULL); + // label + if (fLabel.CountChars() > 0) { + SetDrawingMode(B_OP_COPY); + font_height fh; + GetFontHeight(&fh); + float y = Bounds().bottom - 4.0; + y -= fh.descent; + float x = (width - StringWidth(fLabel.String())) / 2.0; + DrawString(fLabel.String(), BPoint(x, y)); + } +} + +// MouseDown +void +IconButton::MouseDown(BPoint where) +{ + if (!IsValid()) + return; + + if (_HasFlags(STATE_ENABLED)/* && !_HasFlags(STATE_FORCE_PRESSED)*/) { + if (Bounds().Contains(where)) { + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + _AddFlags(STATE_PRESSED | STATE_TRACKING); + } else { + _ClearFlags(STATE_PRESSED | STATE_TRACKING); + } + } +} + +// MouseUp +void +IconButton::MouseUp(BPoint where) +{ + if (!IsValid()) + return; + +// if (!_HasFlags(STATE_FORCE_PRESSED)) { + if (_HasFlags(STATE_ENABLED) && _HasFlags(STATE_PRESSED) && Bounds().Contains(where)) + Invoke(); + else if (Bounds().Contains(where)) + _AddFlags(STATE_INSIDE); + _ClearFlags(STATE_PRESSED | STATE_TRACKING); +// } +} + +// MouseMoved +void +IconButton::MouseMoved(BPoint where, uint32 transit, const BMessage* message) +{ + if (!IsValid()) + return; + + uint32 buttons = 0; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + // catch a mouse up event that we might have missed + if (!buttons && _HasFlags(STATE_PRESSED)) { + MouseUp(where); + return; + } + if (buttons && !_HasFlags(STATE_TRACKING)) + return; + if ((transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW) + && _HasFlags(STATE_ENABLED)) + _AddFlags(STATE_INSIDE); + else + _ClearFlags(STATE_INSIDE); + if (_HasFlags(STATE_TRACKING)) { + if (Bounds().Contains(where)) + _AddFlags(STATE_PRESSED); + else + _ClearFlags(STATE_PRESSED); + } +} + +#define MIN_SPACE 15.0 + +// GetPreferredSize +void +IconButton::GetPreferredSize(float* width, float* height) +{ + float minWidth = 0.0; + float minHeight = 0.0; + if (IsValid()) { + minWidth += fNormalBitmap->Bounds().IntegerWidth() + 1.0; + minHeight += fNormalBitmap->Bounds().IntegerHeight() + 1.0; + } + if (minWidth < MIN_SPACE) + minWidth = MIN_SPACE; + if (minHeight < MIN_SPACE) + minHeight = MIN_SPACE; + + float hPadding = max_c(6.0, ceilf(minHeight / 4.0)); + float vPadding = max_c(6.0, ceilf(minWidth / 4.0)); + + if (fLabel.CountChars() > 0) { + font_height fh; + GetFontHeight(&fh); + minHeight += ceilf(fh.ascent + fh.descent) + vPadding; + minWidth += StringWidth(fLabel.String()) + vPadding; + } + + if (width) + *width = minWidth + hPadding; + if (height) + *height = minHeight + vPadding; +} + +// MinSize +BSize +IconButton::MinSize() +{ + BSize size; + GetPreferredSize(&size.width, &size.height); + return size; +} + +// MaxSize +BSize +IconButton::MaxSize() +{ + return MinSize(); +} + +// Invoke +status_t +IconButton::Invoke(BMessage* message) +{ + if (!message) + message = Message(); + if (message) { + BMessage clone(*message); + clone.AddInt64("be:when", system_time()); + clone.AddPointer("be:source", (BView*)this); + clone.AddInt32("be:value", Value()); + clone.AddInt32("id", ID()); + return BInvoker::Invoke(&clone); + } + return BInvoker::Invoke(message); +} + +// SetPressed +void +IconButton::SetPressed(bool pressed) +{ + if (pressed) + _AddFlags(STATE_FORCE_PRESSED); + else + _ClearFlags(STATE_FORCE_PRESSED); +} + +// IsPressed +bool +IconButton::IsPressed() const +{ + return _HasFlags(STATE_FORCE_PRESSED); +} + +status_t +IconButton::SetIcon(int32 resourceID) +{ + app_info info; + status_t status = be_app->GetAppInfo(&info); + if (status != B_OK) + return status; + + BResources resources(&info.ref); + status = resources.InitCheck(); + if (status != B_OK) + return status; + + size_t size; + const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, + &size); + if (data != NULL) { + BBitmap bitmap(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_RGBA32); + status = bitmap.InitCheck(); + if (status != B_OK) + return status; + status = BIconUtils::GetVectorIcon(reinterpret_cast<const uint8*>(data), + size, &bitmap); + if (status != B_OK) + return status; + return SetIcon(&bitmap); + } +// const void* data = resources.LoadResource(B_BITMAP_TYPE, resourceID, &size); + return B_ERROR; +} + +// SetIcon +status_t +IconButton::SetIcon(const char* pathToBitmap) +{ + if (pathToBitmap == NULL) + return B_BAD_VALUE; + + status_t status = B_BAD_VALUE; + BBitmap* fileBitmap = NULL; + // try to load bitmap from either relative or absolute path + BEntry entry(pathToBitmap, true); + if (!entry.Exists()) { + app_info info; + status = be_app->GetAppInfo(&info); + if (status == B_OK) { + BEntry app_entry(&info.ref, true); + BPath path; + app_entry.GetPath(&path); + status = path.InitCheck(); + if (status == B_OK) { + status = path.GetParent(&path); + if (status == B_OK) { + status = path.Append(pathToBitmap, true); + if (status == B_OK) + fileBitmap = BTranslationUtils::GetBitmap(path.Path()); + else + printf("IconButton::SetIcon() - path.Append() failed: %s\n", strerror(status)); + } else + printf("IconButton::SetIcon() - path.GetParent() failed: %s\n", strerror(status)); + } else + printf("IconButton::SetIcon() - path.InitCheck() failed: %s\n", strerror(status)); + } else + printf("IconButton::SetIcon() - be_app->GetAppInfo() failed: %s\n", strerror(status)); + } else + fileBitmap = BTranslationUtils::GetBitmap(pathToBitmap); + if (fileBitmap) { + status = _MakeBitmaps(fileBitmap); + delete fileBitmap; + } else + status = B_ERROR; + return status; +} + +// SetIcon +status_t +IconButton::SetIcon(const BBitmap* bitmap) +{ + if (bitmap && bitmap->ColorSpace() == B_CMAP8) { + status_t status = bitmap->InitCheck(); + if (status >= B_OK) { + if (BBitmap* rgb32Bitmap = _ConvertToRGB32(bitmap)) { + status = _MakeBitmaps(rgb32Bitmap); + delete rgb32Bitmap; + } else + status = B_NO_MEMORY; + } + return status; + } else + return _MakeBitmaps(bitmap); +} + +// SetIcon +status_t +IconButton::SetIcon(const BMimeType* fileType, bool small) +{ + status_t status = fileType ? fileType->InitCheck() : B_BAD_VALUE; + if (status >= B_OK) { + BBitmap* mimeBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_CMAP8); + if (mimeBitmap && mimeBitmap->IsValid()) { + status = fileType->GetIcon(mimeBitmap, small ? B_MINI_ICON : B_LARGE_ICON); + if (status >= B_OK) { + if (BBitmap* bitmap = _ConvertToRGB32(mimeBitmap)) { + status = _MakeBitmaps(bitmap); + delete bitmap; + } else + printf("IconButton::SetIcon() - B_RGB32 bitmap is not valid\n"); + } else + printf("IconButton::SetIcon() - fileType->GetIcon() failed: %s\n", strerror(status)); + } else + printf("IconButton::SetIcon() - B_CMAP8 bitmap is not valid\n"); + delete mimeBitmap; + } else + printf("IconButton::SetIcon() - fileType is not valid: %s\n", strerror(status)); + return status; +} + +// SetIcon +status_t +IconButton::SetIcon(const unsigned char* bitsFromQuickRes, + uint32 width, uint32 height, color_space format, bool convertToBW) +{ + status_t status = B_BAD_VALUE; + if (bitsFromQuickRes && width > 0 && height > 0) { + BBitmap* quickResBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, width - 1.0, height - 1.0), format); + status = quickResBitmap ? quickResBitmap->InitCheck() : B_ERROR; + if (status >= B_OK) { + // It doesn't look right to copy BitsLength() bytes, but bitmaps + // exported from QuickRes still contain their padding, so it is alright. + memcpy(quickResBitmap->Bits(), bitsFromQuickRes, quickResBitmap->BitsLength()); + if (format != B_RGB32 && format != B_RGBA32 && format != B_RGB32_BIG && format != B_RGBA32_BIG) { + // colorspace needs conversion + BBitmap* bitmap = new(nothrow) BBitmap(quickResBitmap->Bounds(), B_RGB32, true); + if (bitmap && bitmap->IsValid()) { + BView* helper = new BView(bitmap->Bounds(), "helper", + B_FOLLOW_NONE, B_WILL_DRAW); + if (bitmap->Lock()) { + bitmap->AddChild(helper); + helper->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + helper->FillRect(helper->Bounds()); + helper->SetDrawingMode(B_OP_OVER); + helper->DrawBitmap(quickResBitmap, BPoint(0.0, 0.0)); + helper->Sync(); + bitmap->Unlock(); + } + status = _MakeBitmaps(bitmap); + } else + printf("IconButton::SetIcon() - B_RGB32 bitmap is not valid\n"); + delete bitmap; + } else { + // native colorspace (32 bits) + if (convertToBW) { + // convert to gray scale icon + uint8* bits = (uint8*)quickResBitmap->Bits(); + uint32 bpr = quickResBitmap->BytesPerRow(); + for (uint32 y = 0; y < height; y++) { + uint8* handle = bits; + uint8 gray; + for (uint32 x = 0; x < width; x++) { + gray = uint8((116 * handle[0] + 600 * handle[1] + 308 * handle[2]) / 1024); + handle[0] = gray; + handle[1] = gray; + handle[2] = gray; + handle += 4; + } + bits += bpr; + } + } + status = _MakeBitmaps(quickResBitmap); + } + } else + printf("IconButton::SetIcon() - error allocating bitmap: %s\n", strerror(status)); + delete quickResBitmap; + } + return status; +} + +// ClearIcon +void +IconButton::ClearIcon() +{ + _DeleteBitmaps(); + _Update(); +} + +void +IconButton::TrimIcon(bool keepAspect) +{ + if (fNormalBitmap == NULL) + return; + + uint8* bits = (uint8*)fNormalBitmap->Bits(); + uint32 bpr = fNormalBitmap->BytesPerRow(); + uint32 width = fNormalBitmap->Bounds().IntegerWidth() + 1; + uint32 height = fNormalBitmap->Bounds().IntegerHeight() + 1; + BRect trimmed(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); + for (uint32 y = 0; y < height; y++) { + uint8* b = bits + 3; + bool rowHasAlpha = false; + for (uint32 x = 0; x < width; x++) { + if (*b) { + rowHasAlpha = true; + if (x < trimmed.left) + trimmed.left = x; + if (x > trimmed.right) + trimmed.right = x; + } + b += 4; + } + if (rowHasAlpha) { + if (y < trimmed.top) + trimmed.top = y; + if (y > trimmed.bottom) + trimmed.bottom = y; + } + bits += bpr; + } + if (!trimmed.IsValid()) + return; + if (keepAspect) { + float minInset = trimmed.left; + minInset = min_c(minInset, trimmed.top); + minInset = min_c(minInset, fNormalBitmap->Bounds().right - trimmed.right); + minInset = min_c(minInset, fNormalBitmap->Bounds().bottom - trimmed.bottom); + trimmed = fNormalBitmap->Bounds().InsetByCopy(minInset, minInset); + } + trimmed = trimmed & fNormalBitmap->Bounds(); + BBitmap trimmedBitmap(trimmed.OffsetToCopy(B_ORIGIN), + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + bits = (uint8*)fNormalBitmap->Bits(); + bits += 4 * (int32)trimmed.left + bpr * (int32)trimmed.top; + uint8* dst = (uint8*)trimmedBitmap.Bits(); + uint32 trimmedWidth = trimmedBitmap.Bounds().IntegerWidth() + 1; + uint32 trimmedHeight = trimmedBitmap.Bounds().IntegerHeight() + 1; + uint32 trimmedBPR = trimmedBitmap.BytesPerRow(); + for (uint32 y = 0; y < trimmedHeight; y++) { + memcpy(dst, bits, trimmedWidth * 4); + dst += trimmedBPR; + bits += bpr; + } + SetIcon(&trimmedBitmap); +} + +// Bitmap +BBitmap* +IconButton::Bitmap() const +{ + BBitmap* bitmap = NULL; + if (fNormalBitmap && fNormalBitmap->IsValid()) { + bitmap = new(nothrow) BBitmap(fNormalBitmap); + if (bitmap->IsValid()) { + // TODO: remove this functionality when we use real transparent bitmaps + uint8* bits = (uint8*)bitmap->Bits(); + uint32 bpr = bitmap->BytesPerRow(); + uint32 width = bitmap->Bounds().IntegerWidth() + 1; + uint32 height = bitmap->Bounds().IntegerHeight() + 1; + color_space format = bitmap->ColorSpace(); + if (format == B_CMAP8) { + // replace gray with magic transparent index + } else if (format == B_RGB32) { + for (uint32 y = 0; y < height; y++) { + uint8* bitsHandle = bits; + for (uint32 x = 0; x < width; x++) { + if (bitsHandle[0] == 216 + && bitsHandle[1] == 216 + && bitsHandle[2] == 216) { + bitsHandle[3] = 0; // make this pixel completely transparent + } + bitsHandle += 4; + } + bits += bpr; + } + } + } else { + delete bitmap; + bitmap = NULL; + } + } + return bitmap; +} + +// DrawBorder +bool +IconButton::DrawBorder() const +{ + return ((IsEnabled() && (_HasFlags(STATE_INSIDE) + || _HasFlags(STATE_TRACKING))) || _HasFlags(STATE_FORCE_PRESSED)); +} + +// DrawNormalBorder +void +IconButton::DrawNormalBorder(BRect r, rgb_color background, + rgb_color shadow, rgb_color darkShadow, + rgb_color lightShadow, rgb_color light) +{ + _DrawFrame(r, shadow, darkShadow, light, lightShadow); +} + +// DrawPressedBorder +void +IconButton::DrawPressedBorder(BRect r, rgb_color background, + rgb_color shadow, rgb_color darkShadow, + rgb_color lightShadow, rgb_color light) +{ + _DrawFrame(r, shadow, light, darkShadow, background); +} + +// IsValid +bool +IconButton::IsValid() const +{ + return (fNormalBitmap && fDisabledBitmap && fClickedBitmap + && fDisabledClickedBitmap + && fNormalBitmap->IsValid() + && fDisabledBitmap->IsValid() + && fClickedBitmap->IsValid() + && fDisabledClickedBitmap->IsValid()); +} + +// Value +int32 +IconButton::Value() const +{ + return _HasFlags(STATE_PRESSED) ? B_CONTROL_ON : B_CONTROL_OFF; +} + +// SetValue +void +IconButton::SetValue(int32 value) +{ + if (value) + _AddFlags(STATE_PRESSED); + else + _ClearFlags(STATE_PRESSED); +} + +// IsEnabled +bool +IconButton::IsEnabled() const +{ + return _HasFlags(STATE_ENABLED) ? B_CONTROL_ON : B_CONTROL_OFF; +} + +// SetEnabled +void +IconButton::SetEnabled(bool enabled) +{ + if (enabled) + _AddFlags(STATE_ENABLED); + else + _ClearFlags(STATE_ENABLED | STATE_TRACKING | STATE_INSIDE); +} + +// _ConvertToRGB32 +BBitmap* +IconButton::_ConvertToRGB32(const BBitmap* bitmap) const +{ + BBitmap* convertedBitmap = new(nothrow) BBitmap(bitmap->Bounds(), + B_BITMAP_ACCEPTS_VIEWS, B_RGBA32); + if (convertedBitmap && convertedBitmap->IsValid()) { + memset(convertedBitmap->Bits(), 0, convertedBitmap->BitsLength()); + BView* helper = new BView(bitmap->Bounds(), "helper", + B_FOLLOW_NONE, B_WILL_DRAW); + if (convertedBitmap->Lock()) { + convertedBitmap->AddChild(helper); + helper->SetDrawingMode(B_OP_OVER); + helper->DrawBitmap(bitmap, BPoint(0.0, 0.0)); + helper->Sync(); + convertedBitmap->Unlock(); + } + } else { + delete convertedBitmap; + convertedBitmap = NULL; + } + return convertedBitmap; +} + +// _MakeBitmaps +status_t +IconButton::_MakeBitmaps(const BBitmap* bitmap) +{ + status_t status = bitmap ? bitmap->InitCheck() : B_BAD_VALUE; + if (status >= B_OK) { + // make our own versions of the bitmap + BRect b(bitmap->Bounds()); + _DeleteBitmaps(); + color_space format = bitmap->ColorSpace(); + fNormalBitmap = new(nothrow) BBitmap(b, format); + fDisabledBitmap = new(nothrow) BBitmap(b, format); + fClickedBitmap = new(nothrow) BBitmap(b, format); + fDisabledClickedBitmap = new(nothrow) BBitmap(b, format); + if (IsValid()) { + // copy bitmaps from file bitmap + uint8* nBits = (uint8*)fNormalBitmap->Bits(); + uint8* dBits = (uint8*)fDisabledBitmap->Bits(); + uint8* cBits = (uint8*)fClickedBitmap->Bits(); + uint8* dcBits = (uint8*)fDisabledClickedBitmap->Bits(); + uint8* fBits = (uint8*)bitmap->Bits(); + int32 nbpr = fNormalBitmap->BytesPerRow(); + int32 fbpr = bitmap->BytesPerRow(); + int32 pixels = b.IntegerWidth() + 1; + int32 lines = b.IntegerHeight() + 1; + // nontransparent version: + if (format == B_RGB32 || format == B_RGB32_BIG) { + // iterate over color components + for (int32 y = 0; y < lines; y++) { + for (int32 x = 0; x < pixels; x++) { + int32 nOffset = 4 * x; + int32 fOffset = 4 * x; + nBits[nOffset + 0] = fBits[fOffset + 0]; + nBits[nOffset + 1] = fBits[fOffset + 1]; + nBits[nOffset + 2] = fBits[fOffset + 2]; + nBits[nOffset + 3] = 255; + // clicked bits are darker (lame method...) + cBits[nOffset + 0] = (uint8)((float)nBits[nOffset + 0] * 0.8); + cBits[nOffset + 1] = (uint8)((float)nBits[nOffset + 1] * 0.8); + cBits[nOffset + 2] = (uint8)((float)nBits[nOffset + 2] * 0.8); + cBits[nOffset + 3] = 255; + // disabled bits have less contrast (lame method...) + uint8 grey = 216; + float dist = (nBits[nOffset + 0] - grey) * 0.4; + dBits[nOffset + 0] = (uint8)(grey + dist); + dist = (nBits[nOffset + 1] - grey) * 0.4; + dBits[nOffset + 1] = (uint8)(grey + dist); + dist = (nBits[nOffset + 2] - grey) * 0.4; + dBits[nOffset + 2] = (uint8)(grey + dist); + dBits[nOffset + 3] = 255; + // disabled bits have less contrast (lame method...) + grey = 188; + dist = (nBits[nOffset + 0] - grey) * 0.4; + dcBits[nOffset + 0] = (uint8)(grey + dist); + dist = (nBits[nOffset + 1] - grey) * 0.4; + dcBits[nOffset + 1] = (uint8)(grey + dist); + dist = (nBits[nOffset + 2] - grey) * 0.4; + dcBits[nOffset + 2] = (uint8)(grey + dist); + dcBits[nOffset + 3] = 255; + } + nBits += nbpr; + dBits += nbpr; + cBits += nbpr; + dcBits += nbpr; + fBits += fbpr; + } + // transparent version: + } else if (format == B_RGBA32 || format == B_RGBA32_BIG) { + // iterate over color components + for (int32 y = 0; y < lines; y++) { + for (int32 x = 0; x < pixels; x++) { + int32 nOffset = 4 * x; + int32 fOffset = 4 * x; + nBits[nOffset + 0] = fBits[fOffset + 0]; + nBits[nOffset + 1] = fBits[fOffset + 1]; + nBits[nOffset + 2] = fBits[fOffset + 2]; + nBits[nOffset + 3] = fBits[fOffset + 3]; + // clicked bits are darker (lame method...) + cBits[nOffset + 0] = (uint8)(nBits[nOffset + 0] * 0.8); + cBits[nOffset + 1] = (uint8)(nBits[nOffset + 1] * 0.8); + cBits[nOffset + 2] = (uint8)(nBits[nOffset + 2] * 0.8); + cBits[nOffset + 3] = fBits[fOffset + 3]; + // disabled bits have less opacity + + uint8 grey = ((uint16)nBits[nOffset + 0] * 10 + + nBits[nOffset + 1] * 60 + + nBits[nOffset + 2] * 30) / 100; + float dist = (nBits[nOffset + 0] - grey) * 0.3; + dBits[nOffset + 0] = (uint8)(grey + dist); + dist = (nBits[nOffset + 1] - grey) * 0.3; + dBits[nOffset + 1] = (uint8)(grey + dist); + dist = (nBits[nOffset + 2] - grey) * 0.3; + dBits[nOffset + 2] = (uint8)(grey + dist); + dBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); + // disabled bits have less contrast (lame method...) + dcBits[nOffset + 0] = (uint8)(dBits[nOffset + 0] * 0.8); + dcBits[nOffset + 1] = (uint8)(dBits[nOffset + 1] * 0.8); + dcBits[nOffset + 2] = (uint8)(dBits[nOffset + 2] * 0.8); + dcBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); + } + nBits += nbpr; + dBits += nbpr; + cBits += nbpr; + dcBits += nbpr; + fBits += fbpr; + } + // unsupported format + } else { + printf("IconButton::_MakeBitmaps() - bitmap has unsupported colorspace\n"); + status = B_MISMATCHED_VALUES; + _DeleteBitmaps(); + } + } else { + printf("IconButton::_MakeBitmaps() - error allocating local bitmaps\n"); + status = B_NO_MEMORY; + _DeleteBitmaps(); + } + } else + printf("IconButton::_MakeBitmaps() - bitmap is not valid\n"); + return status; +} + +// _DeleteBitmaps +void +IconButton::_DeleteBitmaps() +{ + delete fNormalBitmap; + fNormalBitmap = NULL; + delete fDisabledBitmap; + fDisabledBitmap = NULL; + delete fClickedBitmap; + fClickedBitmap = NULL; + delete fDisabledClickedBitmap; + fDisabledClickedBitmap = NULL; +} + +// _Update +void +IconButton::_Update() +{ + if (LockLooper()) { + Invalidate(); + UnlockLooper(); + } +} + +// _AddFlags +void +IconButton::_AddFlags(uint32 flags) +{ + if (!(fButtonState & flags)) { + fButtonState |= flags; + _Update(); + } +} + +// _ClearFlags +void +IconButton::_ClearFlags(uint32 flags) +{ + if (fButtonState & flags) { + fButtonState &= ~flags; + _Update(); + } +} + +// _HasFlags +bool +IconButton::_HasFlags(uint32 flags) const +{ + return (fButtonState & flags); +} + +// _DrawFrame +void +IconButton::_DrawFrame(BRect r, rgb_color col1, rgb_color col2, + rgb_color col3, rgb_color col4) +{ + BeginLineArray(8); + AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col1); + AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col1); + AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col2); + AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col2); + r.InsetBy(1.0, 1.0); + AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col3); + AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col3); + AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col4); + AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col4); + EndLineArray(); +} Copied: webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.h (from r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/IconButton.h Wed Mar 3 11:08:50 2010 (r278, copy of r252, webkit/trunk/WebKit/haiku/WebPositive/IconButton.h) @@ -0,0 +1,134 @@ +/* + * Copyright 2006-2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus <superstippi@xxxxxx> + */ + +/** gui class that loads an image from disk and shows it + as clickable button */ + +// TODO: inherit from BControl? + +// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic +// it should be placed into a common folder for generic useful stuff + +#ifndef ICON_BUTTON_H +#define ICON_BUTTON_H + +#include <Invoker.h> +#include <String.h> +#include <View.h> + +class BBitmap; +class BMimeType; + +class IconButton : public BView, public BInvoker { +public: + IconButton(const char* name, + uint32 id, + const char* label = NULL, + BMessage* message = NULL, + BHandler* target = NULL); + virtual ~IconButton(); + + // BView interface + virtual void MessageReceived(BMessage* message); + virtual void AttachedToWindow(); + virtual void Draw(BRect updateRect); + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* message); + virtual void GetPreferredSize(float* width, + float* height); + virtual BSize MinSize(); + virtual BSize MaxSize(); + + + // BInvoker interface + virtual status_t Invoke(BMessage* message = NULL); + + // IconButton + bool IsValid() const; + + virtual int32 Value() const; + virtual void SetValue(int32 value); + + bool IsEnabled() const; + void SetEnabled(bool enable); + + void SetPressed(bool pressed); + bool IsPressed() const; + uint32 ID() const + { return fID; } + + status_t SetIcon(int32 resourceID); + status_t SetIcon(const char* pathToBitmap); + status_t SetIcon(const BBitmap* bitmap); + status_t SetIcon(const BMimeType* fileType, + bool small = true); + status_t SetIcon(const unsigned char* bitsFromQuickRes, + uint32 width, uint32 height, + color_space format, + bool convertToBW = false); + void ClearIcon(); + void TrimIcon(bool keepAspect = true); + + BBitmap* Bitmap() const; + // caller has to delete the returned bitmap + + virtual bool DrawBorder() const; + virtual void DrawNormalBorder(BRect r, + rgb_color background, + rgb_color shadow, + rgb_color darkShadow, + rgb_color lightShadow, + rgb_color light); + virtual void DrawPressedBorder(BRect r, + rgb_color background, + rgb_color shadow, + rgb_color darkShadow, + rgb_color lightShadow, + rgb_color light); + +protected: + enum { + STATE_NONE = 0x0000, + STATE_TRACKING = 0x0001, + STATE_PRESSED = 0x0002, + STATE_ENABLED = 0x0004, + STATE_INSIDE = 0x0008, + STATE_FORCE_PRESSED = 0x0010, + }; + + void _AddFlags(uint32 flags); + void _ClearFlags(uint32 flags); + bool _HasFlags(uint32 flags) const; + + void _DrawFrame(BRect frame, + rgb_color col1, + rgb_color col2, + rgb_color col3, + rgb_color col4); + +// private: + BBitmap* _ConvertToRGB32(const BBitmap* bitmap) const; + status_t _MakeBitmaps(const BBitmap* bitmap); + void _DeleteBitmaps(); + void _SendMessage() const; + void _Update(); + + uint32 fButtonState; + int32 fID; + BBitmap* fNormalBitmap; + BBitmap* fDisabledBitmap; + BBitmap* fClickedBitmap; + BBitmap* fDisabledClickedBitmap; + BString fLabel; + + BHandler* fTargetCache; +}; + +#endif // ICON_BUTTON_H Copied: webkit/trunk/WebKit/haiku/WebPositive/support/IconUtils.h (from r252, webkit/trunk/WebKit/haiku/WebPositive/IconUtils.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/IconUtils.h Wed Mar 3 11:08:50 2010 (r278, copy of r252, webkit/trunk/WebKit/haiku/WebPositive/IconUtils.h) @@ -0,0 +1,80 @@ +/* + * Copyright 2006-2008, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _ICON_UTILS_H +#define _ICON_UTILS_H + + +#include <Mime.h> + +class BBitmap; +class BNode; + + +// This class is a little different from many other classes. +// You don't create an instance of it; you just call its various +// static member functions for utility-like operations. +class BIconUtils { + BIconUtils(); + ~BIconUtils(); + BIconUtils(const BIconUtils&); + BIconUtils& operator=(const BIconUtils&); + +public: + + // Utility function to import an icon from the node that + // has either of the provided attribute names. Which icon type + // is preferred (vector, small or large B_CMAP8 icon) depends + // on the colorspace of the provided bitmap. If the colorspace + // is B_CMAP8, B_CMAP8 icons are preferred. In that case, the + // bitmap size must also match the provided icon_size "size"! + static status_t GetIcon(BNode* node, + const char* vectorIconAttrName, + const char* smallIconAttrName, + const char* largeIconAttrName, + icon_size size, BBitmap* result); + + // Utility functions to import a vector icon in "flat icon" + // format from a BNode attribute or from a flat buffer in + // memory into the preallocated BBitmap "result". + // The colorspace of result needs to be B_RGBA32 or at + // least B_RGB32 (though that makes less sense). The icon + // will be scaled from it's "native" size of 64x64 to the + // size of the bitmap, the scale is derived from the bitmap + // width, the bitmap should have square dimension, or the + // icon will be cut off at the bottom (or have room left). + static status_t GetVectorIcon(BNode* node, + const char* attrName, BBitmap* result); + + static status_t GetVectorIcon(const uint8* buffer, + size_t size, BBitmap* result); + + // Utility function to import an "old" BeOS icon in B_CMAP8 + // colorspace from either the small icon attribute or the + // large icon attribute as given in "smallIconAttrName" and + // "largeIconAttrName". Which icon is loaded depends on + // the given "size". + static status_t GetCMAP8Icon(BNode* node, + const char* smallIconAttrName, + const char* largeIconAttrName, + icon_size size, BBitmap* icon); + + // Utility functions to convert from old icon colorspace + // into colorspace of BBitmap "result" (should be B_RGBA32 + // to make any sense). + static status_t ConvertFromCMAP8(BBitmap* source, + BBitmap* result); + static status_t ConvertToCMAP8(BBitmap* source, + BBitmap* result); + + static status_t ConvertFromCMAP8(const uint8* data, + uint32 width, uint32 height, + uint32 bytesPerRow, BBitmap* result); + + static status_t ConvertToCMAP8(const uint8* data, + uint32 width, uint32 height, + uint32 bytesPerRow, BBitmap* result); +}; + +#endif // _ICON_UTILS_H Added: webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.cpp Wed Mar 3 11:08:50 2010 (r278) @@ -0,0 +1,336 @@ +/* + * Copyright 2008, Stephan Aßmus <superstippi@xxxxxx>. + * Copyright 1998, Eric Shepherd. + * All rights reserved. Distributed under the terms of the Be Sample Code + * license. + */ + +//! Be Newsletter Volume II, Issue 35; September 2, 1998 (Eric Shepherd) + +#include "SettingsMessage.h" + +#include <Entry.h> +#include <File.h> +#include <String.h> + + +SettingsMessage::SettingsMessage(directory_which directory, + const char* filename) + : BMessage('pref') +{ + fStatus = find_directory(directory, &fPath); + + if (fStatus == B_OK) + fStatus = fPath.Append(filename); + + if (fStatus == B_OK) + fStatus = Load(); +} + + +SettingsMessage::~SettingsMessage() +{ + Save(); +} + + +status_t +SettingsMessage::InitCheck() const +{ + return fStatus; +} + + +status_t +SettingsMessage::Load() +{ + BFile file(fPath.Path(), B_READ_ONLY); + status_t status = file.InitCheck(); + + if (status == B_OK) + status = Unflatten(&file); + + return status; +} + + +status_t +SettingsMessage::Save() const +{ + BFile file(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + status_t status = file.InitCheck(); + + if (status == B_OK) + status = Flatten(&file); + + return status; +} + + +// #pragma mark - + + +status_t +SettingsMessage::SetValue(const char* name, bool value) +{ + if (ReplaceBool(name, value) == B_OK) + return B_OK; + return AddBool(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, int8 value) +{ + if (ReplaceInt8(name, value) == B_OK) + return B_OK; + return AddInt8(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, int16 value) +{ + if (ReplaceInt16(name, value) == B_OK) + return B_OK; + return AddInt16(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, int32 value) +{ + if (ReplaceInt32(name, value) == B_OK) + return B_OK; + return AddInt32(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, uint32 value) +{ + if (ReplaceInt32(name, (int32)value) == B_OK) + return B_OK; + return AddInt32(name, (int32)value); +} + + +status_t +SettingsMessage::SetValue(const char* name, int64 value) +{ + if (ReplaceInt64(name, value) == B_OK) + return B_OK; + return AddInt64(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, float value) +{ + if (ReplaceFloat(name, value) == B_OK) + return B_OK; + return AddFloat(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, double value) +{ + if (ReplaceDouble(name, value) == B_OK) + return B_OK; + return AddDouble(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const char* value) +{ + if (ReplaceString(name, value) == B_OK) + return B_OK; + return AddString(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const BString& value) +{ + return SetValue(name, value.String()); +} + + +status_t +SettingsMessage::SetValue(const char* name, const BPoint& value) +{ + if (ReplacePoint(name, value) == B_OK) + return B_OK; + return AddPoint(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const BRect& value) +{ + if (ReplaceRect(name, value) == B_OK) + return B_OK; + return AddRect(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const entry_ref& value) +{ + if (ReplaceRef(name, &value) == B_OK) + return B_OK; + return AddRef(name, &value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const BMessage* value) +{ + if (ReplaceMessage(name, value) == B_OK) + return B_OK; + return AddMessage(name, value); +} + + +status_t +SettingsMessage::SetValue(const char* name, const BFlattenable* value) +{ + if (ReplaceFlat(name, const_cast<BFlattenable*>(value)) == B_OK) + return B_OK; + return AddFlat(name, const_cast<BFlattenable*>(value)); +} + + +// #pragma mark - + +bool +SettingsMessage::GetValue(const char* name, bool defaultValue) const +{ + bool value; + if (FindBool(name, &value) != B_OK) + return defaultValue; + return value; +} + + +int8 +SettingsMessage::GetValue(const char* name, int8 defaultValue) const +{ + int8 value; + if (FindInt8(name, &value) != B_OK) + return defaultValue; + return value; +} + + +int16 +SettingsMessage::GetValue(const char* name, int16 defaultValue) const +{ + int16 value; + if (FindInt16(name, &value) != B_OK) + return defaultValue; + return value; +} + + +int32 +SettingsMessage::GetValue(const char* name, int32 defaultValue) const +{ + int32 value; + if (FindInt32(name, &value) != B_OK) + return defaultValue; + return value; +} + + +uint32 +SettingsMessage::GetValue(const char* name, uint32 defaultValue) const +{ + int32 value; + if (FindInt32(name, &value) != B_OK) + return defaultValue; + return (uint32)value; +} + + +int64 +SettingsMessage::GetValue(const char* name, int64 defaultValue) const +{ + int64 value; + if (FindInt64(name, &value) != B_OK) + return defaultValue; + return value; +} + + +float +SettingsMessage::GetValue(const char* name, float defaultValue) const +{ + float value; + if (FindFloat(name, &value) != B_OK) + return defaultValue; + return value; +} + + +double +SettingsMessage::GetValue(const char* name, double defaultValue) const +{ + double value; + if (FindDouble(name, &value) != B_OK) + return defaultValue; + return value; +} + + +BString +SettingsMessage::GetValue(const char* name, const BString& defaultValue) const +{ + BString value; + if (FindString(name, &value) != B_OK) + return defaultValue; + return value; +} + + +BPoint +SettingsMessage::GetValue(const char *name, BPoint defaultValue) const +{ + BPoint value; + if (FindPoint(name, &value) != B_OK) + return defaultValue; + return value; +} + + +BRect +SettingsMessage::GetValue(const char* name, BRect defaultValue) const +{ + BRect value; + if (FindRect(name, &value) != B_OK) + return defaultValue; + return value; +} + + +entry_ref +SettingsMessage::GetValue(const char* name, const entry_ref& defaultValue) const +{ + entry_ref value; + if (FindRef(name, &value) != B_OK) + return defaultValue; + return value; +} + + +BMessage +SettingsMessage::GetValue(const char* name, const BMessage& defaultValue) const +{ + BMessage value; + if (FindMessage(name, &value) != B_OK) + return defaultValue; + return value; +} + Added: webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ webkit/trunk/WebKit/haiku/WebPositive/support/SettingsMessage.h Wed Mar 3 11:08:50 2010 (r278) @@ -0,0 +1,79 @@ +/* + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx>. + * Copyright 1998 Eric Shepherd. + * All rights reserved. Distributed under the terms of the Be Sample Code + * license. + */ +#ifndef SETTINGS_MESSAGE_H +#define SETTINGS_MESSAGE_H + +#include <FindDirectory.h> +#include <Message.h> +#include <Path.h> + +class BString; + +class SettingsMessage : public BMessage { +public: + SettingsMessage(directory_which directory, + const char* filename); + virtual ~SettingsMessage(); + + + status_t InitCheck() const; + status_t Load(); + status_t Save() const; + + status_t SetValue(const char* name, bool value); + status_t SetValue(const char* name, int8 value); + status_t SetValue(const char* name, int16 value); + status_t SetValue(const char* name, int32 value); + status_t SetValue(const char* name, uint32 value); + status_t SetValue(const char* name, int64 value); + status_t SetValue(const char* name, float value); + status_t SetValue(const char* name, double value); + status_t SetValue(const char* name, + const char* value); + status_t SetValue(const char* name, + const BString& value); + status_t SetValue(const char *name, const BPoint& value); + status_t SetValue(const char* name, const BRect& value); + status_t SetValue(const char* name, const entry_ref& value); + status_t SetValue(const char* name, + const BMessage* value); + status_t SetValue(const char* name, + const BFlattenable* value); + + bool GetValue(const char* name, + bool defaultValue) const; + int8 GetValue(const char* name, + int8 defaultValue) const; + int16 GetValue(const char* name, + int16 defaultValue) const; + int32 GetValue(const char* name, + int32 defaultValue) const; + uint32 GetValue(const char* name, + uint32 defaultValue) const; + int64 GetValue(const char* name, + int64 defaultValue) const; + float GetValue(const char* name, + float defaultValue) const; + double GetValue(const char* name, + double defaultValue) const; + BString GetValue(const char* name, + const BString& defaultValue) const; + BPoint GetValue(const char *name, + BPoint defaultValue) const; + BRect GetValue(const char* name, + BRect defaultValue) const; + entry_ref GetValue(const char* name, + const entry_ref& defaultValue) const; + BMessage GetValue(const char* name, + const BMessage& defaultValue) const; + +private: + BPath fPath; + status_t fStatus; +}; + +#endif // SETTINGS_MESSAGE_H