// // XTGameWindowController_vmThreadBannerApi.m // XTads // // Created by Rune Berg on 15/12/15. // Copyright © 2015 Rune Berg. All rights reserved. // // IMPORTANT NOTE: This is not a standalone .m file, and so should // *not* be member of any build targets. Instead, it's #included by // XTGameWindowController.m proper. // - (void *)bannerCreate:(void *)parent where:(NSInteger)where other:(void *)other wintype:(NSInteger)wintype align:(NSInteger)align size:(NSInteger)size sizeUnits:(NSInteger)sizeUnits style:(NSUInteger)style { XT_DEF_SELNAME; XT_TRACE_0(@"ENTER"); RETURN_VALUE_IF_SHUTTING_DOWN_VM_THREAD(0); XTBannerCreateParams *params = [XTBannerCreateParams new]; params.parent = parent; params.where = where; params.other = other; params.wintype = wintype; params.align = align; params.size = size; params.sizeUnits = sizeUnits; params.style = style; [self callOnMainThread:@selector(mainThread_bannerCreate:) withObject:params]; return params.bannerHandle; } - (void)tagBannerReconfigure:(void *)handle align:(NSUInteger)align sizeToContents:(BOOL)sizeToContents sizeAsPrevious:(BOOL)sizeAsPrevious size:(NSUInteger)size sizeUnits:(NSUInteger)sizeUnits style:(NSUInteger)style { XT_DEF_SELNAME; XTBannerTextHandler *banner = [self getBanner:handle]; BOOL wasSizedToContent = banner.isSizedToContent; banner.isSizedToContent = NO; banner.tagBannerNeedsSizeToContent = NO; banner.alignment = align; if (sizeAsPrevious) { //TODO this logic (and the state it uses) is probably much more complicated than it needs to be :-( if (banner.initialSize != nil) { if (banner.hadUnspecifiedSizeLastTime && banner.wasInitiallySizedToPrevious) { // Keep current size banner.isSizedToContent = YES; //XT_WARN_0(@"hadUnspecifiedSizeLastTime && wasInitiallySizedToPrevious --> no change"); int brkpt = 1; } else if (banner.hadPreviousSizeLastTime && banner.wasInitiallySizedToPrevious) { // Keep current size banner.isSizedToContent = wasSizedToContent; //XT_WARN_0(@"hadPreviousSizeLastTime && wasInitiallySizedToPrevious --> no change"); int brkpt = 1; } else { if (banner.wasInitiallySizedToPrevious) { // Keep current size int brkpt = 1; } else if (banner.wasInitiallySizedToContents) { banner.size = [banner.initialSize unsignedIntegerValue]; banner.sizeOfContents = banner.initialSizeOfContents; //XT_WARN_1(@"self.sizeOfContents = %lf", banner.initialSizeOfContents); banner.isSizedToContent = YES; banner.sizeUnits = banner.initialSizeUnits; } else if (banner.initialSizeUnits == OS_BANNER_SIZE_ABS) { banner.size = (NSUInteger)[banner.initialSize doubleValue]; banner.sizeUnits = banner.initialSizeUnits; } else { banner.size = [banner.initialSize unsignedIntegerValue]; banner.sizeUnits = banner.initialSizeUnits; } } } else { XT_ERROR_0(@"sizeAsPrevious && banner.initialSize == nil"); } } else if (sizeToContents) { //XT_WARN_0(@"tagBannerNeedsSizeToContent set to YES"); banner.tagBannerNeedsSizeToContent = YES; } else { banner.size = size; banner.sizeUnits = sizeUnits; } banner.style = style; } - (void *)bannerHandleForTagId:(NSString *)tagId { XT_DEF_SELNAME; void *handle = nil; if (tagId == nil || [tagId length] == 0) { XT_ERROR_0(@"tagId is nil or blank"); } else { XTBannerTextHandler *banner = [self.bannersByTagId valueForKey:tagId]; handle = (void *)banner.bannerIndex; } return handle; } - (XTBannerTextHandler *)bannerHandlerForHandle:(void *)handle { XTBannerTextHandler *banner = [self getBanner:handle]; return banner; } - (void)bannerDelete:(void *)banner_handle { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [self callOnMainThread:@selector(mainThread_bannerDelete:) withObject:banner]; } } - (void)bannerDeleteAll { NSArray * allKeys = [self.bannersByHandle allKeys]; for (NSNumber *handleObj in allKeys) { NSUInteger bannerIndex = handleObj.unsignedIntegerValue; if (bannerIndex >= 1) { void *bannerHandle = (void *)bannerIndex; XTBannerTextHandler *bannerTH = [self bannerHandlerForHandle:bannerHandle]; if (! bannerTH.isForTradStatusLine) { [self bannerDelete:bannerHandle]; } } } } - (void)bannerOrphan:(void *)banner_handle { XT_DEF_SELNAME; XT_TRACE_1(@"%lu", (NSUInteger)banner_handle); // Do nothing - leave the screen as is } - (BOOL)bannerInfo:(void *)banner_handle info:(os_banner_info_t *)info { BOOL res = NO; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner == nil) { return res; } res = YES; info->align = (int)banner.alignment; info->style = banner.style; info->style |= OS_BANNER_STYLE_TAB_ALIGN; // because MJR's terp and QTads behave that way if (_shuttingDownTadsEventLoopThread) { return res; } NSArray *usableSizes = [self childThread_getUsableSizes:banner]; NSNumber *usableHeightInRows = usableSizes[0]; info->rows = usableHeightInRows.intValue; NSNumber *usableWidthInColumns = usableSizes[1]; info->columns = usableWidthInColumns.intValue; NSNumber *usableHeightInPoints = usableSizes[2]; info->pix_height = usableHeightInPoints.intValue; NSNumber *usableWidthInPoints = usableSizes[3]; info->pix_width = usableWidthInPoints.intValue; info->os_line_wrap = 1; return res; } - (NSUInteger)bannerWidthInChars:(void *)banner_handle { NSUInteger res = 0; if (_shuttingDownTadsEventLoopThread) { return res; } XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { if (banner.type & OS_BANNER_TYPE_TEXTGRID) { NSArray *usableSizes = [self childThread_getUsableSizes:banner]; NSNumber *usableWidthInColumns = usableSizes[1]; res = usableWidthInColumns.intValue; } } return res; } - (NSUInteger)bannerHeightInChars:(void *)banner_handle { NSUInteger res = 0; if (_shuttingDownTadsEventLoopThread) { return res; } XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { if (banner.type & OS_BANNER_TYPE_TEXTGRID) { NSArray *usableSizes = [self childThread_getUsableSizes:banner]; NSNumber *usableHeightInRows = usableSizes[0]; res = usableHeightInRows.intValue; } } return res; } - (NSArray *)childThread_getUsableSizes:(XTBannerTextHandler *)banner { NSMutableArray *results = [NSMutableArray arrayWithCapacity:4]; [banner callOnMainThread:@selector(mainThread_getUsableSizes:) withObject:results]; return results; } - (void)bannerDisplay:(void *)banner_handle text:(NSString *)string { XT_DEF_SELNAME; XT_TRACE_1(@"\"%@\"", string); RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [banner display:string]; } } - (void)bannerSetTextColors:(void *)banner_handle foregroundColor:(os_color_t)fg backgroundColor:(os_color_t)bg { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil && [banner isGridMode]) { [banner callOnMainThread:@selector(mainThread_setForegroundColorForGrid:) withObject:[NSNumber numberWithUnsignedInteger:fg]]; [banner callOnMainThread:@selector(mainThread_setBackgroundColorForGrid:) withObject:[NSNumber numberWithUnsignedInteger:bg]]; } } - (void)bannerSetScreenColor:(void *)banner_handle screenColor:(os_color_t)color { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil && [banner isGridMode]) { [banner callOnMainThread:@selector(mainThread_setScreenColorForGrid:) withObject:[NSNumber numberWithUnsignedInteger:color]]; } } - (void)bannerDisplayTradStatusLineScoreString:(void *)banner_handle text:(NSString *)string { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [banner displayTradStatusLineScoreString:string]; } } - (void)bannerFlush:(void *)banner_handle { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [self pumpOutputTextForHandler:banner flushIfBanner:TRUE]; } } - (void)bannerSetHtmlMode:(void *)banner_handle on:(BOOL)on { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; banner.htmlMode = on; } - (void)bannerClear:(void *)banner_handle { XT_DEF_SELNAME; XT_TRACE_0(@""); RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [banner callOnMainThread:@selector(mainThread_clear)]; } } - (void)bannerSetSize:(void *)banner_handle size:(NSUInteger)size sizeUnits:(NSUInteger)sizUnits isAdvisory:(BOOL)isAdvisory { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { if (isAdvisory || ((size == banner.size) && (sizUnits == banner.sizeUnits))) { return; } [banner setSize:size sizeUnits:sizUnits isAdvisory:isAdvisory]; [self layoutAllBannerViews]; } } - (void)bannerSizeToContentsNoLayout:(void *)banner_handle { [self bannerSizeToContents:banner_handle doLayout:NO]; } - (void)bannerSizeToContents:(void *)banner_handle { [self bannerSizeToContents:banner_handle doLayout:YES]; } - (void)bannerSizeToContents:(void *)banner_handle doLayout:(BOOL)doLayout { XT_DEF_SELNAME; XT_TRACE_1(@"banner_handle=%ld", banner_handle); RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { CGFloat oldSizeOfContents = banner.sizeOfContents; NSUInteger oldSize = banner.size; NSUInteger oldSizeUnits = banner.sizeUnits; [banner callOnMainThread:@selector(mainThread_sizeToContents)]; if (doLayout) { BOOL sizeHasChanged = ((banner.sizeOfContents != oldSizeOfContents) || (banner.size != oldSize) || (banner.sizeUnits != oldSizeUnits)); if (sizeHasChanged) { /* if (banner.sizeOfContents != oldSizeOfContents) { XT_WARN_2(@"sizeHasChanged banner.sizeOfContents %lf != oldSizeOfContents %lf", banner.sizeOfContents, oldSizeOfContents); } if (banner.size != oldSize) { XT_WARN_2(@"sizeHasChanged banner.size %lu != oldSize %lu", banner.size, oldSize); }*/ [self layoutAllBannerViews]; } } } } - (void)bannerGoto:(void *)banner_handle row:(NSUInteger)row column:(NSUInteger)column { RETURN_IF_SHUTTING_DOWN_VM_THREAD; XTBannerTextHandler *banner = [self getBanner:banner_handle]; if (banner != nil) { [banner gotoRow:row column:column]; } } //--------------- - (XTBannerTextHandler *)getBanner:(void *)handle { XT_DEF_SELNAME; NSNumber *handleObj = [NSNumber numberWithUnsignedInteger:(NSUInteger)handle]; XTBannerTextHandler *banner = [self.bannersByHandle objectForKey:handleObj]; if (banner == nil) { XT_WARN_1(@"No banner with handle %lu", (NSUInteger)handle); } return banner; } - (void)traceBannerHierarchy { //XT_DEF_SELNAME; if (! XT_TRACE_ON) { return; } XTBannerTextHandler *mainAreaBanner = [self getBanner:0]; [mainAreaBanner traceWithIndentLevel:0]; } - (void)layoutAllBannerViews { //XT_DEF_SELNAME; RETURN_IF_SHUTTING_DOWN_VM_THREAD; //if ([NSThread isMainThread]) { // XT_WARN_0(@"should not be called on main thread"); //} [self callOnMainThread:@selector(mainThread_layoutAllBannerViews)]; }