コード例 #1
0
ファイル: algorithm.hpp プロジェクト: xuxiaowei007/YSLib
_tOut
transform_when(_tIn first, _tOut result, _fPred pred, _fOp op)
{
	yunseq((yconstraint(!is_undereferenceable(first)), 0),
		(yconstraint(!is_undereferenceable(result)), 0));

	for(; pred(*first); yunseq((++first, 0), (++result, 0)))
		*result = op(*first);
	return result;
}
コード例 #2
0
ファイル: Input.cpp プロジェクト: FrankHB/YSLib
void
SaveInput(const ::AInputEvent& e)
{
	const auto update_key([](std::int32_t action, const std::uint8_t keycode){
		lock_guard<mutex> lck(KeyMutex);
		// TODO: Track Alt/Shift/Sym key states.
	//	const auto meta(::AKeyEvent_getMetaState(&e));

		switch(action)
		{
		case ::AKEY_EVENT_ACTION_DOWN:
		case ::AKEY_EVENT_ACTION_UP:
			KeyStateBuffer.set(keycode, action == ::AKEY_EVENT_ACTION_DOWN);
			break;
		case ::AKEY_EVENT_ACTION_MULTIPLE:
			// TODO: Record.
			break;
		}
	});
	const auto update_motion_key([](bool down){
		lock_guard<mutex> lck(KeyMutex);

		KeyStateBuffer.set(platform::KeyCodes::Primary, down);
	});

	switch(::AInputEvent_getType(&e))
	{
	case AINPUT_EVENT_TYPE_KEY:
		if(~::AKeyEvent_getFlags(&e) & ::AKEY_EVENT_FLAG_CANCELED)
			update_key(::AKeyEvent_getAction(&e),
				::AKeyEvent_getKeyCode(&e) & 0xFF);
		break;
	case AINPUT_EVENT_TYPE_MOTION:
		// TODO: Detect multiple pointers using 'AMotionEvent_getPointerCount'.
		// TODO: Support multiple pointers handlers.
		// TODO: Detect edges using 'AMotionEvent_getEdgeFlags'.
		// TODO: Record pressure using 'AMotionEvent_getPressure'.
		// TODO: Record touch area size using 'AMotionEvent_getSize'.
		// TODO: Track historical motion using 'AMotionEvent_getHistorical*'.
		if(::AMotionEvent_getFlags(&e) != AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED)
			switch(::AKeyEvent_getAction(&e) & AMOTION_EVENT_ACTION_MASK)
			{
			case AMOTION_EVENT_ACTION_CANCEL:
				break;
			case AMOTION_EVENT_ACTION_UP:
				update_motion_key({});
				break;
			case AMOTION_EVENT_ACTION_DOWN:
				update_motion_key(true);
			case AMOTION_EVENT_ACTION_MOVE:
			default:
				{
					lock_guard<mutex> lck(CursorMutex);

					yunseq(LastCursorPosX = ::AMotionEvent_getRawX(&e, 0),
						LastCursorPosY = ::AMotionEvent_getRawY(&e, 0));
				}
			}
	}
}
コード例 #3
0
ファイル: Input.cpp プロジェクト: FrankHB/YSLib
void
ClearKeyStates()
{
	lock_guard<mutex> comp_lck(CompKeyMutex);
	lock_guard<mutex> lck(KeyMutex);

	yunseq(Deref(pKeyState).reset(), Deref(pOldKeyState).reset());
}
コード例 #4
0
ファイル: yblit.cpp プロジェクト: kis2009dsh/YSLib
bool
BlitBounds(const Point& dp, const Point& sp,
	const Size& ds, const Size& ss, const Size& sc,
	SDst& min_x, SDst& min_y, SDst& delta_x, SDst& delta_y)
{
	SPos max_x, max_y;

	yunseq(min_x = blit_min(sp.X, dp.X), min_y = blit_min(sp.Y, dp.Y),
		max_x = blit_max(sp.X, dp.X, ss.Width, ds.Width, sc.Width),
		max_y = blit_max(sp.Y, dp.Y, ss.Height, ds.Height, sc.Height));
	if(min_x < max_x && min_y < max_y)
	{
		yunseq(delta_x = max_x - min_x, delta_y = max_y - min_y);
		return true;
	}
	return false;
}
コード例 #5
0
ファイル: Viewer.cpp プロジェクト: coldzhang/YSLib
void
AMUnitList::ResetView()
{
	bool b(vwList.IsSelected());

	vwList.Reset();
	if(b)
		vwList.SetSelectedIndex(0, GetTotal());
	yunseq(uTopOffset = 0, idxShared = size_t(-1));
}
コード例 #6
0
ファイル: progress.cpp プロジェクト: kis2009dsh/YSLib
ProgressBar::ProgressBar(const Rect& r, ValueType m)
	: Control(r, NoBackgroundTag()), GMRange<float>(m == 0 ? 1 : m, 0)
{
	auto& pal(FetchGUIState().Colors);
	BorderStyle style;

	style.ActiveColor = pal[Styles::InactiveBorder];
	yunseq(
	Background = SolidBrush(pal[Styles::Track]),
	ForeColor = pal[Styles::HotTracking],
	FetchEvent<Paint>(*this).Add(BorderBrush(style), BoundaryPriority)
	);
}
コード例 #7
0
ファイル: Hover.cpp プロジェクト: kis2009dsh/YSLib
HoverUpdater::HoverUpdater(IWidget& wgt)
	: Widget(wgt)
{
	yunseq(
	FetchEvent<Enter>(wgt) += [this](UIEventArgs&&){
		entered = true,
		Invalidate(Widget);
	},
	FetchEvent<Leave>(wgt) += [this](UIEventArgs&&){
		entered = false,
		Invalidate(Widget);
	}
	);
}
コード例 #8
0
ファイル: progress.cpp プロジェクト: AntiMoron/YSLib
ProgressBar::ProgressBar(const Rect& r, ValueType m)
	: Control(r), GMRange<float>(m == 0 ? 1 : m, 0)
{
	const auto invalidator([this]{
		Invalidate(*this);
	});
	auto& pal(FetchGUIState().Colors);
	BorderStyle style;

	style.ActiveColor = pal[Styles::InactiveBorder];
	yunseq(
	Background = SolidBrush(pal[Styles::Track]),
	ForeColor = pal[Styles::HotTracking],
	FetchEvent<Paint>(*this).Add(BorderBrush(style), BoundaryPriority),
	FetchEvent<GotFocus>(*this) += invalidator,
	FetchEvent<LostFocus>(*this) += invalidator
	);
}
コード例 #9
0
ファイル: ycontrol.cpp プロジェクト: kis2009dsh/YSLib
Control::Control(const Rect& r, NoBackgroundTag)
    : Widget(new View(r), new Renderer(),
             new Controller(true, FetchPrototype<ControlEventMap>())),
      BoundControlPtr(std::bind(&Control::GetBoundControlPtr, this,
                                std::placeholders::_1))
{
    const auto h([this](UIEventArgs&&) {
        Invalidate(*this);
    });

    FetchGUIState().Wrap(*this),
                  yunseq(
    FetchEvent<Move>(*this) += [this](UIEventArgs&&) {
        InvalidateParent(*this);
    },
    FetchEvent<Resize>(*this) += h,
                                 FetchEvent<GotFocus>(*this) += h,
                                 FetchEvent<LostFocus>(*this) += h
                  );
}
コード例 #10
0
ファイル: ReaderSettingUI.cpp プロジェクト: kis2009dsh/YSLib
SettingPanel&
SettingPanel::operator<<(const ReaderSetting& s)
{
	auto& node(dynWgts.WidgetNode);
	DeclDynWidgetNode(DropDownList, ddlFont)
	DeclDynWidgetNode(CheckButton, cbSmoothScroll)

	yunseq(
	lblAreaUp.ForeColor = s.FontColor,
	lblAreaUp.Background = SolidBrush(s.UpColor),
	lblAreaUp.Font = s.Font,
	lblAreaDown.ForeColor = s.FontColor,
	lblAreaDown.Background = SolidBrush(s.DownColor),
	lblAreaDown.Font = s.Font,
	ddlFont.Text = s.Font.GetFamilyName(),
	scroll_duration = s.ScrollDuration,
	smooth_scroll_duration = s.SmoothScrollDuration
	),
	cbSmoothScroll.Tick(s.SmoothScroll);
	UpdateInfo();
	return *this;
}
コード例 #11
0
ファイル: DSWindow.cpp プロジェクト: xuxiaowei007/YSLib
DSWindow::DSWindow(NativeWindowHandle h_wnd, DSScreen& s_up, DSScreen& s_dn,
	GUIHost& h)
	: Window(h_wnd, h), scr_up(s_up), scr_dn(s_dn)
{
#	if YCL_Win32
	yunseq(
	MessageMap[WM_DESTROY] += []{
		YSLib::PostQuitMessage(0);
		// NOTE: Try to make sure all shells are released before destructing the
		//	instance of %DSApplication.
	},
	MessageMap[WM_PAINT] += [this]{
		GSurface<WindowRegionDeviceContext> sf(Nonnull(GetNativeHandle()));
		const auto& r(sf.GetInvalidatedArea());

		UpdateScreen(sf, scr_up, r);
		UpdateScreen(sf, scr_dn, r);
	}
	);
	Show();
#	endif
}
コード例 #12
0
ファイル: progress.cpp プロジェクト: AntiMoron/YSLib
void
ProgressBar::Refresh(PaintEventArgs&& e)
{
	const auto& g(e.Target);
	auto pt(e.Location);
	auto& r(e.ClipArea);
	Size s(GetSizeOf(*this));

	if(YB_LIKELY(s.Width > 2 && s.Height > 2))
	{
		yunseq(s.Width -= 2, s.Height -= 2, pt.X += 1, pt.Y += 1);

		const SDst w_bar(round(value * s.Width / max_value));

		FillRect(g, r, {pt, w_bar, s.Height}, ForeColor);
		pt.X += w_bar;
		if(s.Width > w_bar)
			// TODO: Finish drawing with non-solid brushes.
			if(const auto p = Background.target<SolidBrush>())
				FillRect(g, r, Rect(pt, s.Width - w_bar, s.Height), p->Color);
	}
}
コード例 #13
0
ファイル: NPLA1.cpp プロジェクト: AntiMoron/YSLib
ValueNode
TransformNPLA1(const ValueNode& node, std::function<NodeMapper> mapper)
{
	auto s(node.GetSize());

	if(s == 0)
		return {0, "", node ? Deliteralize(Access<string>(node)) : string()};

	auto i(node.begin());

	if(s == 1)
		return TransformNPLA1(*i, mapper);

	const auto& name(ParseNPLANodeString(*i));

	if(!name.empty())
		yunseq(++i, --s);
	if(s == 1)
	{
		auto&& n(TransformNPLA1(*i, mapper));

		if(n.GetName().empty())
			return {0, name, std::move(n.Value)};
		return {ValueNode::Container{std::move(n)}, name};
	}

	auto p_node_con(make_unique<ValueNode::Container>());

	std::for_each(i, node.end(), [&](const ValueNode& nd){
		auto&& n(mapper ? mapper(nd) : TransformNPLA1(nd, mapper));

		p_node_con->insert(n.GetName().empty() ? ValueNode(0,
			'$' + std::to_string(p_node_con->size()), std::move(n.Value))
			: std::move(n));
	});
	return {std::move(p_node_con), name};
}
コード例 #14
0
ファイル: Border.cpp プロジェクト: kis2009dsh/YSLib
void
BorderResizer::Wrap()
{
	auto& controller(widget.get().GetController());

	yunseq(
	FetchEvent<TouchDown>(controller).Add([this](CursorEventArgs&& e){
		yunseq(orig_loc = FetchGUIState().CursorLocation,
			locked_bounds = GetBoundsOf(widget), focused = CheckArea(e));
	}, 0xE0),
	FetchEvent<TouchHeld>(controller).Add([this](CursorEventArgs&& e){
		if(e.Strategy == RoutedEventArgs::Direct
			&& focused != Area(BorderArea::Center, BorderArea::Center))
		{
			auto& st(FetchGUIState());

			if(st.CheckDraggingOffset())
			{
				const auto offset(st.CursorLocation - orig_loc);
				auto bounds(locked_bounds);

				switch(focused.first)
				{
				case BorderArea::Left:
					bounds.Width = max<SPos>(MinSize.Width,
						locked_bounds.Width - offset.X);
					bounds.X += locked_bounds.Width - bounds.Width;
					break;
				case BorderArea::Right:
					bounds.Width = max<SPos>(MinSize.Width,
						locked_bounds.Width + offset.X);
					break;
				default:
					;
				}
				switch(focused.second)
				{
				case BorderArea::Up:
					bounds.Height = max<SPos>(MinSize.Height,
						locked_bounds.Height - offset.Y);
					bounds.Y += locked_bounds.Height - bounds.Height;
					break;
				case BorderArea::Down:
					bounds.Height = max<SPos>(MinSize.Height,
						locked_bounds.Height + offset.Y);
					break;
				default:
					;
				}

				YTraceDe(Notice, "BorderResizer: new bounds = %s.\n",
					to_string(bounds).c_str());

				InvalidateParent(widget);

				if(HostMode)
				{
					const auto& off(
						bounds.GetPoint() - locked_bounds.GetPoint());

					SetBoundsOf(widget, bounds);

					const auto& nloc(FetchGUIState().CursorLocation - off);

					if(bounds.Width != MinSize.Width)
						orig_loc.X = nloc.X;
					if(bounds.Height != MinSize.Height)
						orig_loc.Y = nloc.Y;
					locked_bounds = GetBoundsOf(widget);
					locked_bounds.GetPointRef() -= off;
				}
				else
					SetBoundsOf(widget, bounds);
			}
			e.Handled = true;
			// XXX: Paint context target invalidated.
		}
	}, 0xE0),
	FetchEvent<Click>(controller).Add([this](CursorEventArgs&& e){
		CallEvent<ClickAcross>(widget, e);
	}, 0xE0),
	FetchEvent<ClickAcross>(controller).Add([this](CursorEventArgs&&){
		yunseq(orig_loc = Point::Invalid, locked_bounds = Rect(),
			focused = {BorderArea::Center, BorderArea::Center});
	}, 0xE0)
	);
}
コード例 #15
0
ファイル: ComboList.cpp プロジェクト: coldzhang/YSLib
DropDownList::DropDownList(const Rect& r, const shared_ptr<ListType>& h)
    : Button(r),
      lbContent( {}, h)
{
    const auto detacher([this](UIEventArgs&& e) {
        if(!dynamic_cast<RoutedEventArgs*>(&e))
            DetachTopWidget();
    });

    yunseq(
        Margin.Left = 4,
        Margin.Right = 18,
        HorizontalAlignment = TextAlignment::Left,
        lbContent.GetView().DependencyPtr = this,
    FetchEvent<TouchDown>(*this) += [this](CursorEventArgs&& e) {
        if(!FetchContainerPtr(lbContent))
        {
            Point pt;

            if(const auto p
                    = dynamic_cast<Panel*>(&FetchTopLevel(e.GetSender(), pt)))
            {
                // NOTE: Get height of top widget, top and bottom spaces.
                const SDst h0(GetSizeOf(*p).Height);
                // XXX: Conversion to 'SPos' might be implementation-defined.
                const SDst h1(SDst(max<SPos>(0, pt.Y))), h2(SDst(max<SPos>(0,
                        SPos(h0) - pt.Y - SPos(GetHeight()))));

                if(IsInOpenInterval(h1, h0) || IsInOpenInterval(h2, h0))
                {
                    lbContent.ResizeForPreferred(Size(0, max(h1, h2)),
                                                 Size(GetWidth(), 0));

                    const SDst h3(lbContent.GetHeight());

                    // NOTE: Bottom space is preferred.
                    // XXX: Conversion to 'SPos' might be
                    //	implementation-defined.
                    pt.Y += SPos(h2 < h3 ? -h3 : GetHeight());
                    SetLocationOf(lbContent, pt);
                    lbContent.AdjustViewLength();
                    {
                        const auto& lst(lbContent.GetList());
                        const auto i(std::find(lst.cbegin(), lst.cend(), Text));

                        if(i != lst.cend())
                            lbContent.SetSelected(size_t(i - lst.cbegin()));
                        else
                            lbContent.ClearSelected();
                    }
                    p->Add(lbContent, 224U); // TODO: Use non-magic number.
                    RequestFocusCascade(lbContent);
                    e.Handled = true;
                }
            }
        }
    },
    FetchEvent<LostFocus>(*this) += detacher,
                                    FetchEvent<LostFocus>(lbContent) += detacher,
    lbContent.GetConfirmed() += [this](IndexEventArgs&& e) {
        YAssert(e.Value < lbContent.GetList().size(), "Invalid index found.");

        Text = lbContent.GetList()[e.Value];
        // XXX: This seems to be redundant if the detached top widget would be
        //	always invalidated, however there is no such guarantee.
        Invalidate(e.GetSender()),
                   Invalidate(*this);
        DetachTopWidget();
    }
    );
}