voice messages and shared contacts redesigned (contacts not realtime-updated yet)

This commit is contained in:
John Preston 2015-12-13 01:29:33 +03:00
parent 603fb63c91
commit 2225abec5c
15 changed files with 721 additions and 383 deletions

View File

@ -1186,12 +1186,13 @@ mediaInUnreadFg: #999;
mediaInUnreadFgSelected: #7b95aa;
mediaOutUnreadFg: #6aad60;
mediaOutUnreadFgSelected: #5aa382;
mediaUnreadSize: 4px;
mediaUnreadSize: 7px;
mediaUnreadSkip: 5px;
mediaUnreadTop: 6px;
msgFileMenuSize: size(36px, 36px);
msgFileSize: 44px;
msgFilePadding: margins(14px, 12px, 10px, 12px);
msgFilePadding: margins(14px, 12px, 11px, 12px);
msgFileThumbSize: 72px;
msgFileThumbPadding: margins(10px, 10px, 14px, 10px);
msgFileThumbNameTop: 12px;

View File

@ -73,12 +73,11 @@ namespace {
AudioItems audioItems;
DocumentItems documentItems;
WebPageItems webPageItems;
SharedContactItems sharedContactItems;
typedef QMap<HistoryItem*, QMap<HistoryReply*, bool> > RepliesTo;
RepliesTo repliesTo;
typedef QMap<int32, QString> SharedContactPhones;
SharedContactPhones sharedContactPhones;
Histories histories;
typedef QHash<MsgId, HistoryItem*> MsgsData;
@ -1997,7 +1996,7 @@ namespace App {
::audioItems.clear();
::documentItems.clear();
::webPageItems.clear();
::sharedContactPhones.clear();
::sharedContactItems.clear();
::repliesTo.clear();
lastPhotos.clear();
lastPhotosMap.clear();
@ -2373,7 +2372,7 @@ namespace App {
}
void regVideoItem(VideoData *data, HistoryItem *item) {
::videoItems[data][item] = true;
::videoItems[data].insert(item, NullType());
}
void unregVideoItem(VideoData *data, HistoryItem *item) {
@ -2385,7 +2384,7 @@ namespace App {
}
void regAudioItem(AudioData *data, HistoryItem *item) {
::audioItems[data][item] = true;
::audioItems[data].insert(item, NullType());
}
void unregAudioItem(AudioData*data, HistoryItem *item) {
@ -2397,7 +2396,7 @@ namespace App {
}
void regDocumentItem(DocumentData *data, HistoryItem *item) {
::documentItems[data][item] = true;
::documentItems[data].insert(item, NullType());
}
void unregDocumentItem(DocumentData *data, HistoryItem *item) {
@ -2409,7 +2408,7 @@ namespace App {
}
void regWebPageItem(WebPageData *data, HistoryItem *item) {
::webPageItems[data][item] = true;
::webPageItems[data].insert(item, NullType());
}
void unregWebPageItem(WebPageData *data, HistoryItem *item) {
@ -2420,12 +2419,27 @@ namespace App {
return ::webPageItems;
}
void regSharedContactPhone(int32 userId, const QString &phone) {
::sharedContactPhones[userId] = phone;
void regSharedContactItem(int32 userId, HistoryItem *item) {
::sharedContactItems[userId].insert(item, NullType());
}
void unregSharedContactItem(int32 userId, HistoryItem *item) {
::sharedContactItems[userId].remove(item);
}
const SharedContactItems &sharedContactItems() {
return ::sharedContactItems;
}
QString phoneFromSharedContact(int32 userId) {
return ::sharedContactPhones.value(userId);
SharedContactItems::const_iterator i = ::sharedContactItems.constFind(userId);
if (i != ::sharedContactItems.cend()) {
HistoryMedia *media = i->cbegin().key()->getMedia();
if (media && media->type() == MediaTypeContact) {
return static_cast<HistoryContact*>(media)->phone();
}
}
return QString();
}
void regMuted(PeerData *peer, int32 changeIn) {

View File

@ -33,11 +33,12 @@ class FileUploader;
#include "history.h"
typedef QMap<HistoryItem*, bool> HistoryItemsMap;
typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
typedef QMap<VideoData*, HistoryItemsMap> VideoItems;
typedef QMap<AudioData*, HistoryItemsMap> AudioItems;
typedef QMap<DocumentData*, HistoryItemsMap> DocumentItems;
typedef QMap<WebPageData*, HistoryItemsMap> WebPageItems;
typedef QMap<int32, HistoryItemsMap> SharedContactItems;
struct ReplyMarkup {
ReplyMarkup(int32 flags = 0) : flags(flags) {
}
@ -244,7 +245,9 @@ namespace App {
void unregWebPageItem(WebPageData *data, HistoryItem *item);
const WebPageItems &webPageItems();
void regSharedContactPhone(int32 userId, const QString &phone);
void regSharedContactItem(int32 userId, HistoryItem *item);
void unregSharedContactItem(int32 userId, HistoryItem *item);
const SharedContactItems &sharedContactItems();
QString phoneFromSharedContact(int32 userId);
void regMuted(PeerData *peer, int32 changeIn);

View File

@ -91,6 +91,10 @@ namespace Ui {
return false;
}
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) {
if (MainWidget *m = App::main()) m->showPeerHistory(peer, msgId, back);
}
}
namespace Notify {
@ -111,4 +115,8 @@ namespace Notify {
if (MainWidget *m = App::main()) m->notify_redrawHistoryItem(item);
}
void historyItemLayoutChanged(const HistoryItem *item) {
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
}
}

View File

@ -46,6 +46,8 @@ namespace Ui { // it doesn't allow me to use UI :(
void hideLayer(bool fast = false);
bool isLayerShown();
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false);
};
namespace Notify {
@ -54,5 +56,6 @@ namespace Notify {
void botCommandsChanged(UserData *user);
void migrateUpdated(PeerData *peer);
void redrawHistoryItem(const HistoryItem *item);
void historyItemLayoutChanged(const HistoryItem *item);
};

File diff suppressed because it is too large Load Diff

View File

@ -1132,6 +1132,11 @@ public:
void update(float64 prg, bool finished, uint64 ms);
void stop();
void step(uint64 ms);
void step() {
step(getms());
}
void draw(Painter &p, const QRect &inner, const style::color &color);
private:
@ -1139,7 +1144,7 @@ private:
int32 _thickness;
uint64 _firstStart, _lastStart, _lastTime;
float64 _opacity;
anim::fvalue a_arcEnd, a_arcStart;
anim::ivalue a_arcEnd, a_arcStart;
Animation _animation;
};
@ -1147,7 +1152,7 @@ private:
class HistoryMedia : public HistoryElem {
public:
HistoryMedia(int32 width = 0) : w(width) {
HistoryMedia() : w(0) {
}
HistoryMedia(const HistoryMedia &other) : w(0) {
}
@ -1184,7 +1189,7 @@ public:
virtual void unregItem(HistoryItem *item) {
}
virtual void updateFrom(const MTPMessageMedia &media) {
virtual void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize) {
}
virtual bool isImageLink() const {
@ -1247,7 +1252,7 @@ public:
return _data;
}
void updateFrom(const MTPMessageMedia &media);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
TextLinkPtr lnk() const {
return _openl;
@ -1353,7 +1358,63 @@ private:
mutable int32 _dldDone, _uplDone;
};
class HistoryAudio : public HistoryMedia {
class HistoryFileMedia : public HistoryMedia {
public:
HistoryFileMedia();
void linkOver(HistoryItem *parent, const TextLinkPtr &lnk);
void linkOut(HistoryItem *parent, const TextLinkPtr &lnk);
~HistoryFileMedia();
protected:
TextLinkPtr _openl, _savel, _cancell;
void setLinks(ITextLink *openl, ITextLink *savel, ITextLink *cancell);
// >= 0 will contain download / upload string, _statusSize = loaded bytes
// < 0 will contain played string, _statusSize = -(seconds + 1) played
// 0x7FFFFFF0 will contain status for not yet downloaded file
// 0x7FFFFFF1 will contain status for already downloaded file
// 0x7FFFFFF2 will contain status for failed to download / upload file
mutable int32 _statusSize;
mutable QString _statusText;
void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const;
void step_thumbOver(const HistoryItem *parent, float64 ms, bool timer);
void step_radial(const HistoryItem *parent, uint64 ms, bool timer);
void ensureAnimation(const HistoryItem *parent) const;
void checkAnimationFinished();
bool isRadialAnimation(uint64 ms) const {
if (!_animation || !_animation->radial.animating()) return false;
_animation->radial.step(ms);
return _animation && _animation->radial.animating();
}
virtual float64 dataProgress() const = 0;
virtual bool dataFinished() const = 0;
virtual bool dataLoaded() const = 0;
struct AnimationData {
AnimationData(AnimationCallbacks *thumbOverCallbacks, AnimationCallbacks *radialCallbacks) : a_thumbOver(0, 0)
, _a_thumbOver(thumbOverCallbacks)
, radial(st::msgFileRadialLine, radialCallbacks) {
}
anim::fvalue a_thumbOver;
Animation _a_thumbOver;
RadialAnimation radial;
};
mutable AnimationData *_animation;
};
class HistoryAudio : public HistoryFileMedia {
public:
HistoryAudio(const MTPDaudio &audio);
@ -1368,18 +1429,18 @@ public:
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
bool uploading() const {
return (data->status == FileUploading);
return (_data->status == FileUploading);
}
HistoryMedia *clone() const;
AudioData *audio() {
return data;
return _data;
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void updateFrom(const MTPMessageMedia &media);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
bool needsBubble(const HistoryItem *parent) const {
return true;
@ -1388,17 +1449,26 @@ public:
return false;
}
protected:
float64 dataProgress() const {
return _data->progress();
}
bool dataFinished() const {
return !_data->loader;
}
bool dataLoaded() const {
return !_data->already().isEmpty() || !_data->data.isEmpty();
}
private:
AudioData *data;
TextLinkPtr _openl, _savel, _cancell;
AudioData *_data;
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
bool updateStatusText(const HistoryItem *parent) const; // returns showPause
QString _size;
mutable QString _dldTextCache, _uplTextCache;
mutable int32 _dldDone, _uplDone;
};
class HistoryDocument : public HistoryMedia {
class HistoryDocument : public HistoryFileMedia {
public:
HistoryDocument(DocumentData *document);
@ -1421,8 +1491,6 @@ public:
return (_data->status == FileUploading);
}
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void linkOver(HistoryItem *parent, const TextLinkPtr &lnk);
void linkOut(HistoryItem *parent, const TextLinkPtr &lnk);
HistoryMedia *clone() const;
DocumentData *document() {
@ -1432,7 +1500,7 @@ public:
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void updateFrom(const MTPMessageMedia &media);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
bool hasReplyPreview() const {
return !_data->thumb->isNull();
@ -1452,46 +1520,33 @@ public:
return _data->song();
}
~HistoryDocument();
protected:
float64 dataProgress() const {
return _data->progress();
}
bool dataFinished() const {
return !_data->loader;
}
bool dataLoaded() const {
return !_data->already().isEmpty() || !_data->data.isEmpty();
}
private:
DocumentData *_data;
TextLinkPtr _openl, _savel, _thumbsavel, _cancell;
TextLinkPtr _linksavel, _linkcancell;
int32 _namew;
QString _name;
int32 _thumbw;
// >= 0 will contain download / upload string, _statusSize = loaded bytes
// < 0 will contain played string, _statusSize = -(seconds + 1) played
// 0x7FFFFFF0 will contain status for not yet downloaded file
// 0x7FFFFFF1 will contain status for already downloaded file
// 0x7FFFFFF2 will contain status for failed to download / upload file
mutable int32 _statusSize, _linkw;
mutable QString _statusText, _link;
mutable int32 _linkw;
mutable QString _link;
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
bool updateStatusText(const HistoryItem *parent) const; // returns showPause
void step_thumbOver(const HistoryItem *parent, float64 ms, bool timer);
void step_radial(const HistoryItem *parent, uint64 ms, bool timer);
void ensureAnimation(const HistoryItem *parent) const;
void checkAnimationFinished();
struct AnimationData {
AnimationData(AnimationCallbacks *thumbOverCallbacks, AnimationCallbacks *radialCallbacks) : a_thumbOver(0, 0)
, _a_thumbOver(thumbOverCallbacks)
, radial(st::msgFileRadialLine, radialCallbacks) {
}
anim::fvalue a_thumbOver;
Animation _a_thumbOver;
RadialAnimation radial;
};
mutable AnimationData *_animation;
};
class HistoryGif : public HistoryMedia {
@ -1522,7 +1577,7 @@ public:
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void updateFrom(const MTPMessageMedia &media);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
bool hasReplyPreview() const {
return !_data->thumb->isNull();
@ -1578,7 +1633,7 @@ public:
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void updateFrom(const MTPMessageMedia &media);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
bool needsBubble(const HistoryItem *parent) const {
return false;
@ -1596,11 +1651,30 @@ private:
};
class SendMessageLink : public PeerLink {
TEXT_LINK_CLASS(SendMessageLink)
public:
SendMessageLink(PeerData *peer) : PeerLink(peer) {
}
void onClick(Qt::MouseButton button) const;
};
class AddContactLink : public MessageLink {
TEXT_LINK_CLASS(AddContactLink)
public:
AddContactLink(PeerId peer, MsgId msgid) : MessageLink(peer, msgid) {
}
void onClick(Qt::MouseButton button) const;
};
class HistoryContact : public HistoryMedia {
public:
HistoryContact(int32 userId, const QString &first, const QString &last, const QString &phone);
HistoryContact(int32 userId, const QString &fullname, const QString &phone);
void initDimensions(const HistoryItem *parent);
void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const;
@ -1613,7 +1687,10 @@ public:
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width) const;
HistoryMedia *clone() const;
void updateFrom(const MTPMessageMedia &media);
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize);
bool needsBubble(const HistoryItem *parent) const {
return true;
@ -1622,12 +1699,28 @@ public:
return false;
}
const QString &fname() const {
return _fname;
}
const QString &lname() const {
return _lname;
}
const QString &phone() const {
return _phone;
}
private:
int32 userId;
int32 phonew;
Text name;
QString phone;
UserData *contact;
int32 _userId;
UserData *_contact;
int32 _phonew;
QString _fname, _lname, _phone;
Text _name;
TextLinkPtr _linkl;
int32 _linkw;
QString _link;
};
class HistoryWebPage : public HistoryMedia {
@ -1841,7 +1934,7 @@ public:
void updateMedia(const MTPMessageMedia *media, bool allowEmitResize) {
if (media && _media && _media->type() != MediaTypeWebPage) {
_media->updateFrom(*media);
_media->updateFrom(*media, this, allowEmitResize);
} else {
setMedia(media, allowEmitResize);
}

View File

@ -1527,9 +1527,11 @@ void HistoryInner::onUpdateSelected() {
App::mousedItem(item);
m = mapMouseToItem(point, item);
if (item->hasPoint(m.x(), m.y())) {
redrawItem(App::hoveredItem());
App::hoveredItem(item);
redrawItem(App::hoveredItem());
if (App::hoveredItem() != item) {
redrawItem(App::hoveredItem());
App::hoveredItem(item);
redrawItem(App::hoveredItem());
}
} else if (App::hoveredItem()) {
redrawItem(App::hoveredItem());
App::hoveredItem(0);
@ -1670,7 +1672,7 @@ void HistoryInner::onUpdateSelected() {
_widget->noSelectingScroll();
}
if (lnkChanged || cur != _cursor) {
if (_dragAction == NoDrag && (lnkChanged || cur != _cursor)) {
setCursor(_cursor = cur);
}
}
@ -5608,6 +5610,12 @@ void HistoryWidget::notify_redrawHistoryItem(const HistoryItem *item) {
}
}
void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
if (_peer && _list && (item == App::mousedItem() || item == App::hoveredItem() || item == App::hoveredLinkItem())) {
_list->onUpdateSelected();
}
}
void HistoryWidget::resizeEvent(QResizeEvent *e) {
_reportSpamPanel.resize(width(), _reportSpamPanel.height());

View File

@ -431,6 +431,7 @@ public:
void peerMessagesUpdated();
void notify_redrawHistoryItem(const HistoryItem *item);
void notify_historyItemLayoutChanged(const HistoryItem *item);
void newUnreadMsg(History *history, HistoryItem *item);
void historyToDown(History *history);
void historyWasRead(bool force = true);

View File

@ -758,13 +758,18 @@ void MainWidget::notify_migrateUpdated(PeerData *peer) {
history.notify_migrateUpdated(peer);
}
void MainWidget::notify_redrawHistoryItem(const HistoryItem *msg) {
if (!msg) return;
history.notify_redrawHistoryItem(msg);
if (!msg->history()->dialogs.isEmpty() && msg->history()->lastMsg == msg) {
dialogs.dlgUpdated(msg->history()->dialogs[0]);
void MainWidget::notify_redrawHistoryItem(const HistoryItem *item) {
if (!item) return;
history.notify_redrawHistoryItem(item);
if (!item->history()->dialogs.isEmpty() && item->history()->lastMsg == item) {
dialogs.dlgUpdated(item->history()->dialogs[0]);
}
if (overview) overview->notify_redrawHistoryItem(msg);
if (overview) overview->notify_redrawHistoryItem(item);
}
void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
history.notify_historyItemLayoutChanged(item);
}
void MainWidget::noHider(HistoryHider *destroyed) {

View File

@ -389,7 +389,8 @@ public:
void notify_botCommandsChanged(UserData *bot);
void notify_userIsBotChanged(UserData *bot);
void notify_migrateUpdated(PeerData *peer);
void notify_redrawHistoryItem(const HistoryItem *msg);
void notify_redrawHistoryItem(const HistoryItem *item);
void notify_historyItemLayoutChanged(const HistoryItem *item);
void choosePeer(PeerId peerId, MsgId showAtMsgId); // does offerPeer or showPeerHistory
void clearBotStartToken(PeerData *peer);

View File

@ -23,7 +23,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "settings.h"
#include "lang.h"
bool gRtl = true;// false;
bool gRtl = false;
Qt::LayoutDirection gLangDir = gRtl ? Qt::RightToLeft : Qt::LeftToRight;
mtpDcOptions gDcOptions;

View File

@ -62,7 +62,7 @@ style::color peerColor(int32 index) {
}
ImagePtr userDefPhoto(int32 index) {
static const ImagePtr userDefPhotos[8] = {
static const ImagePtr userDefPhotos[UserColorsCount] = {
ImagePtr(qsl(":/ava/art/usercolor1.png"), "PNG"),
ImagePtr(qsl(":/ava/art/usercolor2.png"), "PNG"),
ImagePtr(qsl(":/ava/art/usercolor3.png"), "PNG"),
@ -833,6 +833,18 @@ void AudioData::save(const QString &toFile) {
loader->connect(loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(audioLoadProgress(mtpFileLoader*)));
loader->connect(loader, SIGNAL(failed(mtpFileLoader*, bool)), App::main(), SLOT(audioLoadFailed(mtpFileLoader*, bool)));
loader->start();
notifyLayoutChanged();
}
void AudioData::notifyLayoutChanged() const {
const AudioItems &items(App::audioItems());
AudioItems::const_iterator i = items.constFind(const_cast<AudioData*>(this));
if (i != items.cend()) {
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
Notify::historyItemLayoutChanged(j.key());
}
}
}
QString AudioData::already(bool check) {
@ -1035,6 +1047,18 @@ void DocumentData::save(const QString &toFile) {
loader->connect(loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(documentLoadProgress(mtpFileLoader*)));
loader->connect(loader, SIGNAL(failed(mtpFileLoader*, bool)), App::main(), SLOT(documentLoadFailed(mtpFileLoader*, bool)));
loader->start();
notifyLayoutChanged();
}
void DocumentData::notifyLayoutChanged() const {
const DocumentItems &items(App::documentItems());
DocumentItems::const_iterator i = items.constFind(const_cast<DocumentData*>(this));
if (i != items.cend()) {
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
Notify::historyItemLayoutChanged(j.key());
}
}
}
QString DocumentData::already(bool check) {

View File

@ -186,6 +186,8 @@ inline bool isNotifyMuted(NotifySettingsPtr settings, int32 *changeIn = 0) {
return false;
}
static const int32 UserColorsCount = 8;
style::color peerColor(int32 index);
ImagePtr userDefPhoto(int32 index);
ImagePtr chatDefPhoto(int32 index);
@ -906,6 +908,8 @@ struct AudioData {
l->cancel();
l->deleteLater();
l->rpcInvalidate();
notifyLayoutChanged();
}
_location = FileLocation();
if (!beforeDownload) {
@ -922,7 +926,10 @@ struct AudioData {
loader->deleteLater();
loader->rpcInvalidate();
loader = 0;
notifyLayoutChanged();
}
void notifyLayoutChanged() const;
QString already(bool check = false);
const FileLocation &location(bool check = false);
@ -932,6 +939,10 @@ struct AudioData {
}
}
float64 progress() const {
return loader ? loader->currentProgress() : ((status == FileDownloadFailed || (_location.name().isEmpty() && data.isEmpty())) ? 0 : 1);
}
AudioId id;
uint64 access;
int32 date;
@ -1081,6 +1092,8 @@ struct DocumentData {
l->cancel();
l->deleteLater();
l->rpcInvalidate();
notifyLayoutChanged();
}
_location = FileLocation();
if (!beforeDownload) {
@ -1100,7 +1113,11 @@ struct DocumentData {
loader->deleteLater();
loader->rpcInvalidate();
loader = 0;
notifyLayoutChanged();
}
void notifyLayoutChanged() const;
~DocumentData() {
delete _additional;
}

View File

@ -20,6 +20,11 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
*/
#pragma once
template <typename Type>
void setBadLink(Type *&link) {
link = reinterpret_cast<Type*>(0x00000bad);
}
struct NullType {
};
@ -453,3 +458,8 @@ enum ShowLayerOption {
ForceFastShowLayer = 0x04,
};
typedef QFlags<ShowLayerOption> ShowLayerOptions;
static int32 FullArcLength = 360 * 16;
static int32 QuarterArcLength = (FullArcLength / 4);
static int32 MinArcLength = (FullArcLength / 360);
static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);