void ProgressModal::Center() { UI* tbui = GetSubsystem<UI>(); TBRect rect = window_->GetRect(); TBWidget* root = tbui->GetRootWidget(); TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h); window_->SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds)); delegate_->SetRect(bounds); }
TBRect TBPopupAlignment::GetAlignedRect(TBWidget *popup, TBWidget *target) const { TBWidget *root = target->GetParentRoot(); SizeConstraints sc(root->GetRect().w, root->GetRect().h); PreferredSize ps = popup->GetPreferredSize(sc); // Amount of pixels that should be avoided if the target rect needs to be moved. int avoid_w = 0, avoid_h = 0; int x = 0, y = 0; int w = MIN(ps.pref_w, root->GetRect().w); int h = MIN(ps.pref_h, root->GetRect().h); if (pos_in_root.x != UNSPECIFIED && pos_in_root.y != UNSPECIFIED) { x = pos_in_root.x; y = pos_in_root.y; avoid_w = pos_offset.x; avoid_h = pos_offset.y; // Make sure it's moved into view horizontally if (align == TB_ALIGN_TOP || align == TB_ALIGN_BOTTOM) x = Clamp(x, 0, root->GetRect().w - w); } else { target->ConvertToRoot(x, y); if (align == TB_ALIGN_TOP || align == TB_ALIGN_BOTTOM) { if (expand_to_target_width) w = MAX(w, target->GetRect().w); // If the menu is aligned top or bottom, limit its height to the worst case available height. // Being in the center of the root, that is half the root height minus the target rect. h = MIN(h, root->GetRect().h / 2 - target->GetRect().h); } avoid_w = target->GetRect().w; avoid_h = target->GetRect().h; } if (align == TB_ALIGN_BOTTOM) y = y + avoid_h + h > root->GetRect().h ? y - h : y + avoid_h; else if (align == TB_ALIGN_TOP) y = y - h < 0 ? y + avoid_h : y - h; else if (align == TB_ALIGN_RIGHT) { x = x + avoid_w + w > root->GetRect().w ? x - w : x + avoid_w; y = MIN(y, root->GetRect().h - h); } else // if (align == TB_ALIGN_LEFT) { x = x - w < 0 ? x + avoid_w : x - w; y = MIN(y, root->GetRect().h - h); } return TBRect(x, y, w, h); }
void UIWidget::Center() { if (!widget_) return; // this should center on parent widget, not root UI* ui = GetSubsystem<UI>(); TBRect rect = widget_->GetRect(); TBWidget* root = ui->GetRootWidget(); TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h); widget_->SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds)); }
TBRect TBPopupAlignment::GetAlignedRect(TBWidget *popup, TBWidget *target) const { TBWidget *root = target->GetParentRoot(); SizeConstraints sc(root->GetRect().w, root->GetRect().h); PreferredSize ps = popup->GetPreferredSize(sc); TBRect target_rect; TBPoint pos; int w = MIN(ps.pref_w, root->GetRect().w); int h = MIN(ps.pref_h, root->GetRect().h); if (pos_in_root.x != UNSPECIFIED && pos_in_root.y != UNSPECIFIED) { pos = pos_in_root; } else { target->ConvertToRoot(pos.x, pos.y); if (align == TB_ALIGN_TOP || align == TB_ALIGN_BOTTOM) { if (expand_to_target_width) w = MAX(w, target->GetRect().w); // If the menu is aligned top or bottom, limit its height to the worst case available height. // Being in the center of the root, that is half the root height minus the target rect. h = MIN(h, root->GetRect().h / 2 - target->GetRect().h); } target_rect = target->GetRect(); } int x, y; if (align == TB_ALIGN_BOTTOM) { x = pos.x; y = pos.y + target_rect.h + h > root->GetRect().h ? pos.y - h : pos.y + target_rect.h; } else if (align == TB_ALIGN_TOP) { x = pos.x; y = pos.y - h < 0 ? pos.y + target_rect.h : pos.y - h; } else if (align == TB_ALIGN_RIGHT) { x = pos.x + target_rect.w + w > root->GetRect().w ? pos.x - w : pos.x + target_rect.w; y = MIN(pos.y, root->GetRect().h - h); } else //if (align == TB_ALIGN_LEFT) { x = pos.x - w < 0 ? pos.x + target_rect.w : pos.x - w; y = MIN(pos.y, root->GetRect().h - h); } return TBRect(x, y, w, h); }
void UIWidget::Center() { if (!widget_) return; TBRect rect = widget_->GetRect(); TBWidget* root = widget_->GetParent(); if (!root) { UI* ui = GetSubsystem<UI>(); root = ui->GetRootWidget(); } TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h); widget_->SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds)); }
bool TBMover::OnEvent(const TBWidgetEvent &ev) { TBWidget *target = GetParent(); if (!target) return false; if (ev.type == EVENT_TYPE_POINTER_MOVE && captured_widget == this) { int dx = ev.target_x - pointer_down_widget_x; int dy = ev.target_y - pointer_down_widget_y; TBRect rect = target->GetRect().Offset(dx, dy); if (target->GetParent()) { // Apply limit. rect.x = CLAMP(rect.x, -pointer_down_widget_x, target->GetParent()->GetRect().w - pointer_down_widget_x); rect.y = CLAMP(rect.y, -pointer_down_widget_y, target->GetParent()->GetRect().h - pointer_down_widget_y); } target->SetRect(rect); return true; } return false; }
bool TBResizer::OnEvent(const TBWidgetEvent &ev) { TBWidget *target = GetParent(); if (!target) return false; if (ev.type == EVENT_TYPE_POINTER_MOVE && captured_widget == this) { int dx = ev.target_x - pointer_down_widget_x; int dy = ev.target_y - pointer_down_widget_y; TBRect rect = target->GetRect(); rect.w += dx; rect.h += dy; // Apply limit. We should not use minimum size since we can squeeze // the layout much more, and provide scroll/pan when smaller. rect.w = MAX(rect.w, 50); rect.h = MAX(rect.h, 50); target->SetRect(rect); } else return false; return true; }
int32 TBTextFragmentContentWidget::GetHeight(TBFontFace *font, TBTextFragment *fragment) { return m_widget->GetRect().h ? m_widget->GetRect().h : m_widget->GetPreferredSize().pref_h; }
int32 TBTextFragmentContentWidget::GetWidth(TBFontFace *font, TBTextFragment *fragment) { return m_widget->GetRect().w ? m_widget->GetRect().w : m_widget->GetPreferredSize().pref_w; }
bool TBMessageWindow::Show(const char *title, const char *message, TBMessageWindowSettings *settings) { TBWidget *target = m_target.Get(); if (!target) return false; TBMessageWindowSettings default_settings; if (!settings) settings = &default_settings; TBWidget *root = target->GetParentRoot(); const char *source = "TBLayout: axis: y, distribution: available\n" " TBLayout: distribution: available, size: available\n" " TBSkinImage: id: 2\n" " TBEditField: multiline: 1, readonly: 1, id: 1\n" " TBLayout: distribution-position: right bottom, id: 3\n"; if (!g_widgets_reader->LoadData(GetContentRoot(), source)) return false; SetText(title); GetWidgetByIDAndType<TBSkinImage>(2)->SetSkinBg(settings->icon_skin); TBEditField *editfield = GetWidgetByIDAndType<TBEditField>(1); editfield->SetStyling(settings->styling); editfield->SetText(message); editfield->SetSkinBg(""); // Create buttons if (settings->msg == TB_MSG_OK) { AddButton("TBMessageWindow.ok", true); } else if (settings->msg == TB_MSG_OK_CANCEL) { AddButton("TBMessageWindow.ok", true); AddButton("TBMessageWindow.cancel", false); } else if (settings->msg == TB_MSG_YES_NO) { AddButton("TBMessageWindow.yes", true); AddButton("TBMessageWindow.no", false); } // Size to fit content. This will use the default size of the textfield. ResizeToFitContent(); TBRect rect = GetRect(); // Get how much we overflow the textfield has given the current width, and grow our height to show all we can. // FIX: It would be better to use adapt-to-content on the editfield to achieve the most optimal size. // At least when we do full blown multi pass size checking. rect.h += editfield->GetStyleEdit()->GetOverflowY(); // Create background dimmer if (settings->dimmer) { if (TBDimmer *dimmer = new TBDimmer) { root->AddChild(dimmer); m_dimmer.Set(dimmer); } } // Center and size to the new height TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h); SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds)); root->AddChild(this); return true; }